agent-device 0.19.2 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +61 -70
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.0.apk +0 -0
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.0.apk.sha256 +1 -0
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.0.manifest.json +10 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.0.apk +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.0.apk.sha256 +1 -0
- package/{android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.19.2.manifest.json → android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.0.manifest.json} +6 -6
- package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.h +2 -0
- package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.m +5 -0
- package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.h +12 -10
- package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.m +154 -185
- package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift +113 -19
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+BlockingSystemModalResolution.swift +82 -0
- package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +275 -113
- package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +2 -2
- package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +150 -104
- package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +56 -2
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+LifecycleCacheTests.swift +73 -0
- package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +44 -14
- package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollGesture.swift +2 -2
- package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SequenceExecution.swift +2 -106
- package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +126 -11
- package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +51 -8
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotTraversalIdentityTests.swift +24 -0
- package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedGesturePolicy.swift +1 -1
- package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SystemModal.swift +43 -35
- package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +14 -0
- package/dist/src/agent-browser-tool.js +1 -1
- package/dist/src/agent-device-client.js +3 -0
- package/dist/src/android-adb.d.ts +1 -1
- package/dist/src/android-adb.js +1 -1
- package/dist/src/android-input-method-overlays.js +1 -0
- package/dist/src/android-input-ownership.js +1 -6
- package/dist/src/android-system-chrome.js +1 -0
- package/dist/src/android.js +1 -1
- package/dist/src/app-lifecycle.js +5 -5
- package/dist/src/app-log-request-scope.js +1 -0
- package/dist/src/app-resolution.js +1 -0
- package/dist/src/apple-multitouch-support.js +1 -0
- package/dist/src/apps.js +5 -5
- package/dist/src/audio-probe.js +1 -1
- package/dist/src/boot-diagnostics.js +2 -0
- package/dist/src/cli-config.js +1 -0
- package/dist/src/cli-help.js +64 -30
- package/dist/src/cli-runner.js +1 -1
- package/dist/src/cli.js +15 -11
- package/dist/src/command-schema.js +3 -3
- package/dist/src/config.js +1 -0
- package/dist/src/context.js +1 -0
- package/dist/src/contracts.d.ts +1 -1
- package/dist/src/contracts.js +1 -1
- package/dist/src/daemon-shutdown-report.js +1 -0
- package/dist/src/debug-symbols.js +1 -1
- package/dist/src/device-input-state.js +1 -1
- package/dist/src/devices2.js +1 -1
- package/dist/src/find.js +1 -1
- package/dist/src/finders.js +1 -1
- package/dist/src/generic.js +1 -1
- package/dist/src/helper.js +1 -1
- package/dist/src/index.d.ts +412 -289
- package/dist/src/index.js +1 -1
- package/dist/src/input-actions.js +4 -3
- package/dist/src/input-actions2.js +1 -1
- package/dist/src/install-artifact.js +1 -0
- package/dist/src/install-source.d.ts +5 -1
- package/dist/src/install-source.js +1 -1
- package/dist/src/install-source2.js +1 -1
- package/dist/src/interaction-snapshot.js +1 -1
- package/dist/src/interaction.d.ts +230 -0
- package/dist/src/interaction.js +1 -1
- package/dist/src/interactor.js +2 -2
- package/dist/src/internal/bin.js +1 -1
- package/dist/src/internal/daemon.js +43 -17
- package/dist/src/internal/png-worker.d.ts +22 -0
- package/dist/src/internal/png-worker.js +1 -1
- package/dist/src/launch-console.js +1 -0
- package/dist/src/lease-context.js +1 -0
- package/dist/src/lease.js +1 -1
- package/dist/src/linux.js +1 -1
- package/dist/src/logcat.js +5 -0
- package/dist/src/metro.d.ts +2 -2
- package/dist/src/notifications.js +1 -1
- package/dist/src/png-worker-contract.js +1 -1
- package/dist/src/process-lock.js +1 -0
- package/dist/src/react-native.js +1 -1
- package/dist/src/record-trace.js +1 -1
- package/dist/src/register-builtins.js +1 -0
- package/dist/src/registry.js +24 -24
- package/dist/src/reporting.js +8 -7
- package/dist/src/runner-client.js +1 -1
- package/dist/src/runner-disposal.js +2 -0
- package/dist/src/runner-lease.js +1 -0
- package/dist/src/runner-sequence.js +1 -1
- package/dist/src/runtime-transport.js +1 -1
- package/dist/src/runtime.js +3 -3
- package/dist/src/runtime2.js +1 -0
- package/dist/src/sdk-android-adb.d.ts +119 -33
- package/dist/src/sdk-android-adb.js +4 -4
- package/dist/src/sdk-app-inventory.js +1 -1
- package/dist/src/sdk-batch-runner.d.ts +2 -1
- package/dist/src/sdk-batch-runner.js +2 -2
- package/dist/src/sdk-batch.js +2 -2
- package/dist/src/sdk-contracts.d.ts +105 -98
- package/dist/src/sdk-contracts.js +2 -2
- package/dist/src/sdk-device.js +1 -0
- package/dist/src/sdk-finders.d.ts +3 -3
- package/dist/src/sdk-finders.js +1 -1
- package/dist/src/sdk-io.d.ts +1 -1
- package/dist/src/sdk-io.js +1 -1
- package/dist/src/sdk-remote-config.d.ts +9 -1
- package/dist/src/sdk-remote-config.js +1 -1
- package/dist/src/sdk-selectors.js +1 -1
- package/dist/src/selector-runtime.js +1 -1
- package/dist/src/selector-vocabulary.js +1 -0
- package/dist/src/selectors.d.ts +12 -3
- package/dist/src/selectors.js +1 -1
- package/dist/src/server.js +3 -3
- package/dist/src/session-target-evidence.js +1 -0
- package/dist/src/session.js +8 -10
- package/dist/src/setting-state.js +1 -1
- package/dist/src/simulator.js +1 -1
- package/dist/src/snapshot-diagnostics.js +5 -2
- package/dist/src/snapshot.js +1 -1
- package/dist/src/snapshot2.js +1 -2
- package/dist/src/tool-provider.js +2 -2
- package/dist/src/tool-provider2.js +1 -1
- package/dist/src/tv-remote.js +13 -12
- package/dist/src/url.js +1 -1
- package/dist/src/web.js +1 -1
- package/package.json +33 -20
- package/server.json +2 -2
- package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.19.2.apk +0 -0
- package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.19.2.apk.sha256 +0 -1
- package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.19.2.manifest.json +0 -10
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.19.2.apk +0 -0
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.19.2.apk.sha256 +0 -1
- package/dist/src/apple-runner-options.js +0 -1
- package/dist/src/cli-output.js +0 -1
- package/dist/src/client.js +0 -3
- package/dist/src/handler-utils.js +0 -1
- package/dist/src/output-path.js +0 -1
- package/dist/src/points.js +0 -4
- package/dist/src/provider.js +0 -1
- package/dist/src/providers.js +0 -1
- package/dist/src/record-trace-recording.js +0 -23
- package/dist/src/recording-provider.js +0 -1
- package/dist/src/selectors2.js +0 -1
- package/dist/src/simctl.js +0 -1
- package/dist/src/snapshot-helper.js +0 -5
- package/dist/src/ttl-memo.js +0 -1
- package/dist/src/xml.js +0 -2
- /package/{macos-helper → apple/macos-helper}/Package.swift +0 -0
- /package/{macos-helper → apple/macos-helper}/Sources/AgentDeviceMacOSHelper/AudioProbe.swift +0 -0
- /package/{macos-helper → apple/macos-helper}/Sources/AgentDeviceMacOSHelper/SnapshotTraversal.swift +0 -0
- /package/{macos-helper → apple/macos-helper}/Sources/AgentDeviceMacOSHelper/main.swift +0 -0
- /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunner/AgentDeviceRunnerApp.m +0 -0
- /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/project.pbxproj +0 -0
- /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -0
- /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/xcshareddata/xcschemes/AgentDeviceRunner.xcscheme +0 -0
- /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/AgentDeviceRunnerUITests-Bridging-Header.h +0 -0
- /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/AgentDeviceRunnerUITests.entitlements +0 -0
- /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerObjCExceptionCatcher.h +0 -0
- /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerObjCExceptionCatcher.m +0 -0
- /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTapPointPolicy.swift +0 -0
- /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +0 -0
- /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Environment.swift +0 -0
- /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Exceptions.swift +0 -0
- /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+FlatSnapshotFiltering.swift +0 -0
- /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Navigation.swift +0 -0
- /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScreenRecorder.swift +0 -0
- /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +0 -0
- /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Transport.swift +0 -0
- /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TvRemote.swift +0 -0
- /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests.xctestplan +0 -0
- /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/RecordingScripts/recording-overlay.swift +0 -0
- /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/RecordingScripts/recording-resize.swift +0 -0
- /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/RecordingScripts/recording-trim.swift +0 -0
- /package/{src/platforms/linux → linux}/atspi-dump.py +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{_ as e}from"./sdk-contracts.js";function t(e){return e.map(e=>({args:e.args.join(` `),exitCode:e.exitCode,stderr:e.stderr.slice(0,400)}))}const n=[`camera`,`microphone`,`photos`,`contacts`,`contacts-limited`,`notifications`,`calendar`,`location`,`location-always`,`media-library`,`motion`,`reminders`,`siri`];function r(t){let n=t.trim().toLowerCase();if(n===`grant`)return`grant`;if(n===`deny`)return`deny`;if(n===`reset`)return`reset`;throw new e(`INVALID_ARGS`,`Invalid permission action: ${t}. Use grant|deny|reset.`)}function i(t){let r=t?.trim().toLowerCase();if(r===`camera`||r===`microphone`||r===`photos`||r===`contacts`||r===`contacts-limited`||r===`notifications`||r===`calendar`||r===`location`||r===`location-always`||r===`media-library`||r===`motion`||r===`reminders`||r===`siri`)return r;throw new e(`INVALID_ARGS`,`permission setting requires a target: ${n.join(`|`)}`)}function a(t){let n=t.trim().toLowerCase();if(n===`light`)return`light`;if(n===`dark`)return`dark`;if(n===`toggle`)return`toggle`;throw new e(`INVALID_ARGS`,`Invalid appearance state: ${t}. Use light|dark|toggle.`)}function o(t){let n=t.toLowerCase();if(n===`on`||n===`true`||n===`1`)return!0;if(n===`off`||n===`false`||n===`0`)return!1;throw new e(`INVALID_ARGS`,`Invalid setting state: ${t}`)}export{t as a,i,a as n,r,o as t};
|
package/dist/src/simulator.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as e}from"./rolldown-runtime.js";import{
|
|
1
|
+
import{t as e}from"./rolldown-runtime.js";import{_ as t}from"./sdk-contracts.js";import{h as n,p as r}from"./sdk-android-adb.js";import{l as i,n as a,s as o,t as s}from"./boot-diagnostics.js";import{M as c,j as l,k as u}from"./runner-disposal.js";import{a as d,i as f}from"./tool-provider.js";import{n as p,o as m}from"./config.js";var h=e({SIMULATOR_BOOTED_MEMO_TTL_MS:()=>v,ensureBootedSimulator:()=>E,getSimulatorState:()=>O,markSimulatorBooted:()=>S,openIosSimulatorApp:()=>T,requireSimulatorDevice:()=>w,shutdownSimulator:()=>D});const g=[`Simulator`],_=[`Device Hub`,`Simulator`],v=5e3,y=u({ttlMs:v});function b(e){return`${e.id}|${e.simulatorSetPath??``}`}function x(e){return y.get(b(e))===!0}function S(e){y.set(b(e),!0)}function C(e){y.delete(b(e))}function w(e,n){if(e.kind!==`simulator`)throw new t(`UNSUPPORTED_OPERATION`,`${n} is only supported on iOS simulators`)}async function T(e={}){let t=e.deviceHub?_:g,n=e.background?[`-g`,`-a`]:[`-a`];for(let e of t)if((await f(`open`,[...n,e],{allowFailure:!0,timeoutMs:1e4})).exitCode===0)return}async function E(e,l={}){if(e.kind!==`simulator`)return;if((x(e)?`Booted`:await O(e))===`Booted`){S(e),l.focusExisting&&await T({background:l.deviceHub,deviceHub:l.deviceHub});return}l.onColdBootStart?.(e);let u=o.fromTimeoutMs(p),f,m;try{await i(async({deadline:i})=>{if(i?.isExpired())throw new t(`COMMAND_FAILED`,`iOS simulator boot deadline exceeded`,{timeoutMs:p});let a=Math.max(1e3,i?.remainingMs()??18e4);f=await d(c(e,[`boot`,e.id]),{allowFailure:!0,timeoutMs:a});let o=`${f.stdout}\n${f.stderr}`.toLowerCase(),s=o.includes(`already booted`)||o.includes(`current state: booted`);if(f.exitCode!==0&&!s)throw new t(`COMMAND_FAILED`,`simctl boot failed`,r(f));m=await d(c(e,[`bootstatus`,e.id,`-b`]),{allowFailure:!0,timeoutMs:a}),n(m,`simctl bootstatus failed`);let l=await O(e);if(l!==`Booted`)throw new t(`COMMAND_FAILED`,`Simulator is still booting`,{state:l})},{maxAttempts:3,baseDelayMs:500,maxDelayMs:2e3,jitter:.2,shouldRetry:e=>{let t=a({error:e,stdout:m?.stdout??f?.stdout,stderr:m?.stderr??f?.stderr,context:{platform:`ios`,phase:`boot`}});return t!==`IOS_BOOT_TIMEOUT`&&t!==`CI_RESOURCE_STARVATION_SUSPECTED`}},{deadline:u,phase:`boot`,classifyReason:e=>a({error:e,stdout:m?.stdout??f?.stdout,stderr:m?.stderr??f?.stderr,context:{platform:`ios`,phase:`boot`}})})}catch(n){let r=a({error:n,stdout:m?.stdout??f?.stdout,stderr:m?.stderr??f?.stderr,context:{platform:`ios`,phase:`boot`}});throw new t(`COMMAND_FAILED`,`iOS simulator failed to boot`,{platform:`ios`,deviceId:e.id,timeoutMs:p,elapsedMs:u.elapsedMs(),reason:r,hint:s(r),boot:f,bootstatus:m})}S(e),await T({deviceHub:l.deviceHub})}async function D(e){C(e);let t=await d(c(e,[`shutdown`,e.id]),{allowFailure:!0,timeoutMs:15e3});return{success:t.exitCode===0,exitCode:t.exitCode,stdout:t.stdout,stderr:t.stderr}}async function O(e){let t=typeof e==`string`?e:e.id,n=await d(typeof e==`string`?l([`list`,`devices`,`-j`]):c(e,[`list`,`devices`,`-j`]),{allowFailure:!0,timeoutMs:m});if(n.exitCode!==0)return null;try{let e=JSON.parse(n.stdout);for(let n of Object.values(e.devices??{})){let e=n.find(e=>e.udid===t);if(e)return e.state}return null}catch{return null}}export{D as a,w as i,O as n,h as o,S as r,E as t};
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
-
import{F as e}from"./sdk-contracts.js";import{n as t,t as n}from"./version.js";import{n as r,t as i}from"./path-resolution.js";import{a,n as o,o as s,u as c}from"./host-process.js";import{d as l,l as u,u as d}from"./sdk-batch-runner.js";import f from"node:crypto";import p from"node:fs";import m from"node:path";function h(e){return new Promise((t,n)=>{let r=``;e.setEncoding(`utf8`),e.on(`data`,e=>{r+=e}),e.on(`end`,()=>t(r)),e.on(`error`,n)})}async function g(t,n,r){let i=[],a=0;for await(let o of t){let t=Buffer.isBuffer(o)?o:Buffer.from(o);if(a+=t.length,a>n)throw new e(`INVALID_ARGS`,r);i.push(t)}return Buffer.concat(i)}function _(e,t={}){let n=v(e,t);return{baseDir:n,infoPath:m.join(n,`daemon.json`),lockPath:m.join(n,`daemon.lock`),logPath:m.join(n,`daemon.log`),sessionsDir:m.join(n,`sessions`)}}function v(e,t){let n=(e??``).trim();return n?r(n,{env:t.env}):y(t)}function y(e={}){let t=m.join(i(`~`,{env:e.env}),`.agent-device`),r=e.projectRoot??n();return b(r)?m.join(t,`dev`,x(r)):t}function b(e){return p.existsSync(m.join(e,`package.json`))&&p.existsSync(m.join(e,`src`,`daemon.ts`))}function x(e){let t=ee(e),n=m.basename(t).replaceAll(/[^a-zA-Z0-9._-]+/g,`-`),r=f.createHash(`sha1`).update(t).digest(`hex`).slice(0,12);return`${n||`agent-device`}-${r}`}function ee(e){try{return p.realpathSync.native(e)}catch{return m.resolve(e)}}function te(e){let t=(e??``).trim().toLowerCase();return t===`http`?`http`:t===`dual`?`dual`:`socket`}function ne(e){let t=(e??``).trim().toLowerCase();return t===`auto`?`auto`:t===`socket`?`socket`:t===`http`?`http`:`auto`}function re(e){return(e??``).trim().toLowerCase()===`tenant`?`tenant`:`none`}function ie(e){if(!e)return;let t=e.trim();if(t&&/^[a-zA-Z0-9._-]{1,128}$/.test(t))return t}const ae=/(?:^|[^\w$.])(?:import|export)\s+(?:type\s+)?(?:[^'"`]*?\s+from\s+)?['"]([^'"]+)['"]/gm,S=/import\(\s*['"]([^'"]+)['"]\s*\)/gm,C=[`.ts`,`.tsx`,`.js`,`.jsx`,`.mjs`,`.cjs`];function w(){let e=process.argv[1];return e?T(e):`unknown`}function T(e,t=n()){try{let n=m.resolve(t),r=[m.resolve(e)],i=new Set,a=[];for(;r.length>0;){let e=r.pop();if(!e||i.has(e))continue;i.add(e);let t=p.statSync(e);if(!t.isFile())continue;let o=m.relative(n,e)||e;a.push(`${o}:${t.size}:${Math.trunc(t.mtimeMs)}`);let s=p.readFileSync(e,`utf8`);for(let t of E(s)){let n=O(e,t);n&&r.push(n)}}let o=a.sort().join(`|`),s=f.createHash(`sha1`).update(o).digest(`hex`);return`graph:${a.length}:${s}`}catch{return`unknown`}}function E(e){let t=new Set;return D(e,ae,t),D(e,S,t),[...t]}function D(e,t,n){t.lastIndex=0;let r=null;for(;(r=t.exec(e))!==null;){let e=r[1]?.trim();e?.startsWith(`.`)&&n.add(e)}}function O(e,t){let n=m.resolve(m.dirname(e),t),r=k(n);if(r)return r;for(let e of C){let t=k(`${n}${e}`);if(t)return t}for(let e of C){let t=k(m.join(n,`index${e}`));if(t)return t}return null}function k(e){try{return p.statSync(e).isFile()?e:null}catch{return null}}const A=[/(^|[/\s"'=])dist\/src\/daemon\.js($|[\s"'])/,/(^|[/\s"'=])dist\/src\/internal\/daemon\.js($|[\s"'])/,/(^|[/\s"'=])src\/daemon\.ts($|[\s"'])/];function j(e){let t=e.toLowerCase().replaceAll(`\\`,`/`);return t.includes(`agent-device`)?A.some(e=>e.test(t)):!1}function M(e,t){if(!o(e))return!1;if(t){let n=s(e);if(!n||n!==t)return!1}let n=a(e);return n?j(n):!1}function N(e,t){try{return process.kill(e,t),!0}catch(e){let t=e.code;if(t===`ESRCH`||t===`EPERM`)return!1;throw e}}async function P(e,t){M(e,t.expectedStartTime)&&N(e,`SIGTERM`)&&(await c(e,t.termTimeoutMs)||N(e,`SIGKILL`)&&await c(e,t.killTimeoutMs))}const F=/^[A-Za-z0-9_@%+=:,./-]+$/;function I(e){return`'${e.replaceAll(`'`,`'\\''`)}'`}function L(e){return F.test(e)?e:I(e)}function R(e,t){let n=[],r=e+t.toString(),i=r.indexOf(`
|
|
1
|
+
import{T as e,_ as t,h as n}from"./sdk-contracts.js";import{N as r,j as i}from"./sdk-android-adb.js";import{P as a,b as o,h as s}from"./sdk-batch.js";import{Qn as c,Yn as ee,nr as te,qn as ne,rr as l}from"./tv-remote.js";import{n as re,t as u}from"./version.js";import{n as d,t as ie}from"./path-resolution.js";import{m as ae}from"./sdk-device.js";import{st as oe}from"./sdk-selectors.js";import{d as se,f,u as p}from"./sdk-batch-runner.js";import{a as ce,n as le,o as ue,u as m}from"./host-process.js";import h from"node:crypto";import g from"node:fs";import _ from"node:path";import{StringDecoder as de}from"node:string_decoder";const v=`/agent-device`,fe=`x-agent-device-tenant`;function pe(e){return me(e,v)}function me(e,t){let n=e.endsWith(`/`)?e:`${e}/`;return new URL(t.replace(/^\/+/,``),n).toString()}function he(e){let t=e?.trim();return t?{authorization:`Bearer ${t}`,"x-agent-device-token":t}:{}}function ge(e){let t=e?.trim();return t?{[fe]:t}:{}}const _e=`.webm`;function ve(e){return e===`web`?_e:`.mp4`}function ye(e,t){return _.extname(e)?e:`${e}${t}`}function be(e){return`./recording-${Date.now()}${ve(e)}`}function xe(e){return new Promise((t,n)=>{let r=``;e.setEncoding(`utf8`),e.on(`data`,e=>{r+=e}),e.on(`end`,()=>t(r)),e.on(`error`,n)})}async function Se(e,n,r){let i=[],a=0;for await(let o of e){let e=Buffer.isBuffer(o)?o:Buffer.from(o);if(a+=e.length,a>n)throw new t(`INVALID_ARGS`,r);i.push(e)}return Buffer.concat(i)}function y(e){return e.replace(/[^a-zA-Z0-9._-]/g,`_`)}function b(e,t){return d(e,{cwd:t})}function x(e,t,n){e.saveScriptPath!==void 0&&e.saveScriptPath!==t&&!n&&(e.saveScriptForce=void 0),e.saveScriptPath=t}function Ce(e,t){if(t.flags?.noRecord||Ee(e,t))return;t.flags?.saveScript&&(e.recordSession=!0,typeof t.flags.saveScript==`string`&&(x(e,b(t.flags.saveScript),t.flags.force),e.saveScriptDefaultedHealedPath=!1),t.flags.force&&(e.saveScriptForce=!0));let n={ts:Date.now(),command:t.command,positionals:t.positionals,runtime:t.runtime,flags:Oe(t.flags),result:t.result,...t.targetEvidence?{targetEvidence:t.targetEvidence}:{}};return e.actions.push(n),i({level:`debug`,phase:`record_action`,data:{command:t.command,session:e.name}}),n}const we=new Set([`snapshot`,`get`,`is`,`find`]);function Te(e){return e.internal?.replayPlanStep===!0?!1:we.has(e.command)}function Ee(e,t){return!t.interactiveObservation||e.saveScriptBoundary===void 0?!1:t.flags?.record!==!0}const De=[`platform`,`device`,`udid`,`serial`,`out`,`verbose`,`metroHost`,`metroPort`,`bundleUrl`,`launchUrl`,`snapshotInteractiveOnly`,`snapshotDepth`,`snapshotScope`,`snapshotRaw`,...ee,`relaunch`,`saveScript`,`force`,`noRecord`,`record`,`fps`,`quality`,`hideTouches`,`count`,`pointerCount`,`intervalMs`,`delayMs`,`holdMs`,`jitterPx`,`doubleTap`,`clickButton`,`pauseMs`,`pattern`];function Oe(e){if(!e)return{};let t={};for(let n of De)e[n]!==void 0&&(t[n]=e[n]);return t}function ke(e){let t=e.result?.text;if(typeof t==`string`&&t.trim().length>0)return t;let n=e.positionals??[];return n.length===0?``:n[0]?.startsWith(`@`)?n.length>=3?n.slice(2).join(` `).trim():n.slice(1).join(` `).trim():n.length>=3&&!Number.isNaN(Number(n[0]))&&!Number.isNaN(Number(n[1]))?n.slice(2).join(` `).trim():n.slice(1).join(` `).trim()}function S(e){return e.startsWith(`@`)?n(e)?.base??e:e}const C=/^-?\d+(\.\d+)?$/,Ae=/^[^\s"\\]+$/,je=new Map([[`--count`,`count`],[`--interval-ms`,`intervalMs`],[`--hold-ms`,`holdMs`],[`--jitter-px`,`jitterPx`]]),Me=new Map([[`--count`,`count`],[`--pause-ms`,`pauseMs`]]),Ne=new Map([[`--pointer-count`,`pointerCount`]]),Pe=new Map([[`--delay-ms`,`delayMs`]]);function w(e){return e===`click`||e===`press`}function T(e){return w(e)||e===`longpress`}function E(e){return e===`type`||e===`fill`}function D(e){return A(e,Fe)}function O(e){return JSON.stringify(e)}function k(e){return A(e,j)}function A(e,t){return t(e)?e:O(e)}function Fe(e){return j(e)&&e.startsWith(`@`)||C.test(e)}function j(e){return Ae.test(e)}const Ie=new Set([`fill`,`type`]);function Le(e){if(!Ie.has(e.command)){let t=(e.positionals??[]).map(e=>D(e));return[e.command,...t].join(` `)}let t=Re(e).map(e=>D(e)).join(` `);return[e.command,t,`<text>`].filter(e=>e.length>0).join(` `)}function Re(e){if(e.command===`type`)return[];let t=e.positionals??[],n=t[0];return n===void 0?[]:n.startsWith(`@`)?[n]:t.length>=3&&C.test(n)&&C.test(t[1]??``)?[n,t[1]]:[n]}function M(e,t){let n=t.flags??{};if(w(t.command)){typeof n.count==`number`&&e.push(`--count`,String(n.count)),typeof n.intervalMs==`number`&&e.push(`--interval-ms`,String(n.intervalMs)),typeof n.holdMs==`number`&&e.push(`--hold-ms`,String(n.holdMs)),typeof n.jitterPx==`number`&&e.push(`--jitter-px`,String(n.jitterPx)),n.doubleTap===!0&&e.push(`--double-tap`);let t=n.clickButton;t&&t!==`primary`&&e.push(`--button`,t);return}if(t.command===`swipe`){typeof n.count==`number`&&e.push(`--count`,String(n.count)),typeof n.pauseMs==`number`&&e.push(`--pause-ms`,String(n.pauseMs)),(n.pattern===`one-way`||n.pattern===`ping-pong`)&&e.push(`--pattern`,n.pattern);return}if(t.command===`gesture`){typeof n.pointerCount==`number`&&e.push(`--pointer-count`,String(n.pointerCount));return}E(t.command)&&typeof n.delayMs==`number`&&e.push(`--delay-ms`,String(n.delayMs))}function N(e,t){t&&((t.platform===`ios`||t.platform===`android`)&&e.push(`--platform`,t.platform),typeof t.metroHost==`string`&&t.metroHost.length>0&&e.push(`--metro-host`,k(t.metroHost)),typeof t.metroPort==`number`&&e.push(`--metro-port`,String(t.metroPort)),typeof t.bundleUrl==`string`&&t.bundleUrl.length>0&&e.push(`--bundle-url`,k(t.bundleUrl)),typeof t.launchUrl==`string`&&t.launchUrl.length>0&&e.push(`--launch-url`,k(t.launchUrl)))}function ze(e,t){let[n,...r]=t.positionals??[];n&&e.push(k(n));for(let t of r)e.push(D(t));typeof t.flags?.fps==`number`&&e.push(`--fps`,String(t.flags.fps)),typeof t.flags?.screenshotMaxSize==`number`&&e.push(`--max-size`,String(t.flags.screenshotMaxSize)),(typeof t.flags?.quality==`number`||typeof t.flags?.quality==`string`)&&e.push(`--quality`,String(t.flags.quality)),t.flags?.hideTouches&&e.push(`--hide-touches`)}function Be(e,t){t.flags?.snapshotInteractiveOnly&&e.push(`-i`),typeof t.flags?.snapshotDepth==`number`&&e.push(`-d`,String(t.flags.snapshotDepth)),t.flags?.snapshotScope&&e.push(`-s`,D(t.flags.snapshotScope)),t.flags?.snapshotRaw&&e.push(`--raw`)}function Ve(e,t){for(let n of t.positionals??[])e.push(D(n));c(e,t.flags)}function He(e,t,n={}){let r=t.positionals??[],i=n.includeAllPositionals?r:r.slice(0,1);for(let t of i)e.push(k(t));N(e,t.flags)}function Ue(e,t){for(let n of t.positionals??[])e.push(D(t.command===`wait`?S(n):n));M(e,t)}function We(e,t){let n=[],r={},i=w(e)?je:e===`swipe`?Me:e===`gesture`?Ne:E(e)?Pe:void 0;for(let a=0;a<t.length;a+=1){let o=t[a];if(w(e)&&o===`--double-tap`){r.doubleTap=!0;continue}let s=t[a+1];if(w(e)&&o===`--button`&&s!==void 0){let e=s;(e===`primary`||e===`secondary`||e===`middle`)&&(r.clickButton=e),a+=1;continue}let c=i?.get(o);if(c&&s!==void 0){let e=F(s);if(e!==null){r[c]=e,a+=1;continue}}if(e===`swipe`&&o===`--pattern`&&s!==void 0){let e=s;(e===`one-way`||e===`ping-pong`)&&(r.pattern=e),a+=1;continue}n.push(o)}return{positionals:n,flags:r}}function P(e){let t=[],n={};for(let r=0;r<e.length;r+=1){let i=e[r],a=e[r+1];if(i===`--platform`&&a!==void 0){let e=a;(e===`ios`||e===`android`)&&(n.platform=e),r+=1;continue}if(i===`--metro-host`&&a!==void 0){n.metroHost=a,r+=1;continue}if(i===`--metro-port`&&a!==void 0){let e=F(a);e!==null&&(n.metroPort=e),r+=1;continue}if(i===`--bundle-url`&&a!==void 0){n.bundleUrl=a,r+=1;continue}if(i===`--launch-url`&&a!==void 0){n.launchUrl=a,r+=1;continue}t.push(i)}return{positionals:t,flags:n}}function F(e){if(!e)return null;let t=Number(e);return!Number.isFinite(t)||t<0?null:Math.floor(t)}function Ge(e,t){for(let n of t.positionals??[])e.push(D(n));t.flags?.relaunch&&e.push(`--relaunch`),N(e,t.runtime)}function Ke(e){let t=[],n={};for(let r of e){if(r===`--relaunch`){n.relaunch=!0;continue}t.push(r)}let r=P(t);return{positionals:r.positionals,flags:n,runtime:qe(r.flags)?r.flags:void 0}}function qe(e){return!!(e.platform||e.metroHost||e.metroPort!==void 0||e.bundleUrl||e.launchUrl)}function Je(e,t={}){let n=[e.command];return e.command===`snapshot`?Be(n,e):e.command===`open`?Ge(n,e):e.command===`runtime`?He(n,e,{includeAllPositionals:t.runtimeIncludeAllPositionals}):e.command===`record`?ze(n,e):e.command===`screenshot`?Ve(n,e):Ue(n,e),n.join(` `)}function Ye(e){return e.targetEvidence?[oe(e.targetEvidence)]:[]}function Xe(e){let n=e.flatMap((e,t)=>e.command===`open`?[t]:[]);if(n.length!==1||n[0]!==0)throw new t(`COMMAND_FAILED`,`Cannot publish this session: an open-to-destination script requires exactly one initial recorded open.`,{retriable:!1,hint:`Close this session and start a fresh one with open <app> --save-script[=<path>].`});if(e.some(e=>e.command===`close`))throw new t(`COMMAND_FAILED`,`Cannot publish an active-session script containing close.`,{retriable:!1,hint:`Close this session and record the journey again from a fresh open --save-script session.`});let r=-1;for(let[t,n]of e.entries())s({command:n.command,positionals:n.positionals,flags:n.flags})===`mutates-app`&&(r=t);if(!e.slice(r+1).some($e))throw new t(`COMMAND_FAILED`,`Cannot publish this session without a portable destination guard after the final mutating action.`,{retriable:!0,hint:`Record a selective selector-targeted wait, for example wait 'role="heading" label="Screen X"', then retry session save-script.`})}function Ze(e){for(let n of e){let e=et(n),r=e??(n.command===`wait`?n.positionals[0]:void 0);if(r?.startsWith(`@`))throw new t(`COMMAND_FAILED`,`Cannot publish recorded step "${n.command} ${r}": the session-local ref was not converted to a portable selector.`,{retriable:!1,hint:`Close this session and record the journey again using selectors or resolvable refs.`});if(n.command===`find`&&s(n)===`mutates-app`)throw new t(`COMMAND_FAILED`,`Cannot publish a recorded mutating find step because its target identity is not replay-verifiable.`,{retriable:!1,hint:`Close this session and record the journey again with an explicit selector-targeted click, press, fill, or focus action.`});let i=e;if(!(!i||!a(i)||n.targetEvidence))throw new t(`COMMAND_FAILED`,`Cannot publish recorded step "${n.command} ${i}": recording-time target identity evidence is missing.`,{retriable:!1,hint:`Close this session and record the journey again from open --save-script so target-v1 evidence is captured before each interaction.`})}}function Qe(e,n){if(e instanceof t){if(e.details?.reason===`script_target_exists`)return new t(e.code,`A file already exists at ${String(e.details.path)}.`,{...e.details,retriable:!0,hint:`Retry session save-script with another path, or pass --force to replace the existing file. The session remains armed.`});let n=e.details?.retriable===!0;return new t(e.code,e.message,{...e.details,retriable:n,hint:e.details?.hint??(n?`Fix the recorded journey or target, then retry session save-script. The session remains armed.`:`Close this session and start a fresh one with open <app> --save-script[=<path>].`)})}let r=e instanceof Error?e.message:String(e);return new t(`COMMAND_FAILED`,`Failed to publish the active session script${n?` to ${n}`:``}: ${r}`,{retriable:!0,hint:`Check the target path and permissions, then retry session save-script. The session remains armed.`})}function $e(e){if(e.command!==`wait`)return!1;let t=o(e.positionals);return t?.kind===`selector`&&a(t.selectorExpression)!==null}function et(e){if(e.command===`get`)return e.positionals[1];if(T(e.command)||e.command===`fill`){let[t,n]=e.positionals;return t!==void 0&&n!==void 0&&I(t)&&I(n)?void 0:t}}function I(e){return e.trim().length>0&&Number.isFinite(Number(e))}function tt(e){return e.saveScriptBoundary===void 0?!1:e.saveScriptCommitted?!0:!e.saveScriptComplete}var nt=class{sessionsDir;constructor(e){this.sessionsDir=e}write(e,t){let n=e.saveScriptBoundary!==void 0,r=t?.publication===`active`,i;try{if(!e.recordSession||tt(e))return{written:!1};let a=rt(e,{appendCompleteSentinel:n,activePublication:r});i=this.resolveScriptPath(e);let o=_.dirname(i);return g.existsSync(o)||g.mkdirSync(o,{recursive:!0}),ot({scriptPath:i,script:a.script,force:t?.force}),n&&(e.saveScriptCommitted=!0),{written:!0,path:i,actionCount:a.actionCount}}catch(t){return it({session:e,error:t,scriptPath:i,repairArmed:n,activePublication:r})}}resolveScriptPath(e){if(e.saveScriptPath)return b(e.saveScriptPath);let t=y(e.name),n=new Date(e.createdAt).toISOString().replace(/[:.]/g,`-`);return _.join(this.sessionsDir,`${t}-${n}.ad`)}};function rt(e,t){let n=st(e,{strictPortableRefs:t.activePublication});return t.activePublication&&Xe(n),{script:gt(e,n,t.appendCompleteSentinel),actionCount:n.length}}function it(e){let{session:n,error:r,scriptPath:a,repairArmed:o,activePublication:s}=e;if(i({level:`warn`,phase:`session_script_write_failed`,data:{session:n.name,path:a,error:r instanceof Error?r.message:String(r)}}),o)return{written:!1,error:at(r,a)};if(s)return{written:!1,error:Qe(r,a)};if(r instanceof t)throw r;return{written:!1}}function at(e,n){if(e instanceof t)return e;let r=e instanceof Error?e.message:String(e);return new t(`COMMAND_FAILED`,`Failed to write the healed script${n?` to ${n}`:``}: ${r}`,{hint:`The repair transaction completed but the healed .ad could not be published; check the target path and permissions, then retry close --save-script.`})}function ot(e){let{scriptPath:n,script:r,force:i}=e,a=_.dirname(n),o=_.join(a,`.${_.basename(n)}.${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`);g.writeFileSync(o,r);try{if(i){g.renameSync(o,n);return}g.linkSync(o,n)}catch(e){throw e.code===`EEXIST`?new t(`COMMAND_FAILED`,`A file already exists at ${n}; remove it, pass replay --save-script=<other-path>, or pass --force/--overwrite to replace it.`,{reason:`script_target_exists`,path:n}):e}finally{g.rmSync(o,{force:!0})}}function st(e,t={}){let n=e.saveScriptBoundary!==void 0,r=e.actions.slice(e.saveScriptBoundary??0),i=[];for(let a of r){if(a.command===`snapshot`)continue;let r=lt(a);if(r){i.push(r);continue}(n||t.strictPortableRefs)&&ct(a);let o=ht(e,a);o&&i.push(o),i.push(a)}return t.strictPortableRefs&&Ze(i),i}function ct(e){if(!L(e.command))return;let n=e.command===`get`?e.positionals?.[1]:e.positionals?.[0];if(n?.startsWith(`@`))throw new t(`COMMAND_FAILED`,`Cannot write recorded step "${e.command} ${n}" to a script: it never resolved to a selector, so the ref would not resolve in a fresh replay session.`)}function lt(e){let t=ut(e);if(!(!t||!L(e.command)))return w(e.command)?{...e,positionals:[t]}:e.command===`longpress`?ft(e,t):e.command===`fill`?dt(e,t):pt(e,t)}function ut(e){let t=Array.isArray(e.result?.selectorChain)&&e.result.selectorChain.every(e=>typeof e==`string`)?e.result.selectorChain:[];return t.length>0?t.join(` || `):void 0}function L(e){return T(e)||e===`fill`||e===`get`}function dt(e,t){let n=ke(e);return n.length>0?{...e,positionals:[t,n]}:void 0}function ft(e,t){let n=typeof e.result?.durationMs==`number`?String(e.result.durationMs):mt(e.positionals??[]);return{...e,positionals:n?[t,n]:[t]}}function pt(e,t){let n=e.positionals?.[0];return n===`text`||n===`attrs`?{...e,positionals:[n,t]}:void 0}function mt(e){let t=e.at(-1);if(!(e.length<=1||t===void 0||t.trim()===``))return Number.isFinite(Number(t))?t:void 0}function ht(e,t){if(!L(t.command))return;let n=t.result?.refLabel;if(typeof n!=`string`||n.trim().length===0)return;let r=n.trim();return{ts:t.ts,command:`snapshot`,positionals:[],flags:{platform:e.device.platform,snapshotInteractiveOnly:!0,snapshotScope:r},result:{scope:r}}}function gt(e,t,n){let r=[],i=e.device.kind?` kind=${e.device.kind}`:``;r.push(`context platform=${ae(e.device)} device=${O(e.device.name)}${i} theme=unknown`);for(let e of t)e.flags?.noRecord||(r.push(...Ye(e)),r.push(_t(e)));return n&&r.push(`# agent-device:heal-complete`),`${r.join(`
|
|
2
|
+
`)}\n`}function _t(e){return vt([e.command],e)||Je(e)}function vt(e,t){if(w(t.command))return yt(e,t);if(t.command===`fill`)return bt(e,t);if(t.command===`get`)return xt(e,t)}function yt(e,t){let n=t.positionals?.[0];if(n){if(n.startsWith(`@`))return e.push(D(S(n))),R(e,t),M(e,t),e.join(` `);if(t.positionals.length===1)return e.push(D(n)),M(e,t),e.join(` `)}}function bt(e,t){let n=t.positionals?.[0];if(!n?.startsWith(`@`))return;e.push(D(S(n))),R(e,t);let r=t.positionals.slice(1).join(` `);return t.positionals.length>1&&e.push(D(r)),M(e,t),e.join(` `)}function xt(e,t){let n=t.positionals?.[0],r=t.positionals?.[1];if(!(!n||!r))return e.push(D(n)),e.push(D(S(r))),r.startsWith(`@`)&&R(e,t),e.join(` `)}function R(e,t){let n=t.result?.refLabel;typeof n==`string`&&n.trim().length>0&&e.push(D(n))}function St(e){switch(e.command){case l.open:return`Opened ${B(e)??`session`}`;case l.close:return`Closed ${K(e.result?.session)??`session`}`;case l.click:case l.press:return`Tapped ${B(e)??`target`}`;case l.longPress:return`Long pressed ${B(e)??`target`}`;case l.fill:return`Filled ${B(e)??`target`}`;case l.type:return`Typed ${G(`text`,H(e))}`;case l.install:case l.reinstall:case te.installSource:return`Installed ${B(e)??`app`}`;default:return z(e)??`Ran ${e.command}`}}function Ct(e){let t=e.result??{};return{command:e.command,positionals:V(e),flags:e.flags,action:t.action,message:z(e),ref:t.ref,targetLabel:B(e),selectorChainLength:Vt(t.selectorChain)?.length,x:t.x,y:t.y,x2:t.x2,y2:t.y2,durationMs:t.durationMs,waitedMs:t.waitedMs,found:t.found,path:t.path,outPath:t.outPath,telemetryPath:t.telemetryPath,sessionStateDir:t.sessionStateDir,requestLogPath:t.requestLogPath,runnerLogPath:t.runnerLogPath,platform:t.platform,target:t.target,device:t.device,appName:t.appName,appBundleId:t.appBundleId,bundleId:t.bundleId,packageName:t.packageName,launchTarget:t.launchTarget,textLength:typeof t.text==`string`?Array.from(t.text).length:void 0,nodeCount:Array.isArray(t.nodes)?t.nodes.length:void 0}}function z(e){let t=K(e.result?.message);if(t&&!(wt(e)||Tt(e.result??{})))return t}function wt(e){return Et(e).length>0}function Tt(e){return K(e.refLabel)!==void 0||K(e.selector)!==void 0||Vt(e.selectorChain)!==void 0}function Et(e){return kt(Dt(e).sort((e,t)=>t.raw.length-e.raw.length))}function Dt(e){let t=V(e)??[],n=e.positionals.flatMap((e,n)=>{let r=Ot(e,t[n]);return r?[r]:[]}),r=e.result?.text;return typeof r==`string`&&r.length>0?[{raw:r,display:W(`text`,r)},...n]:n}function Ot(e,t){if(!e)return;let n=t??U(e);return n===e?void 0:{raw:e,display:n}}function kt(e){let t=new Set,n=[];for(let{raw:r,display:i}of e)t.has(r)||(t.add(r),n.push({raw:r,display:i}));return n}function B(e){let t=e.result??{};return At(t)??jt(t)??Mt(t)??zt(e.positionals[0])}function At(e){let t=K(e.ref);if(t)return t.startsWith(`@`)?t:`@${t}`}function jt(e){let t=q(e.x),n=q(e.y);if(t!==void 0&&n!==void 0)return`(${t}, ${n})`}function Mt(e){return K(e.appName)??K(e.appBundleId)??K(e.bundleId)??K(e.packageName)}function V(e){if(e.positionals.length!==0)return e.command===l.type?[G(`text`,H(e))]:e.command===l.fill?Nt(e):e.command===l.find?Pt(e):e.command===l.clipboard?Ft(e):e.command===l.push||e.command===l.triggerAppEvent?It(e,`payload`):e.positionals.map(U)}function Nt(e){let t=G(`text`,H(e)),n=e.result??{},r=K(n.ref);if(r)return[r.startsWith(`@`)?r:`@${r}`,t];let i=K(n.selector);if(i)return[W(`target`,i),t];let a=q(n.x),o=q(n.y);return a!==void 0&&o!==void 0?[String(a),String(o),t]:[t]}function Pt(e){let t=+!!Bt(e.positionals[0]),n=e.positionals[t];if(n===void 0)return;let r=t+1,i=[...t===1?[String(e.positionals[0])]:[],W(`query`,n)],a=e.positionals[r];return a?a===`fill`||a===`type`?[...i,a,G(`text`,H(e))]:[...i,...e.positionals.slice(r).map(Lt)]:i}function Ft(e){let t=e.positionals[0]?.toLowerCase();return t===`read`?[`read`]:t===`write`?[`write`,G(`text`,Rt(e))]:e.positionals.map(U)}function It(e,t){let[n,r,...i]=e.positionals;return[...n?[n]:[],...r?[W(t,r)]:[],...i.map(U)]}function Lt(e){return e===`click`||e===`focus`||e===`exists`||e===`get`||e===`text`||e===`attrs`||e===`wait`?e:U(e)}function H(e){let t=e.result?.text;return typeof t==`string`?Array.from(t).length:e.command===l.type?Array.from(e.positionals.join(` `)).length:0}function Rt(e){let t=e.result?.textLength;return typeof t==`number`&&Number.isFinite(t)?t:Array.from(e.positionals.slice(1).join(` `)).length}function U(e){return zt(e)??W(`arg`,e)}function zt(e){if(!e)return;let t=e.trim();if(/^@[a-zA-Z0-9:_-]+$/.test(t))return t}function W(e,t){return G(e,Array.from(t).length)}function G(e,t){return`<${e}:${t} chars>`}function Bt(e){return e===`text`||e===`label`||e===`value`||e===`role`||e===`id`}function K(e){if(typeof e==`string`)return e.trim().length>0?e:void 0}function q(e){return typeof e==`number`&&Number.isFinite(e)?e:void 0}function Vt(e){return Array.isArray(e)&&e.every(e=>typeof e==`string`)?e:void 0}const J=new Map,Ht=new Set;function Ut(e){return _.join(e,`events.ndjson`)}function Wt(e){return e.command!==l.events}function Gt(t,n,r){let i=e({version:1,ts:r.ts??new Date().toISOString(),session:n,...r});qt(t,`${JSON.stringify(i)}\n`)}async function Kt(e){await(e?J.get(e):Promise.all(J.values()))}function qt(e,t){let n=(J.get(e)??Promise.resolve()).catch(()=>void 0).then(async()=>{await Jt(e),await g.promises.appendFile(e,t,`utf8`)}).catch(t=>{i({level:`warn`,phase:`session_event_log_write_failed`,data:{path:e,error:t instanceof Error?t.message:String(t)}})}).finally(()=>{J.get(e)===n&&J.delete(e)});J.set(e,n)}async function Jt(e){let t=_.dirname(e);if(!Ht.has(t))try{await g.promises.mkdir(t,{recursive:!0}),Ht.add(t)}catch(t){throw i({level:`warn`,phase:`session_event_log_dir_failed`,data:{path:e,error:t instanceof Error?t.message:String(t)}}),t}}function Yt(e,t,n){Gt(e,t,{kind:`action.recorded`,requestId:r().requestId,command:n.command,summary:St(n),details:Ct(n)})}function Xt(e){let{req:t,sessionName:n,requestLogPath:i,runnerLogPath:a}=e;return{kind:`request.started`,requestId:t.meta?.requestId??r().requestId,command:t.command,summary:`Started ${t.command}`,details:{publicSession:t.session,effectiveSession:n,tenant:t.meta?.tenantId,isolation:t.meta?.sessionIsolation,requestLogPath:i,runnerLogPath:a}}}function Zt(e){let{req:t,response:n,durationMs:i}=e;return n.ok?{kind:`request.finished`,requestId:t.meta?.requestId??r().requestId,command:t.command,status:`ok`,summary:`Finished ${t.command}`,details:{durationMs:i}}:{kind:`request.finished`,requestId:t.meta?.requestId??r().requestId,command:t.command,status:`error`,summary:`Failed ${t.command}: ${n.error.code}`,details:{durationMs:i,code:n.error.code,diagnosticId:n.error.diagnosticId,logPath:n.error.logPath}}}function Qt(e,t={}){let n=rn(t.cursor),r=an(t.limit);if(!g.existsSync(e))return{path:e,cursor:String(n),limit:r,events:[]};let i=$t(e,n,r),a=i.lines.flatMap(e=>{let t=on(e);return t?[t]:[]});return{path:e,cursor:String(n),limit:r,events:a,...i.nextCursor===void 0?{}:{nextCursor:String(i.nextCursor)}}}function $t(e,t,n){let r=g.openSync(e,`r`);try{let e=new de(`utf8`),i=Buffer.allocUnsafe(65536),a=en(t,n),o=``,s=0;do{s=g.readSync(r,i,0,i.length,null);let t=e.write(i.subarray(0,s));o=tn(`${o}${t}`,a)}while(s>0&&a.nextCursor===void 0);let c=`${o}${e.end()}`;return a.nextCursor===void 0&&c.length>0&&nn(c,a),{lines:a.lines,nextCursor:a.nextCursor}}finally{g.closeSync(r)}}function en(e,t){return{cursor:e,limit:t,lineIndex:0,lines:[]}}function tn(e,t){let n=0;for(let r=e.indexOf(`
|
|
3
|
+
`);r!==-1;r=e.indexOf(`
|
|
4
|
+
`,n))if(nn(e.slice(n,r),t),n=r+1,t.nextCursor!==void 0)return``;return e.slice(n)}function nn(e,t){let n=e.endsWith(`\r`)?e.slice(0,-1):e;if(n.trim().length!==0){if(t.lineIndex>=t.cursor+t.limit){t.nextCursor=t.cursor+t.limit;return}t.lineIndex>=t.cursor&&t.lines.push(n),t.lineIndex+=1}}function rn(e){if(e===void 0||e.trim()===``)return 0;let n=Number(e);if(Number.isInteger(n)&&n>=0)return n;throw new t(`INVALID_ARGS`,`events cursor must be a non-negative integer string.`)}function an(e){if(e===void 0||typeof e==`string`&&e.trim()===``)return 100;let n=typeof e==`string`?Number(e):e;if(Number.isInteger(n)&&n>=1&&n<=500)return n;throw new t(`INVALID_ARGS`,`events limit must be between 1 and 500.`)}function on(e){try{let t=sn(JSON.parse(e));return t?cn(t):void 0}catch{return}}function sn(e){if(p(e)&&e.version===1&&!(typeof e.ts!=`string`||typeof e.session!=`string`)&&ln(e.kind))return e}function cn(e){let t=p(e.details)?e.details:void 0;return{version:1,ts:e.ts,session:e.session,kind:e.kind,...typeof e.requestId==`string`?{requestId:e.requestId}:{},...typeof e.command==`string`?{command:e.command}:{},...un(e.status)?{status:e.status}:{},...typeof e.summary==`string`?{summary:e.summary}:{},...t?{details:t}:{}}}function ln(e){return e===`request.started`||e===`request.finished`||e===`action.recorded`}function un(e){return e===`ok`||e===`error`}const dn=60*6e4;var fn=class{sessions=new Map;runtimeHints=new Map;sessionsDir;scriptWriter;constructor(e){this.sessionsDir=e,this.scriptWriter=new nt(e)}get(e){return this.sessions.get(e)}set(e,t){this.sessions.set(e,t)}delete(e){return this.runtimeHints.delete(e),this.sessions.delete(e)}values(){return this.sessions.values()}toArray(){return Array.from(this.sessions.values())}getRuntimeHints(e){return this.runtimeHints.get(e)}setRuntimeHints(e,t){this.runtimeHints.set(e,t)}clearRuntimeHints(e){return this.runtimeHints.delete(e)}recordAction(e,t){let n=Ce(e,t);if(n){let t=this.resolveStoredSessionName(e);Yt(this.resolveEventLogPath(t),t,n)}}recordEvent(e,t){Gt(this.resolveEventLogPath(e),e,t)}readEvents(e,t={}){return Qt(this.resolveEventLogPath(e),t)}async flushEvents(e){await Kt(e?this.resolveEventLogPath(e):void 0)}writeSessionLog(e,t){let n=this.scriptWriter.write(e,t);return n.written&&i({level:`info`,phase:`session_script_written`,data:{session:e.name,path:n.path}}),n}finalizeRepairTeardown(e){this.recordRepairFinalizeCloseIfCommitting(e);let t=this.writeSessionLog(e,{force:e.saveScriptForce});e.saveScriptBoundary!==void 0&&e.saveScriptCommitted!==!0&&(!t.written&&t.error?this.writeRepairTombstone(e,dn,{code:String(t.error.code),message:t.error.message}):this.writeRepairTombstone(e))}recordRepairFinalizeCloseIfCommitting(e){e.saveScriptBoundary!==void 0&&e.saveScriptComplete===!0&&e.saveScriptCommitted!==!0&&this.recordAction(e,{command:`close`,positionals:[],flags:{},result:{session:e.name,...ne(`Closed: ${e.name}`)}})}writeRepairTombstone(e,t=dn,n){try{let r=this.resolveSessionDir(e.name);g.mkdirSync(r,{recursive:!0});let i={owner:e.name,reapedAt:Date.now(),expiresAt:Date.now()+t,...e.repairSourcePath?{sourcePath:e.repairSourcePath}:{},...n?{commitFailure:n}:{}};g.writeFileSync(this.repairTombstonePath(e.name),`${JSON.stringify(i)}\n`)}catch(t){i({level:`warn`,phase:`repair_tombstone_write_failed`,data:{session:e.name,error:t instanceof Error?t.message:String(t)}})}}readRepairTombstone(e){return pn(this.repairTombstonePath(e))}clearRepairTombstone(e){try{g.rmSync(this.repairTombstonePath(e),{force:!0})}catch{}}repairTombstonePath(e){return _.join(this.resolveSessionDir(e),`repair-tombstone.json`)}defaultTracePath(e){let t=y(e.name),n=new Date().toISOString().replace(/[:.]/g,`-`);return _.join(this.sessionsDir,`${t}-${n}.trace.log`)}resolveSessionDir(e){return _.join(this.sessionsDir,y(e))}resolveDaemonStateDir(){return _.dirname(this.sessionsDir)}ensureSessionDir(e){let t=this.resolveSessionDir(e);return g.mkdirSync(t,{recursive:!0}),t}resolveAppLogPath(e){return _.join(this.resolveSessionDir(e),`app.log`)}resolveAppLogPidPath(e){return _.join(this.resolveSessionDir(e),`app-log.pid`)}resolveEventLogPath(e){return Ut(this.resolveSessionDir(e))}static expandHome(e,t){return b(e,t)}resolveStoredSessionName(e){for(let[t,n]of this.sessions)if(n===e)return t;return e.name}};function pn(e){let t;try{t=g.readFileSync(e,`utf8`)}catch{return}let n;try{n=JSON.parse(t)}catch{return}if(!(typeof n?.expiresAt!=`number`||n.expiresAt<=Date.now()))return n}function mn(e){let t;try{t=g.readdirSync(e,{withFileTypes:!0})}catch{return}for(let n of t){if(!n.isDirectory())continue;let t=pn(_.join(e,n.name,`repair-tombstone.json`));if(t?.commitFailure)return{sessionName:n.name,tombstone:{...t,commitFailure:t.commitFailure}}}}function hn(e){return _.join(e,`runner.log`)}function gn(e,t){let n=y(t&&t.length>0?t:`unknown`);return _.join(e,`requests`,`${n}.ndjson`)}function _n(e,t={}){let n=vn(e,t);return{baseDir:n,infoPath:_.join(n,`daemon.json`),lockPath:_.join(n,`daemon.lock`),logPath:_.join(n,`daemon.log`),sessionsDir:_.join(n,`sessions`)}}function vn(e,t){let n=(e??``).trim();return n?d(n,{env:t.env}):yn(t)}function yn(e={}){let t=_.join(ie(`~`,{env:e.env}),`.agent-device`),n=e.projectRoot??u();return bn(n)?_.join(t,`dev`,xn(n)):t}function bn(e){return g.existsSync(_.join(e,`package.json`))&&g.existsSync(_.join(e,`src`,`daemon.ts`))}function xn(e){let t=Sn(e),n=_.basename(t).replaceAll(/[^a-zA-Z0-9._-]+/g,`-`),r=h.createHash(`sha1`).update(t).digest(`hex`).slice(0,12);return`${n||`agent-device`}-${r}`}function Sn(e){try{return g.realpathSync.native(e)}catch{return _.resolve(e)}}function Cn(e){let t=(e??``).trim().toLowerCase();return t===`http`?`http`:t===`dual`?`dual`:`socket`}function wn(e){let t=(e??``).trim().toLowerCase();return t===`auto`?`auto`:t===`socket`?`socket`:t===`http`?`http`:`auto`}function Tn(e){return(e??``).trim().toLowerCase()===`tenant`?`tenant`:`none`}function En(e){if(!e)return;let t=e.trim();if(t&&/^[a-zA-Z0-9._-]{1,128}$/.test(t))return t}const Dn=/(?:^|[^\w$.])(?:import|export)\s+(?:type\s+)?(?:[^'"`]*?\s+from\s+)?['"]([^'"]+)['"]/gm,On=/import\(\s*['"]([^'"]+)['"]\s*\)/gm,kn=[`.ts`,`.tsx`,`.js`,`.jsx`,`.mjs`,`.cjs`];function An(){let e=process.argv[1];return e?jn(e):`unknown`}function jn(e,t=u()){try{let n=_.resolve(t),r=[_.resolve(e)],i=new Set,a=[];for(;r.length>0;){let e=r.pop();if(!e||i.has(e))continue;i.add(e);let t=g.statSync(e);if(!t.isFile())continue;let o=_.relative(n,e)||e;a.push(`${o}:${t.size}:${Math.trunc(t.mtimeMs)}`);let s=g.readFileSync(e,`utf8`);for(let t of Mn(s)){let n=Pn(e,t);n&&r.push(n)}}let o=a.sort().join(`|`),s=h.createHash(`sha1`).update(o).digest(`hex`);return`graph:${a.length}:${s}`}catch{return`unknown`}}function Mn(e){let t=new Set;return Nn(e,Dn,t),Nn(e,On,t),[...t]}function Nn(e,t,n){t.lastIndex=0;let r=null;for(;(r=t.exec(e))!==null;){let e=r[1]?.trim();e?.startsWith(`.`)&&n.add(e)}}function Pn(e,t){let n=_.resolve(_.dirname(e),t),r=Y(n);if(r)return r;for(let e of kn){let t=Y(`${n}${e}`);if(t)return t}for(let e of kn){let t=Y(_.join(n,`index${e}`));if(t)return t}return null}function Y(e){try{return g.statSync(e).isFile()?e:null}catch{return null}}const Fn=[/(^|[/\s"'=])dist\/src\/daemon\.js($|[\s"'])/,/(^|[/\s"'=])dist\/src\/internal\/daemon\.js($|[\s"'])/,/(^|[/\s"'=])src\/daemon\.ts($|[\s"'])/];function In(e){let t=e.toLowerCase().replaceAll(`\\`,`/`);return t.includes(`agent-device`)?Fn.some(e=>e.test(t)):!1}function Ln(e,t){if(!le(e))return!1;if(t){let n=ue(e);if(!n||n!==t)return!1}let n=ce(e);return n?In(n):!1}function X(e,t){try{return process.kill(e,t),!0}catch(e){let t=e.code;if(t===`ESRCH`||t===`EPERM`)return!1;throw e}}async function Rn(e,t){Ln(e,t.expectedStartTime)&&X(e,`SIGTERM`)&&(await m(e,t.termTimeoutMs)||X(e,`SIGKILL`)&&await m(e,t.killTimeoutMs))}const zn=/^[A-Za-z0-9_@%+=:,./-]+$/;function Bn(e){return`'${e.replaceAll(`'`,`'\\''`)}'`}function Vn(e){return zn.test(e)?e:Bn(e)}function Hn(e,t){let n=[],r=e+t.toString(),i=r.indexOf(`
|
|
2
5
|
`);for(;i!==-1;){let e=r.slice(0,i).trim();r=r.slice(i+1),e&&n.push(e),i=r.indexOf(`
|
|
3
|
-
`)}return{lines:n,buffer:r}}function
|
|
6
|
+
`)}return{lines:n,buffer:r}}function Un(e){return e.meta?.requestProgress===`replay-test`||e.meta?.requestProgress===`command`}function Wn(e){return!!e&&typeof e==`object`&&e.type===`progress`&&!!e.event}function Gn(e){return!!e&&typeof e==`object`&&e.type===`response`&&!!e.response}function Kn(e){return`${JSON.stringify({type:`progress`,event:e})}\n`}function qn(e){return`${JSON.stringify({type:`response`,response:e})}\n`}function Jn(e){return`${JSON.stringify({type:`response`,response:e})}\n`}function Yn(e,t={}){return{ok:!0,service:e,version:re(),rpcProtocolVersion:2,...t.upstream===void 0?{}:{upstream:t.upstream}}}function Z(e){return{...typeof e.path==`string`?{path:e.path}:{},...typeof e.width==`number`?{width:e.width}:{},...typeof e.height==`number`?{height:e.height}:{},...typeof e.logicalWidth==`number`?{logicalWidth:e.logicalWidth}:{},...typeof e.logicalHeight==`number`?{logicalHeight:e.logicalHeight}:{},...typeof e.pixelDensity==`number`?{pixelDensity:e.pixelDensity}:{},...e.overlayRefs?{overlayRefs:e.overlayRefs}:{}}}function Xn(e){if(p(e))return Z({path:typeof e.path==`string`?e.path:void 0,width:typeof e.width==`number`?e.width:void 0,height:typeof e.height==`number`?e.height:void 0,logicalWidth:typeof e.logicalWidth==`number`?e.logicalWidth:void 0,logicalHeight:typeof e.logicalHeight==`number`?e.logicalHeight:void 0,pixelDensity:typeof e.pixelDensity==`number`?e.pixelDensity:void 0,overlayRefs:Array.isArray(e.overlayRefs)?e.overlayRefs.filter(er).flatMap(e=>{let t=Zn(e);return t?[t]:[]}):void 0})}function Zn(e){if(typeof e.ref!=`string`||e.ref.length===0)return;let t=Qn(e);if(t)return{ref:e.ref,...$n(e),...t}}function Qn(e){let t=f(e.rect);if(!t)return;let n=f(e.overlayRect);if(!n)return;let r=se(e.center);return r?{rect:t,overlayRect:n,center:r}:void 0}function $n(e){return typeof e.label==`string`&&e.label.length>0?{label:e.label}:{}}function er(e){return p(e)}const Q=1500;function tr(e,t){e&&(e.snapshotDiagnostics??={samples:[]}).samples.push({...t,durationMs:Math.max(0,Math.round(t.durationMs))})}function nr(e){let t=e?.snapshotDiagnostics?.samples;if(!(!t||t.length===0))return rr(t)}function rr(e){if(e.length===0)return;let t=or(e);return{stats:t,...t.p95Ms>=Q?{warning:$(t)}:{}}}function ir(e){let t=e.flatMap(e=>mr(e?.stats));if(t.length===0)return;let n=or(t);return{stats:n,...n.p95Ms>=Q?{warning:$(n)}:{}}}function ar(e){if(!p(e))return;let t=ur(e.stats);if(!t)return;let n=typeof e.warning==`string`?e.warning:void 0;return{stats:t,...n?{warning:n}:{}}}function or(e){let t=e.map(e=>e.durationMs).sort((e,t)=>e-t);return{count:t.length,p50Ms:sr(t,50),p95Ms:sr(t,95),maxMs:t[t.length-1]??0,slowThresholdMs:Q,...cr(e),...lr(e)}}function sr(e,t){if(e.length===0)return 0;let n=Math.max(0,Math.ceil(t/100*e.length)-1);return e[Math.min(n,e.length-1)]??0}function cr(e){let t=e.map(e=>e.platform).filter(e=>!!e);return new Set(t).size===1?{platform:t[0]}:{}}function lr(e){let t={};for(let n of e)n.backend&&(t[n.backend]=(t[n.backend]??0)+1);return Object.keys(t).length>0?{backends:t}:{}}function $(e){return`Warning: ${e.platform?`${e.platform} `:``}snapshots are slow in this run: p95 ${e.p95Ms}ms over ${e.count} captures. Possible causes: device load, app or dev server stuck, helper fallback, or stale daemon.`}function ur(e){if(!p(e))return;let t=dr(e);if(t)return{...t,...pr(e)}}function dr(e){let t={count:e.count,p50Ms:e.p50Ms,p95Ms:e.p95Ms,maxMs:e.maxMs,slowThresholdMs:e.slowThresholdMs};if(!Object.values(t).some(e=>typeof e!=`number`))return t}function fr(e){let t=Object.entries(e).filter(e=>typeof e[1]==`number`);return t.length>0?Object.fromEntries(t):void 0}function pr(e){let t=typeof e.platform==`string`?e.platform:void 0,n=p(e.backends)?fr(e.backends):void 0;return{...t?{platform:t}:{},...n?{backends:n}:{}}}function mr(e){if(!e||e.count<=0)return[];let t=e.platform;return e.count===1?[{durationMs:e.maxMs,platform:t}]:e.count===2?[{durationMs:e.p50Ms,platform:t},{durationMs:e.maxMs,platform:t}]:[...Array.from({length:e.count-3},()=>({durationMs:e.p50Ms,platform:t})),{durationMs:e.p50Ms,platform:t},{durationMs:e.p95Ms,platform:t},{durationMs:e.maxMs,platform:t}]}export{ve as $,gn as A,T as B,En as C,Tn as D,wn as E,V as F,Te as G,We as H,Ke as I,Se as J,b as K,Le as L,Zt as M,Xt as N,fn as O,Wt as P,be as Q,D as R,An as S,Cn as T,S as U,P as V,x as W,_e as X,xe as Y,ye as Z,Vn as _,rr as a,me as at,X as b,Yn as c,Kn as d,v as et,qn as f,Bn as g,Hn as h,nr as i,ge as it,hn as j,mn as k,Wn as l,Un as m,ar as n,he as nt,Z as o,Jn as p,y as q,tr as r,pe as rt,Xn as s,ir as t,fe as tt,Gn as u,Ln as v,_n as w,jn as x,Rn as y,w as z};
|
package/dist/src/snapshot.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as e}from"./rolldown-runtime.js";import{
|
|
1
|
+
import{t as e}from"./rolldown-runtime.js";import{_ as t}from"./sdk-contracts.js";import{j as n}from"./sdk-android-adb.js";import{n as r,t as i}from"./tool-provider2.js";import a from"node:fs";import o from"node:path";import{fileURLToPath as s}from"node:url";const c={"push button":`Button`,"toggle button":`Button`,"push button menu":`Button`,label:`StaticText`,static:`StaticText`,caption:`StaticText`,text:`TextField`,entry:`TextField`,"password text":`TextField`,"spin button":`TextField`,terminal:`TextArea`,"document text":`TextArea`,paragraph:`TextArea`,frame:`Window`,window:`Window`,dialog:`Dialog`,alert:`Alert`,"file chooser":`Dialog`,"color chooser":`Dialog`,"font chooser":`Dialog`,panel:`Group`,filler:`Group`,section:`Group`,form:`Group`,grouping:`Group`,"layered pane":`Group`,"glass pane":`Group`,"root pane":`Group`,"option pane":`Group`,"internal frame":`Group`,"desktop frame":`Group`,"block quote":`Group`,article:`Group`,comment:`Group`,landmark:`Group`,log:`Group`,marquee:`Group`,math:`Group`,notification:`Group`,"content deletion":`Group`,"content insertion":`Group`,mark:`Group`,suggestion:`Group`,"scroll pane":`ScrollArea`,"scroll bar":`ScrollBar`,"menu bar":`MenuBar`,menu:`Menu`,"popup menu":`Menu`,"menu item":`MenuItem`,"check menu item":`MenuItem`,"radio menu item":`MenuItem`,"tearoff menu item":`MenuItem`,"check box":`CheckBox`,"radio button":`RadioButton`,switch:`Switch`,"combo box":`ComboBox`,"page tab":`Tab`,"page tab list":`TabList`,table:`Table`,"tree table":`Table`,"table cell":`Cell`,"table row":`Row`,"table column header":`Cell`,"table row header":`Cell`,"column header":`Cell`,"row header":`Cell`,list:`List`,"list item":`ListItem`,"list box":`List`,tree:`Tree`,"tree item":`TreeItem`,"description list":`List`,"description term":`ListItem`,"description value":`ListItem`,"tool bar":`Toolbar`,"status bar":`StatusBar`,"info bar":`StatusBar`,slider:`Slider`,"progress bar":`ProgressBar`,"level bar":`ProgressBar`,image:`Image`,icon:`Image`,animation:`Image`,canvas:`Image`,"drawing area":`Image`,video:`Video`,audio:`Audio`,link:`Link`,hyperlink:`Link`,separator:`Separator`,application:`Application`,"tool tip":`Tooltip`,timer:`Timer`,heading:`Heading`,footnote:`Footnote`,"title bar":`TitleBar`,"date editor":`DateEditor`,rating:`Slider`};function l(e){let t=e.toLowerCase().trim();return c[t]||t.split(/[\s_-]+/).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(``)}const u=`atspi-dump.py`;let d=null;function f(){if(d)return d;let e=o.dirname(s(import.meta.url));for(let t=0;t<6;t++){let t=o.join(e,`linux`,u);if(a.existsSync(t))return d=t,t;e=o.dirname(e)}throw new t(`TOOL_MISSING`,`Cannot find ${u}. Ensure the agent-device package is installed correctly.`)}async function p(e,n={}){let a=i().accessibility;if(a)return await a.captureTree(e,n);if(process.platform!==`linux`)throw new t(`UNSUPPORTED_PLATFORM`,`AT-SPI2 bridge is only available on Linux`);if(!await i().whichCommand(`python3`))throw new t(`TOOL_MISSING`,`python3 is required for AT-SPI2 accessibility snapshots on Linux.`);let o=n.maxNodes??1500,s=n.maxDepth??12,c=n.maxApps??24,u=await r(`python3`,[f(),`--surface`,e,`--max-nodes`,String(o),`--max-depth`,String(s),`--max-apps`,String(c)],{allowFailure:!0,timeoutMs:3e4});if(u.exitCode!==0){let e=u.stderr.trim();throw e.includes(`No module named`)||e.includes(`gi.require_version`)?new t(`TOOL_MISSING`,`AT-SPI2 Python bindings not found. Install python3-gi and gir1.2-atspi-2.0.`,{cause:e}):new t(`COMMAND_FAILED`,`AT-SPI2 snapshot failed (exit ${u.exitCode}): ${e||u.stdout}`)}let d;try{d=JSON.parse(u.stdout)}catch{throw new t(`COMMAND_FAILED`,`AT-SPI2 snapshot returned invalid JSON: ${u.stdout.slice(0,200)}`)}if(d.error)throw new t(`COMMAND_FAILED`,`AT-SPI2: ${d.error}`);return{nodes:(d.nodes??[]).map(e=>({index:e.index,type:l(e.role),role:e.role,label:e.label??void 0,value:e.value??void 0,rect:e.rect??void 0,enabled:e.enabled??void 0,selected:e.selected??void 0,hittable:e.hittable??void 0,depth:e.depth,parentIndex:e.parentIndex??void 0,pid:e.pid??void 0,appName:e.appName??void 0,windowTitle:e.windowTitle??void 0})),truncated:d.truncated,surface:e}}var m=e({readLinuxTextAtPoint:()=>_,snapshotLinux:()=>g});function h(e){return e===`desktop`?`desktop`:e===`frontmost-app`||e===`app`?`frontmost-app`:(e===`menubar`&&n({level:`warn`,phase:`linux_snapshot`,data:{message:`menubar surface is not supported on Linux, falling back to desktop`}}),`desktop`)}async function g(e){let t=await p(h(e));return{nodes:t.nodes,truncated:t.truncated}}async function _(e,t,n){let{nodes:r}=await g(n),i=r.filter(n=>{let r=n.rect;return r?e>=r.x&&t>=r.y&&e<=r.x+r.width&&t<=r.y+r.height:!1}).sort((e,t)=>{let n=e.depth??0,r=t.depth??0;return n===r?v(e.rect)-v(t.rect):r-n});for(let e of i){let t=y(e);if(t.trim())return t}return``}function v(e){return(e?.width??0)*(e?.height??0)}function y(e){for(let t of[e.value,e.label,e.identifier])if(typeof t==`string`&&t.length>0)return t;return``}export{m as n,g as t};
|
package/dist/src/snapshot2.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
import{B as e,F as t,O as n,b as r,m as i,p as a}from"./sdk-contracts.js";import{F as o,j as s}from"./sdk-android-adb.js";import{E as c}from"./sdk-batch.js";import{Et as l,Ot as u,hn as d,jt as f,kt as p,wn as m}from"./tv-remote.js";import{i as h}from"./snapshot-diagnostics.js";import{t as g}from"./timeouts.js";import{t as _}from"./runtime.js";import{i as v}from"./runner-client.js";import{i as ee}from"./helper.js";import{$t as y,At as te,Ct as ne,Dt as re,Ft as ie,Gt as b,Ot as ae,Pt as x,tn as S,zt as C}from"./internal/daemon.js";import{l as oe,n as se}from"./input-actions.js";import{t as ce}from"./apple-runner-options.js";import{C as w,S as T,b as le,i as ue,o as de,x as E}from"./selector-runtime.js";import{promises as D}from"node:fs";import fe from"node:os";import O from"node:path";const k=new Set([`com.android.permissioncontroller`,`com.google.android.permissioncontroller`,`com.google.android.packageinstaller`,`com.android.packageinstaller`]),A=new Set([`android`,`com.android.systemui`]),j=/^android:id\/(?:alertTitle|message|button[123]|parentPanel|buttonPanel|contentPanel)$/i,M=/^android:id\/button[123]$/i,N=/(?:^|:)id\/permission_/i,P=/\b(?:is(?:n't| not) responding|keeps stopping|has stopped|close app|app info)\b/i,F=/^(?:ok|allow|allow all|while using the app|only this time|yes|continue|save|confirm|turn on|open settings)$/i,I=/^(?:cancel|deny|don.t allow|don’t allow|not now|no|dismiss|close|close app|later|skip)$/i;function L(e){let t=z(e),n=t.nodes;if(n.length===0)return null;let r=he(n),i=n.filter(e=>K(e)&&!G(e)),a=ve(i),o=ye(i,a),s=Se(n);return{alert:{...a?{title:a}:{},...o?{message:o}:{},buttons:r.map(e=>e.label),platform:`android`,source:t.source,...s?{packageName:s}:{}},buttons:r}}function R(e,t){let n=t===`accept`?`accept`:`dismiss`;return e.find(e=>e.role===n)||(t===`dismiss`?e.find(e=>e.role===`neutral`)??null:e.length===1?e[0]??null:null)}function z(e){let t=e.filter(e=>be(e));if(t.length)return{nodes:t,source:`permission`};let n=me(e);return n.length?{nodes:n,source:`system-dialog`}:{nodes:B(e),source:`native-dialog`}}function B(e){let t=e.filter(e=>V(e.type??``)),n=e.filter(e=>j.test(e.identifier??``)),r=t.length?[...t,...n]:pe(n);if(r.length===0)return[];let i=H(e,r);return i===void 0?r:W(e,i)}function V(e){return/(?:^|[.$])[^.]*Dialog$/i.test(e)}function pe(e){let t=e.some(e=>M.test(e.identifier??``)),n=e.some(e=>!M.test(e.identifier??``));return t&&n?e:[]}function me(e){let t=e.filter(e=>xe(e));if(t.length===0)return[];let n=H(e,t);return n===void 0?t:W(e,n).filter(e=>e.bundleId&&A.has(e.bundleId))}function he(e){let t=new Set,r=[];for(let i of e){let e=K(i);if(!e||!i.rect||!G(i))continue;let a=e.trim().toLowerCase();if(!a||t.has(a))continue;t.add(a);let o=n(i.rect);r.push({label:e,x:o.x,y:o.y,role:ge(i,e)})}return r}function ge(e,t){return _e(e.identifier??``)||(F.test(t.trim())?`accept`:I.test(t.trim())?`dismiss`:`neutral`)}function _e(e){return/(?:^|:)id\/button1$/i.test(e)?`accept`:/(?:^|:)id\/button2$/i.test(e)?`dismiss`:/(?:^|:)id\/button3$/i.test(e)?`neutral`:/(?:^|:)id\/permission_allow/i.test(e)?`accept`:/(?:^|:)id\/permission_deny/i.test(e)?`dismiss`:null}function ve(e){return K(e.find(e=>/(?:^|:)id\/(?:alertTitle|permission_message)$/i.test(e.identifier??``)))||K(e[0])}function ye(e,t){let n=e.map(e=>K(e)).filter(e=>e&&e!==t);return n.length?[...new Set(n)].join(`
|
|
2
|
-
`):void 0}function H(e,t){let n=t[0];if(!n)return;let r=U(e,n.index);for(let n of t.slice(1)){let t=new Set(U(e,n.index));for(let e=r.length-1;e>=0;--e)t.has(r[e])||r.splice(e,1)}return r[r.length-1]}function U(e,t){let n=new Map(e.map(e=>[e.index,e])),r=[],i=n.get(t);for(;i;)r.push(i.index),i=i.parentIndex===void 0?void 0:n.get(i.parentIndex);return r.reverse()}function W(e,t){let n=new Map;for(let t of e){if(t.parentIndex===void 0)continue;let e=n.get(t.parentIndex)??[];e.push(t),n.set(t.parentIndex,e)}let r=new Set([t]),i=[t];for(let e of i)for(let t of n.get(e)??[])r.has(t.index)||(r.add(t.index),i.push(t.index));return e.filter(e=>r.has(e.index))}function be(e){let t=e.bundleId??``;return k.has(t)||N.test(e.identifier??``)}function xe(e){let t=e.bundleId??``;return A.has(t)&&P.test(K(e))}function G(e){let t=e.type??``,n=e.identifier??``;return!!(e.hittable||/\bbutton\b/i.test(t)||M.test(n)||/(?:^|:)id\/permission_(?:allow|deny)/i.test(n))}function K(e){return e?[e.label,e.value].filter(e=>typeof e==`string`&&e.trim().length>0)[0]?.trim()??``:``}function Se(e){return e.find(e=>e.bundleId)?.bundleId}async function Ce(e,t,n={}){return t===`wait`?await we(e,n.timeoutMs??1e4):t===`get`?Ee((await J(e))?.alert??null):await Te(e,t)}async function we(e,n){let r=Date.now(),i=await q(e,n);if(!i)throw new t(`COMMAND_FAILED`,`alert wait timed out`);return{kind:`alertWait`,platform:`android`,action:`wait`,alert:i.alert,waitedMs:Date.now()-r,...m(`Alert visible`)}}async function Te(e,n){let r=await q(e,f);if(!r)throw new t(`COMMAND_FAILED`,`alert not found`,{hint:`If a sheet is visible in snapshot but alert reports no alert, it is likely app-owned UI. Use snapshot -i and press the visible label/ref.`});let i=R(r.buttons,n);if(i)return await oe(e,i.x,i.y),Y(n,r.alert,i.label);if(n===`dismiss`)return await se(e),Y(n,r.alert,`Back`);throw new t(`COMMAND_FAILED`,`alert accept found an alert but no accept button`,{alert:r.alert,hint:`Inspect alert get --json for visible buttons, then use press by visible label/ref if needed.`})}async function q(e,t){let n=Date.now();for(;Date.now()-n<t;){let t=await J(e);if(t)return t;await g(300)}return null}async function J(e){return L((await o(`snapshot_capture`,async()=>await re(e,{helperWaitForIdleTimeoutMs:0,includeHiddenContentHints:!1}),{backend:`android`,purpose:`alert`})).nodes)}function Ee(e){return{kind:`alertStatus`,platform:`android`,action:`get`,alert:e,...m(e?`Alert visible`:`No alert visible`)}}function Y(e,t,n){return{kind:`alertHandled`,platform:`android`,action:e,handled:!0,alert:t,button:n,...m(`Alert ${e}ed`)}}async function De(e){let{req:t,logPath:n,session:r,device:a}=e,o=Oe(t.positionals?.[0]),s=r?r.surface===`frontmost-app`?{surface:`frontmost-app`}:{bundleId:r.appBundleId,surface:r.surface}:{},l=S(`alert`,a);if(l)return l;if(a.platform===`android`)return Z(e,await Ce(a,o,{timeoutMs:c(t.positionals?.[1])??1e4}));if(i(a))return await X(e,o,async e=>await ee(e,s));let u=ce({req:t,logPath:n,traceLogPath:r?.trace?.outPath});return await X(e,o,async e=>await v(a,{command:`alert`,action:e,appBundleId:r?.appBundleId},u))}async function X(e,t,n){if(t===`wait`)return await ke(e,n);let r=t===`accept`||t===`dismiss`?t:`get`;return r===`accept`||r===`dismiss`?await Ae(e,r,n):Z(e,await n(`get`))}function Oe(e){return e===`accept`||e===`dismiss`||e===`wait`?e:`get`}async function ke(e,t){let n=c(e.req.positionals?.[1])??1e4,r=Date.now();for(;Date.now()-r<n;){try{return Z(e,await t(`get`))}catch{}await g(300)}return y(`COMMAND_FAILED`,`alert wait timed out`)}async function Ae(e,t,n){let r=Date.now(),i;for(;Date.now()-r<f;){try{return Z(e,await n(t))}catch(e){i=e;let t=String(e?.message??``).toLowerCase();if(!t.includes(`alert not found`)&&!t.includes(`no alert`))break}await g(300)}throw je(i)}function Z(e,t){let n=t;return E(e.sessionStore,e.session,e.req,n),{ok:!0,data:n}}function je(e){return!(e instanceof t)||!Me(e)?e:new t(e.code,e.message,{...e.details??{},hint:`If the permission sheet is visible in snapshot or screenshot but alert reports no alert, take a scoped snapshot around the visible button label and use press @ref.`})}function Me(e){let t=String(e?.message??``).toLowerCase();return t.includes(`alert not found`)||t.includes(`no alert`)}function Ne(e){let t=e.positionals?.[0]?.toLowerCase(),n=e.positionals?.[1]?.toLowerCase(),r=e.positionals?.[2]?.toLowerCase();return t===`clear-app-state`?{ok:!0,parsed:{setting:t,state:`clear`,appBundleId:n===`clear`?e.positionals?.[2]:e.positionals?.[1]}}:!t||!n||t===`permission`&&!r||t===`location`&&n===`set`&&(!e.positionals?.[2]||!e.positionals?.[3])?y(`INVALID_ARGS`,l):{ok:!0,parsed:{setting:t,state:n,permissionTarget:r,latitude:e.positionals?.[2],longitude:e.positionals?.[3]}}}async function Pe(e){let{req:t,logPath:n,sessionStore:r,session:a,device:o,parsed:s}=e,{setting:c,state:l,appBundleId:d,permissionTarget:f,latitude:m,longitude:h}=s,g=S(`settings`,o);if(g)return g;if(i(o)&&!p(c))return y(`INVALID_ARGS`,u(c));let _=d??a?.appBundleId;if(c===`clear-app-state`&&!_)return y(`INVALID_ARGS`,`settings clear-app-state requires an app id when no app is bound to the session`);let v=await b(o,`settings`,c===`clear-app-state`?[c,l,_??``]:c===`permission`?[c,l,f??``,t.positionals?.[3]??``,_??``]:c===`location`&&l===`set`?[c,l,m??``,h??``,_??``]:[c,l,_??``],t.flags?.out,{...C(n,t.flags,_,a?.trace?.outPath)});return E(r,a,t,v??{setting:c,state:l}),{ok:!0,data:v??{setting:c,state:l}}}async function Fe(t){if(t.command!==`snapshot`||t.device.platform!==`android`)return;let n=e(t.error);if(Be(n))return{ok:!1,error:{...n,details:{...n.details??{},androidSnapshotTimeoutScreenshot:await Ie(t)}}}}async function Ie(t){try{let e=await D.mkdtemp(O.join(fe.tmpdir(),`agent-device-android-snapshot-timeout-`)),n=O.join(e,`snapshot-timeout-overlay-refs.png`),r=Re(await b(t.device,`screenshot`,[n],void 0,{...C(t.logPath,{screenshotNoStabilize:!0},t.session?.appBundleId,t.session?.trace?.outPath),surface:t.session?.surface}),n);await D.access(r);let i=await Le(r,t.session);return s({level:`warn`,phase:`android_snapshot_timeout_screenshot_captured`,data:{path:r,overlayRefCount:`overlayRefCount`in i?i.overlayRefCount:void 0,overlayRefsAnnotated:`overlayRefsAnnotated`in i?i.overlayRefsAnnotated:void 0}}),i}catch(t){let n=e(t);return s({level:`warn`,phase:`android_snapshot_timeout_screenshot_failed`,data:{error:n.message}}),{captureFailed:!0,error:n.message}}}async function Le(t,n){if(!n?.snapshot)return{path:t,overlayRefsRequested:!0,overlayRefsAnnotated:!1,overlayRefSource:`unavailable`,overlayRefCount:0};try{let e=await ne({screenshotPath:t,snapshot:n.snapshot});return{path:t,overlayRefsRequested:!0,overlayRefsAnnotated:e.length>0,overlayRefCount:e.length,overlayRefSource:`session-snapshot`,overlayRefs:e}}catch(n){let r=e(n);return s({level:`warn`,phase:`android_snapshot_timeout_screenshot_overlay_failed`,data:{path:t,error:r.message}}),{path:t,overlayRefsRequested:!0,overlayRefsAnnotated:!1,overlayRefSource:`session-snapshot`,overlayRefCount:0,overlayAnnotationError:r.message}}}function Re(e,t){return ze(e)?e.path:t}function ze(e){return typeof e==`object`&&!!e&&`path`in e&&typeof e.path==`string`}function Be(e){return e.code===`COMMAND_FAILED`?Ve(e)||He(e.details?.helper)||Ue(e.details):!1}function Ve(e){let t=`${e.message}\n${e.hint??``}`;return/Android UI hierarchy dump timed out/i.test(t)||/Stock UIAutomator fallback was skipped/i.test(t)?!0:/Android accessibility snapshots can be blocked/i.test(t)}function He(e){if(!e||typeof e!=`object`)return!1;let t=e,n=String(t.errorType??``),r=String(t.message??``);return/TimeoutException/i.test(n)||/timed out/i.test(r)}function Ue(e){if(!e)return!1;let t=e?.timeoutMs,n=e?.cmd,r=We(e?.args);return typeof t==`number`&&n===`adb`&&r.includes(`uiautomator`)&&r.includes(`dump`)}function We(e){return Array.isArray(e)?e.map(String):typeof e==`string`?e.split(/\s+/):[]}async function Ge(e){return await Q({...e,command:`snapshot`,unsupportedMessage:`snapshot is not supported on this device`,execute:async({runtime:t,sessionName:n,req:r,snapshotScope:i})=>{let a=await t.capture.snapshot({session:n,interactiveOnly:r.flags?.snapshotInteractiveOnly,depth:r.flags?.snapshotDepth,scope:i,raw:r.flags?.snapshotRaw,forceFull:r.flags?.snapshotForceFull}),o=e.sessionStore.get(n)?.snapshotGeneration;return{data:o===void 0?a:{...a,refsGeneration:o},record:{kind:`snapshot`,nodes:a.nodes.length,truncated:a.truncated}}}})}async function Ke(e){return await Q({...e,command:`diff`,unsupportedMessage:`diff is not supported on this device`,execute:async({runtime:e,sessionName:t,req:n,snapshotScope:r})=>{let i=await e.capture.diffSnapshot({session:t,interactiveOnly:n.flags?.snapshotInteractiveOnly,depth:n.flags?.snapshotDepth,scope:r,raw:n.flags?.snapshotRaw});return{data:i,record:{kind:`diff`,mode:`snapshot`,baselineInitialized:i.baselineInitialized,summary:i.summary}}}})}async function Q(e){let{req:t,sessionName:n,logPath:r,sessionStore:i}=e,{session:a,device:o}=await T(i,n,t.flags),s=S(e.command,o,{message:e.unsupportedMessage});if(s)return s;let c=ie(t.flags?.snapshotScope,a);return c.ok?qe(e.command,a,o)||await w(a,o,async()=>{let s=Je({req:t,sessionName:n,logPath:r,sessionStore:i,session:a,device:o,snapshotScope:c.scope}),l;try{l=await e.execute({runtime:s,sessionName:n,req:t,snapshotScope:c.scope})}catch(t){let n=await Fe({error:t,command:e.command,logPath:r,session:a,device:o});if(!n)throw t;return n}return $e({req:t,sessionName:n,sessionStore:i,result:l.record}),{ok:!0,data:l.data}}):c}function qe(e,t,n){return!a(n)||t?.appBundleId?null:y(`SESSION_NOT_FOUND`,`iOS ${e} requires an active app session on the target device. Run open first (for example: open --session ${t?.name??`sim`} --platform ios --device "<name>" <app>).`)}function Je(e){let{req:t,sessionName:n,logPath:r,sessionStore:i,session:a,device:o,snapshotScope:s}=e;return _({backend:Qe({req:t,logPath:r,session:a,device:o,snapshotScope:s}),...de(`snapshot`),sessions:ae({sessionName:n,getSession:()=>i.get(n),recordOptions:{includeSnapshot:!0},setRecord:e=>{let r=et(e),a=i.get(n);i.set(n,$({current:a,sessionName:n,device:o,record:r,refScopedSnapshot:Ye(t),issuesRefsToClient:t.command===`snapshot`}))}})})}function $(e){let{current:t,sessionName:n,device:r,record:i,refScopedSnapshot:a}=e,o=Xe(t,i,a),s=le({session:t,sessionName:n,device:r,snapshot:o?t.snapshot:i.snapshot,appBundleId:i.appBundleId});return s.snapshotScopeSource=Ze({current:t,keepCurrentSnapshot:o,refScopedSnapshot:a}),s.snapshotRefsStale=o?t?.snapshotRefsStale:!e.issuesRefsToClient,s.snapshotGeneration=o?t?.snapshotGeneration:te(t?.snapshotGeneration),i.appName&&(s.appName=i.appName),s}function Ye(e){return e.flags?.snapshotScope?.trim().startsWith(`@`)===!0}function Xe(e,t,n){return n&&t.snapshot?.nodes.length===0&&e?.snapshot!==void 0}function Ze(e){let{current:t,keepCurrentSnapshot:n,refScopedSnapshot:r}=e;if(r)return n?t?.snapshotScopeSource:t?.snapshotScopeSource??t?.snapshot}function Qe(e){let{req:t,logPath:n,session:i,device:a,snapshotScope:o}=e;return{platform:r(a),captureSnapshot:async(e,r)=>{let s=await x({device:a,session:i,flags:t.flags,outPath:r?.outPath??t.flags?.out,logPath:n,snapshotScope:o}),c=h(i);return{snapshot:s.snapshot,...d(s),...c?{snapshotDiagnostics:c}:{},appName:i?.appBundleId?i.appName??i.appBundleId:void 0,appBundleId:i?.appBundleId}}}}function $e(e){let t=e.sessionStore.get(e.sessionName);t&&e.sessionStore.recordAction(t,{command:e.req.command,positionals:e.req.positionals??[],flags:e.req.flags??{},result:tt(e.result)})}function et(e){if(!e.snapshot)throw new t(`UNKNOWN`,`snapshot runtime did not produce session state`);return e}function tt(e){return e.kind===`snapshot`?{nodes:e.nodes,truncated:e.truncated}:{mode:e.mode,baselineInitialized:e.baselineInitialized,summary:e.summary}}const nt={snapshot:async({req:e,sessionName:t,logPath:n,sessionStore:r})=>await Ge({req:e,sessionName:t,logPath:n,sessionStore:r}),diff:async({req:e,sessionName:t,logPath:n,sessionStore:r})=>e.positionals?.[0]===`snapshot`?await Ke({req:e,sessionName:t,logPath:n,sessionStore:r}):y(`INVALID_ARGS`,`diff currently supports only: diff snapshot`),wait:async({req:e,sessionName:t,logPath:n,sessionStore:r})=>await ue({req:e,sessionName:t,logPath:n,sessionStore:r}),alert:async({req:e,sessionName:t,logPath:n,sessionStore:r})=>{let{session:i,device:a}=await T(r,t,e.flags);return await w(i,a,async()=>await De({req:e,logPath:n,sessionStore:r,session:i,device:a}))},settings:async({req:e,sessionName:t,logPath:n,sessionStore:r})=>{let i=Ne(e);if(!i.ok)return i;let{session:a,device:o}=await T(r,t,e.flags);return await w(a,o,async()=>await Pe({req:e,logPath:n,sessionStore:r,session:a,device:o,parsed:i.parsed}))}};async function rt(e){let t=e.req.command,n=nt[t];return n?await n(e):null}export{rt as handleSnapshotCommands};
|
|
1
|
+
import{S as e,_ as t}from"./sdk-contracts.js";import{F as n,j as r}from"./sdk-android-adb.js";import{x as i}from"./sdk-batch.js";import{Gt as a,Ht as o,Jt as s,Xt as c,Zt as l,qn as u,qt as d}from"./tv-remote.js";import{G as f,i as p}from"./snapshot-diagnostics.js";import{c as m,m as h,s as g}from"./sdk-device.js";import{t as _}from"./timeouts.js";import{t as v}from"./runtime.js";import{l as y,n as b,s as x,t as S}from"./context.js";import{i as C}from"./helper.js";import{a as w}from"./runner-client.js";import{$t as T,Ft as E,Jt as D,Kt as O,Nt as k,Pt as A,Zt as j,kt as ee,nn as te,rn as ne,u as re,vn as ie}from"./internal/daemon.js";import{l as ae,n as M}from"./input-actions.js";import{C as N,S as P,b as F,i as I,o as L,x as R}from"./selector-runtime.js";import{promises as z}from"node:fs";import B from"node:os";import V from"node:path";async function H(e,t,n={}){return t===`wait`?await U(e,n.timeoutMs??1e4):t===`get`?q((await K(e))?.alert??null):await W(e,t)}async function U(e,n){let r=Date.now(),i=await G(e,n);if(!i)throw new t(`COMMAND_FAILED`,`alert wait timed out`);return{kind:`alertWait`,platform:`android`,action:`wait`,alert:i.alert,waitedMs:Date.now()-r,...u(`Alert visible`)}}async function W(e,n){let r=await G(e,c);if(!r)throw new t(`COMMAND_FAILED`,`alert not found`,{hint:`If a sheet is visible in snapshot but alert reports no alert, it is likely app-owned UI. Use snapshot -i and press the visible label/ref.`});let i=A(r.buttons,n);if(i)return await ae(e,i.x,i.y),J(n,r.alert,i.label);if(n===`dismiss`)return await M(e),J(n,r.alert,`Back`);throw new t(`COMMAND_FAILED`,`alert accept found an alert but no accept button`,{alert:r.alert,hint:`Inspect alert get --json for visible buttons, then use press by visible label/ref if needed.`})}async function G(e,t){let n=Date.now();for(;Date.now()-n<t;){let t=await K(e);if(t)return t;await _(300)}return null}async function K(e){return E((await n(`snapshot_capture`,async()=>await k(e,{helperWaitForIdleTimeoutMs:0,includeHiddenContentHints:!1}),{backend:`android`,purpose:`alert`})).nodes)}function q(e){return{kind:`alertStatus`,platform:`android`,action:`get`,alert:e,...u(e?`Alert visible`:`No alert visible`)}}function J(e,t,n){return{kind:`alertHandled`,platform:`android`,action:e,handled:!0,alert:t,button:n,...u(`Alert ${e}ed`)}}async function oe(e){let{req:t,logPath:n,session:r,device:a}=e,o=se(t.positionals?.[0]),s=r?r.surface===`frontmost-app`?{surface:`frontmost-app`}:{bundleId:r.appBundleId,surface:r.surface}:{},c=y(`alert`,a);if(c)return c;if(r&&ie(t)===`may-invalidate`&&T(r),a.platform===`android`)return Z(e,await H(a,o,{timeoutMs:i(t.positionals?.[1])??1e4}));if(m(a))return await Y(e,o,async e=>await C(e,s));let l=re({req:t,logPath:n,traceLogPath:r?.trace?.outPath});return await Y(e,o,async(e,t)=>await w(a,{command:`alert`,action:e,appBundleId:r?.appBundleId,timeoutMs:t},l))}async function Y(e,t,n){if(t===`wait`)return await ce(e,n);let r=t===`accept`||t===`dismiss`?t:`get`;return r===`accept`||r===`dismiss`?await le(e,r,n):Z(e,await n(`get`,l))}function se(e){return e===`accept`||e===`dismiss`||e===`wait`?e:`get`}async function ce(e,t){let n=i(e.req.positionals?.[1])??1e4,r=Date.now(),a=!0;for(;Date.now()-r<n;){try{let i=a?n:X(r,n);return a=!1,Z(e,await t(`get`,i))}catch{}await _(300)}return x(`COMMAND_FAILED`,`alert wait timed out`)}async function le(e,t,n){let r=g(e.device)?l:c,i=Date.now(),a,o=!0;for(;Date.now()-i<c;){try{let a=o?r:X(i,c);return o=!1,Z(e,await n(t,a))}catch(e){a=e;let t=String(e?.message??``).toLowerCase();if(!t.includes(`alert not found`)&&!t.includes(`no alert`))break}await _(300)}throw ue(a)}function X(e,t){return Math.max(1,t-(Date.now()-e))}function Z(e,t){let n=t;return R(e.sessionStore,e.session,e.req,n),{ok:!0,data:n}}function ue(e){return!(e instanceof t)||!de(e)?e:new t(e.code,e.message,{...e.details??{},hint:`If the permission sheet is visible in snapshot or screenshot but alert reports no alert, take a scoped snapshot around the visible button label and use press @ref.`})}function de(e){let t=String(e?.message??``).toLowerCase();return t.includes(`alert not found`)||t.includes(`no alert`)}function fe(e){let t=e.positionals?.[0]?.toLowerCase(),n=e.positionals?.[1]?.toLowerCase(),r=e.positionals?.[2]?.toLowerCase();return t===`clear-app-state`?{ok:!0,parsed:{setting:t,state:`clear`,appBundleId:n===`clear`?e.positionals?.[2]:e.positionals?.[1]}}:!t||!n||t===`permission`&&!r||t===`location`&&n===`set`&&(!e.positionals?.[2]||!e.positionals?.[3])?x(`INVALID_ARGS`,a):{ok:!0,parsed:{setting:t,state:n,permissionTarget:r,latitude:e.positionals?.[2],longitude:e.positionals?.[3]}}}async function pe(e){let{req:t,logPath:n,sessionStore:r,session:i,device:a,parsed:o}=e,{setting:c,state:l,appBundleId:u,permissionTarget:f,latitude:p,longitude:h}=o,g=y(`settings`,a);if(g)return g;if(m(a)&&!s(c))return x(`INVALID_ARGS`,d(c));let _=u??i?.appBundleId;if(c===`clear-app-state`&&!_)return x(`INVALID_ARGS`,`settings clear-app-state requires an app id when no app is bound to the session`);let v=c===`clear-app-state`?[c,l,_??``]:c===`permission`?[c,l,f??``,t.positionals?.[3]??``,_??``]:c===`location`&&l===`set`?[c,l,p??``,h??``,_??``]:[c,l,_??``];i&&T(i);let C=await b(a,`settings`,v,t.flags?.out,{...S(n,t.flags,_,i?.trace?.outPath)});return R(r,i,t,C??{setting:c,state:l}),{ok:!0,data:C??{setting:c,state:l}}}async function me(t){if(t.command!==`snapshot`||t.device.platform!==`android`)return;let n=e(t.error);if(ye(n))return{ok:!1,error:{...n,details:{...n.details??{},androidSnapshotTimeoutScreenshot:await he(t)}}}}async function he(t){try{let e=await z.mkdtemp(V.join(B.tmpdir(),`agent-device-android-snapshot-timeout-`)),n=V.join(e,`snapshot-timeout-overlay-refs.png`),i=_e(await b(t.device,`screenshot`,[n],void 0,{...S(t.logPath,{screenshotNoStabilize:!0},t.session?.appBundleId,t.session?.trace?.outPath),surface:t.session?.surface}),n);await z.access(i);let a=await ge(i,t.session);return r({level:`warn`,phase:`android_snapshot_timeout_screenshot_captured`,data:{path:i,overlayRefCount:`overlayRefCount`in a?a.overlayRefCount:void 0,overlayRefsAnnotated:`overlayRefsAnnotated`in a?a.overlayRefsAnnotated:void 0}}),a}catch(t){let n=e(t);return r({level:`warn`,phase:`android_snapshot_timeout_screenshot_failed`,data:{error:n.message}}),{captureFailed:!0,error:n.message}}}async function ge(t,n){if(!n?.snapshot)return{path:t,overlayRefsRequested:!0,overlayRefsAnnotated:!1,overlayRefSource:`unavailable`,overlayRefCount:0};try{let e=await ee({screenshotPath:t,snapshot:n.snapshot});return{path:t,overlayRefsRequested:!0,overlayRefsAnnotated:e.length>0,overlayRefCount:e.length,overlayRefSource:`session-snapshot`,overlayRefs:e}}catch(n){let i=e(n);return r({level:`warn`,phase:`android_snapshot_timeout_screenshot_overlay_failed`,data:{path:t,error:i.message}}),{path:t,overlayRefsRequested:!0,overlayRefsAnnotated:!1,overlayRefSource:`session-snapshot`,overlayRefCount:0,overlayAnnotationError:i.message}}}function _e(e,t){return ve(e)?e.path:t}function ve(e){return typeof e==`object`&&!!e&&`path`in e&&typeof e.path==`string`}function ye(e){return e.code===`COMMAND_FAILED`?be(e)||xe(e.details?.helper):!1}function be(e){let t=`${e.message}\n${e.hint??``}`;return/Android accessibility snapshots can be blocked/i.test(t)}function xe(e){if(!e||typeof e!=`object`)return!1;let t=e,n=String(t.errorType??``),r=String(t.message??``);return/TimeoutException/i.test(n)||/timed out/i.test(r)}async function Se(e){return await Q({...e,command:`snapshot`,unsupportedMessage:`snapshot is not supported on this device`,execute:async({runtime:t,sessionName:n,req:r,snapshotScope:i})=>{let a=await t.capture.snapshot({session:n,interactiveOnly:r.flags?.snapshotInteractiveOnly,depth:r.flags?.snapshotDepth,scope:i,raw:r.flags?.snapshotRaw,forceFull:r.flags?.snapshotForceFull}),o=e.sessionStore.get(n)?.snapshotGeneration;return{data:o===void 0?a:{...a,refsGeneration:o},record:{kind:`snapshot`,nodes:a.nodes.length,truncated:a.truncated}}}})}async function Ce(e){return await Q({...e,command:`diff`,unsupportedMessage:`diff is not supported on this device`,execute:async({runtime:e,sessionName:t,req:n,snapshotScope:r})=>{let i=await e.capture.diffSnapshot({session:t,interactiveOnly:n.flags?.snapshotInteractiveOnly,depth:n.flags?.snapshotDepth,scope:r,raw:n.flags?.snapshotRaw});return{data:i,record:{kind:`diff`,mode:`snapshot`,baselineInitialized:i.baselineInitialized,summary:i.summary}}}})}async function Q(e){let{req:t,sessionName:n,logPath:r,sessionStore:i}=e,{session:a,device:o}=await P(i,n,t.flags),s=y(e.command,o,{message:e.unsupportedMessage});if(s)return s;let c=ne(t.flags?.snapshotScope,a);return c.ok?we(e.command,a,o)||await N(a,o,async()=>{let s=Te({req:t,sessionName:n,logPath:r,sessionStore:i,session:a,device:o,snapshotScope:c.scope}),l;try{l=await e.execute({runtime:s,sessionName:n,req:t,snapshotScope:c.scope})}catch(t){let n=await me({error:t,command:e.command,logPath:r,session:a,device:o});if(!n)throw t;return n}return je({req:t,sessionName:n,sessionStore:i,result:l.record}),{ok:!0,data:l.data}}):c}function we(e,t,n){return!g(n)||t?.appBundleId?null:x(`SESSION_NOT_FOUND`,`iOS ${e} requires an active app session on the target device. Run open first (for example: open --session ${t?.name??`sim`} --platform ios --device "<name>" <app>).`)}function Te(e){let{req:t,sessionName:n,logPath:r,sessionStore:i,session:a,device:o,snapshotScope:s}=e;return v({backend:Ae({req:t,logPath:r,session:a,device:o,snapshotScope:s}),...L(`snapshot`),sessions:O({sessionName:n,getSession:()=>i.get(n),recordOptions:{includeSnapshot:!0},setRecord:e=>{let r=Me(e),a=i.get(n);i.set(n,Ee({current:a,sessionName:n,device:o,record:r,refScopedSnapshot:De(t),issuesRefsToClient:t.command===`snapshot`}))}})})}function Ee(e){let{current:t,sessionName:n,device:r,record:i,refScopedSnapshot:a}=e,o=Oe(t,i,a),s=F({session:t,sessionName:n,device:r,snapshot:o?t.snapshot:i.snapshot,appBundleId:i.appBundleId});return s.snapshotScopeSource=$({current:t,keepCurrentSnapshot:o,refScopedSnapshot:a}),s.snapshotGeneration=o?t?.snapshotGeneration:D(t?.snapshotGeneration),ke(s,o,e.issuesRefsToClient),i.appName&&(s.appName=i.appName),s}function De(e){return e.flags?.snapshotScope?.trim().startsWith(`@`)===!0}function Oe(e,t,n){return n&&t.snapshot?.nodes.length===0&&e?.snapshot!==void 0}function ke(e,t,n){!t&&n&&j(e)}function $(e){let{current:t,keepCurrentSnapshot:n,refScopedSnapshot:r}=e;if(r)return n?t?.snapshotScopeSource:t?.snapshotScopeSource??t?.snapshot}function Ae(e){let{req:t,logPath:n,session:r,device:i,snapshotScope:a}=e;return{platform:h(i),captureSnapshot:async(e,s)=>{let c=await te({device:i,session:r,flags:t.flags,outPath:s?.outPath??t.flags?.out,logPath:n,snapshotScope:a}),l=p(r);return{snapshot:c.snapshot,...o(c),...l?{snapshotDiagnostics:l}:{},appName:r?.appBundleId?r.appName??r.appBundleId:void 0,appBundleId:r?.appBundleId}}}}function je(e){let t=e.sessionStore.get(e.sessionName);t&&e.sessionStore.recordAction(t,{command:e.req.command,positionals:e.req.positionals??[],flags:e.req.flags??{},result:Ne(e.result),interactiveObservation:f(e.req)})}function Me(e){if(!e.snapshot)throw new t(`UNKNOWN`,`snapshot runtime did not produce session state`);return e}function Ne(e){return e.kind===`snapshot`?{nodes:e.nodes,truncated:e.truncated}:{mode:e.mode,baselineInitialized:e.baselineInitialized,summary:e.summary}}const Pe={snapshot:async({req:e,sessionName:t,logPath:n,sessionStore:r})=>await Se({req:e,sessionName:t,logPath:n,sessionStore:r}),diff:async({req:e,sessionName:t,logPath:n,sessionStore:r})=>e.positionals?.[0]===`snapshot`?await Ce({req:e,sessionName:t,logPath:n,sessionStore:r}):x(`INVALID_ARGS`,`diff currently supports only: diff snapshot`),wait:async({req:e,sessionName:t,logPath:n,sessionStore:r})=>await I({req:e,sessionName:t,logPath:n,sessionStore:r}),alert:async({req:e,sessionName:t,logPath:n,sessionStore:r})=>{let{session:i,device:a}=await P(r,t,e.flags);return await N(i,a,async()=>await oe({req:e,logPath:n,sessionStore:r,session:i,device:a}))},settings:async({req:e,sessionName:t,logPath:n,sessionStore:r})=>{let i=fe(e);if(!i.ok)return i;let{session:a,device:o}=await P(r,t,e.flags);return await N(a,o,async()=>await pe({req:e,logPath:n,sessionStore:r,session:a,device:o,parsed:i.parsed}))}};async function Fe(e){let t=e.req.command,n=Pe[t];return n?await n(e):null}export{Fe as handleSnapshotCommands};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{t as e}from"./rolldown-runtime.js";import{
|
|
1
|
+
import{t as e}from"./rolldown-runtime.js";import{_ as t}from"./sdk-contracts.js";import{f as n,h as r,v as i,w as a}from"./sdk-android-adb.js";import{t as o}from"./scoped-provider.js";import{promises as s}from"node:fs";import c from"node:os";import l from"node:path";function u(e,t){return t===`user-installed`?e.filter(e=>!e.bundleId.startsWith(`com.apple.`)):e}function d(e,n){return{openBundle:async(t,n)=>{await e(`open`,f(t,n))},openTarget:async t=>{await e(`open`,[t])},readClipboard:async()=>r(await e(`pbpaste`,[],{allowFailure:!0}),`Failed to read macOS clipboard`).stdout.replace(/\r\n/g,`
|
|
2
2
|
`).replace(/\n$/,``),writeClipboard:async t=>{r(await e(`pbcopy`,[],{allowFailure:!0,stdin:t}),`Failed to write macOS clipboard`)},readDarkMode:async()=>{let n=r(await e(`osascript`,[`-e`,`tell application "System Events" to tell appearance preferences to get dark mode`],{allowFailure:!0}),`Failed to read macOS appearance`),i=n.stdout.trim().toLowerCase();if(i===`true`)return!0;if(i===`false`)return!1;throw new t(`COMMAND_FAILED`,`Unable to determine current macOS appearance from osascript output: ${n.stdout.trim()}`)},setDarkMode:async t=>{r(await e(`osascript`,[`-e`,`tell application "System Events" to tell appearance preferences to set dark mode to ${t?`true`:`false`}`],{allowFailure:!0}),`Failed to set macOS appearance`)},listApps:async t=>await p(e,n,t)}}function f(e,t){let n=[`-b`,e];return t&&n.push(t),n}async function p(e,t,n){let r=[`/Applications`,`/System/Applications`,l.join(c.homedir(),`Applications`)],i=new Set;for(let t of r){if(!(await s.stat(t).catch(()=>null))?.isDirectory())continue;let n=await e(`find`,[t,`-maxdepth`,`4`,`-type`,`d`,`-name`,`*.app`],{allowFailure:!0});if(n.exitCode===0)for(let e of n.stdout.split(`
|
|
3
|
-
`)){let t=e.trim();t&&i.add(t)}}return u((await Promise.all(Array.from(i).map(async e=>{let n=await m(e,t).catch(()=>({})),r=n.bundleId;return r?{bundleId:r,name:n.appName??l.basename(e,`.app`)}:null}))).filter(e=>e!==null).sort((e,t)=>e.name.localeCompare(t.name)),n)}async function m(e,t){for(let n of[l.join(e,`Contents`,`Info.plist`),l.join(e,`Info.plist`)]){let e=await t(n),r=h(e,`CFBundleIdentifier`),i=h(e,`CFBundleDisplayName`),a=h(e,`CFBundleName`);if(r||i||a)return{bundleId:r,appName:i??a}}return{}}function h(e,t){let n=e?.[t];return typeof n==`string`&&n.trim()?n.trim():void 0}var g=e({createLocalAppleToolProvider:()=>y,hasScopedAppleToolProvider:()=>S,readApplePlistJson:()=>T,resolveAppleToolProvider:()=>b,runAppleToolCommand:()=>C,runXcrun:()=>w,withAppleToolProvider:()=>x});const _={runCommand:i,simctl:{run:async(e,t)=>await i(`xcrun`,[`simctl`,...e],t)},devicectl:{run:async(e,t)=>await i(`xcrun`,[`devicectl`,...e],t)},plist:{readJson:async e=>await k(i,e)},macosHost:d(i,async e=>await k(i,e)),whichCommand:a},v=o(_,E);function y(e={}){let t={..._,...e},n=e.plist??{readJson:async e=>await k(t.runCommand,e)};return{...t,simctl:e.simctl??{run:async(e,n)=>await t.runCommand(`xcrun`,[`simctl`,...e],n)},devicectl:e.devicectl??{run:async(e,n)=>await t.runCommand(`xcrun`,[`devicectl`,...e],n)},plist:n,macosHost:e.macosHost??d(t.runCommand,async e=>await n.readJson(e))}}function b(e){return v.resolve(e)}async function x(e,t){return await v.run(e,t)}function S(){return v.hasScope()}async function C(e,t,n){return await b().runCommand(e,t,n)}async function w(e,t){let n=b(),[r,...i]=e;return r===`simctl`?await(n.simctl?.run(i,t)??n.runCommand(`xcrun`,e,t)):r===`devicectl`?await(n.devicectl?.run(i,t)??n.runCommand(`xcrun`,e,t)):await C(`xcrun`,e,t)}async function T(e){return await b().plist?.readJson(e)??null}function E(e){return y(typeof e==`function`?{runCommand:D(e)}:{...e,runCommand:D(e.runCommand),...e.simctl?{simctl:{run:O(e.simctl.run)}}:{},...e.devicectl?{devicectl:{run:O(e.devicectl.run)}}:{},...e.macosHelper?{macosHelper:{run:O(e.macosHelper.run)}}:{}})}function D(e){return async(t,r,i)=>n(await e(t,r,i))}function O(e){return async(t,r)=>n(await e(t,r))}async function k(e,t){try{let n=await e(`plutil`,[`-convert`,`json`,`-o`,`-`,t],{allowFailure:!0});return n.exitCode!==0||!n.stdout.trim()?null:JSON.parse(n.stdout)}catch{return null}}export{
|
|
3
|
+
`)){let t=e.trim();t&&i.add(t)}}return u((await Promise.all(Array.from(i).map(async e=>{let n=await m(e,t).catch(()=>({})),r=n.bundleId;return r?{bundleId:r,name:n.appName??l.basename(e,`.app`)}:null}))).filter(e=>e!==null).sort((e,t)=>e.name.localeCompare(t.name)),n)}async function m(e,t){for(let n of[l.join(e,`Contents`,`Info.plist`),l.join(e,`Info.plist`)]){let e=await t(n),r=h(e,`CFBundleIdentifier`),i=h(e,`CFBundleDisplayName`),a=h(e,`CFBundleName`);if(r||i||a)return{bundleId:r,appName:i??a}}return{}}function h(e,t){let n=e?.[t];return typeof n==`string`&&n.trim()?n.trim():void 0}var g=e({createLocalAppleToolProvider:()=>y,hasScopedAppleToolProvider:()=>S,readApplePlistJson:()=>T,resolveAppleToolProvider:()=>b,runAppleToolCommand:()=>C,runXcrun:()=>w,withAppleToolProvider:()=>x});const _={runCommand:i,simctl:{run:async(e,t)=>await i(`xcrun`,[`simctl`,...e],t)},devicectl:{run:async(e,t)=>await i(`xcrun`,[`devicectl`,...e],t)},plist:{readJson:async e=>await k(i,e)},macosHost:d(i,async e=>await k(i,e)),whichCommand:a},v=o(_,E);function y(e={}){let t={..._,...e},n=e.plist??{readJson:async e=>await k(t.runCommand,e)};return{...t,simctl:e.simctl??{run:async(e,n)=>await t.runCommand(`xcrun`,[`simctl`,...e],n)},devicectl:e.devicectl??{run:async(e,n)=>await t.runCommand(`xcrun`,[`devicectl`,...e],n)},plist:n,macosHost:e.macosHost??d(t.runCommand,async e=>await n.readJson(e))}}function b(e){return v.resolve(e)}async function x(e,t){return await v.run(e,t)}function S(){return v.hasScope()}async function C(e,t,n){return await b().runCommand(e,t,n)}async function w(e,t){let n=b(),[r,...i]=e;return r===`simctl`?await(n.simctl?.run(i,t)??n.runCommand(`xcrun`,e,t)):r===`devicectl`?await(n.devicectl?.run(i,t)??n.runCommand(`xcrun`,e,t)):await C(`xcrun`,e,t)}async function T(e){return await b().plist?.readJson(e)??null}function E(e){return y(typeof e==`function`?{runCommand:D(e)}:{...e,runCommand:D(e.runCommand),...e.simctl?{simctl:{run:O(e.simctl.run)}}:{},...e.devicectl?{devicectl:{run:O(e.devicectl.run)}}:{},...e.macosHelper?{macosHelper:{run:O(e.macosHelper.run)}}:{}})}function D(e){return async(t,r,i)=>n(await e(t,r,i))}function O(e){return async(t,r)=>n(await e(t,r))}async function k(e,t){try{let n=await e(`plutil`,[`-convert`,`json`,`-o`,`-`,t],{allowFailure:!0});return n.exitCode!==0||!n.stdout.trim()?null:JSON.parse(n.stdout)}catch{return null}}export{w as a,C as i,T as n,g as o,b as r,u as s,S as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as e}from"./rolldown-runtime.js";import{
|
|
1
|
+
import{t as e}from"./rolldown-runtime.js";import{_ as t}from"./sdk-contracts.js";import{j as n,v as r,w as i}from"./sdk-android-adb.js";import{t as a}from"./timeouts.js";import{t as o}from"./scoped-provider.js";var s=e({createLocalLinuxToolProvider:()=>u,resolveLinuxToolProvider:()=>d,runLinuxToolCommand:()=>p,withLinuxToolProvider:()=>f});const c={runCommand:r,whichCommand:i,desktop:m(r,i),clipboard:h(r,i),screenshot:g(r,i)},l=o(c,u);function u(e={}){let t={...c,...e};return{...t,desktop:e.desktop??m(t.runCommand,t.whichCommand),clipboard:e.clipboard??h(t.runCommand,t.whichCommand),screenshot:e.screenshot??g(t.runCommand,t.whichCommand)}}function d(e){return l.resolve(e)}async function f(e,t){return await l.run(e,t)}async function p(e,t,n){return await d().runCommand(e,t,n)}function m(e,t){return{async openTarget(r){if(r.includes(`://`)||r.startsWith(`/`)){await e(`xdg-open`,[r]);return}if(await t(r)){e(r,[],{allowFailure:!0}).catch(e=>{n({level:`warn`,phase:`linux_app_launch`,data:{app:r,error:String(e)}})}),await a(500);return}await e(`xdg-open`,[r],{allowFailure:!0})},async closeApp(n){if(await t(`wmctrl`)){await e(`wmctrl`,[`-c`,n],{allowFailure:!0});return}await e(`pkill`,[`-x`,n],{allowFailure:!0})}}}function h(e,t){return{async readText(){let n=await C(t,v),r=b[n];return(await e(r.cmd,r.args,r.options)).stdout},async writeText(n){let r=await C(t,v),i=x[r](n);await e(i.cmd,i.args,i.options)}}}function g(e,t){return{async capture(n){let r=await C(t,y),i=S[r](n);await e(i.cmd,i.args,i.options)}}}const _=5e3,v={wayland:[{tool:`wl-clipboard`,command:`wl-paste`}],x11:[{tool:`xclip`,command:`xclip`},{tool:`xsel`,command:`xsel`}],waylandError:`wl-paste (wl-clipboard) is required for clipboard access on Wayland. Install via your package manager.`,x11Error:`xclip or xsel is required for clipboard access on X11. Install via your package manager.`},y={wayland:[{tool:`grim`,command:`grim`},{tool:`gnome-screenshot`,command:`gnome-screenshot`}],x11:[{tool:`scrot`,command:`scrot`},{tool:`import`,command:`import`},{tool:`gnome-screenshot`,command:`gnome-screenshot`}],waylandError:`grim or gnome-screenshot is required for screenshots on Wayland. Install via your package manager.`,x11Error:`scrot, import (ImageMagick), or gnome-screenshot is required for screenshots on X11. Install via your package manager.`},b={"wl-clipboard":{cmd:`wl-paste`,args:[`--no-newline`],options:{allowFailure:!0,timeoutMs:_}},xclip:{cmd:`xclip`,args:[`-selection`,`clipboard`,`-o`],options:{allowFailure:!0,timeoutMs:_}},xsel:{cmd:`xsel`,args:[`--clipboard`,`--output`],options:{allowFailure:!0,timeoutMs:_}}},x={"wl-clipboard":e=>({cmd:`wl-copy`,args:[`--`,e],options:{allowFailure:!1,timeoutMs:_}}),xclip:e=>({cmd:`xclip`,args:[`-selection`,`clipboard`],options:{allowFailure:!1,timeoutMs:_,stdin:e}}),xsel:e=>({cmd:`xsel`,args:[`--clipboard`,`--input`],options:{allowFailure:!1,timeoutMs:_,stdin:e}})},S={grim:e=>({cmd:`grim`,args:[e]}),scrot:e=>({cmd:`scrot`,args:[e]}),import:e=>({cmd:`import`,args:[`-window`,`root`,e]}),"gnome-screenshot":e=>({cmd:`gnome-screenshot`,args:[`-f`,e]})};async function C(e,n){let r=w()?`wayland`:`x11`;for(let t of n[r])if(await e(t.command))return t.tool;throw new t(`TOOL_MISSING`,r===`wayland`?n.waylandError:n.x11Error)}function w(){return!!process.env.WAYLAND_DISPLAY||process.env.XDG_SESSION_TYPE===`wayland`}export{p as n,s as r,d as t};
|