agent-device 0.20.8 → 0.20.9
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 +94 -31
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.8.apk → agent-device-android-ime-helper-0.20.9.apk} +0 -0
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.9.apk.sha256 +1 -0
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.8.manifest.json → agent-device-android-ime-helper-0.20.9.manifest.json} +4 -4
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.8.apk → agent-device-android-snapshot-helper-0.20.9.apk} +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.9.apk.sha256 +1 -0
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.8.manifest.json → agent-device-android-snapshot-helper-0.20.9.manifest.json} +6 -6
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.h +3 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.m +13 -7
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +4 -112
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+FlatSnapshotFiltering.swift +9 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+PrivateAXPresentation.swift +90 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +46 -10
- package/dist/src/agent-browser-tool.js +1 -1
- package/dist/src/agent-device-client.js +2 -2
- package/dist/src/android-adb.d.ts +5 -5
- package/dist/src/android-adb.js +1 -1
- package/dist/src/android.js +1 -1
- package/dist/src/app-helpers.js +1 -1
- package/dist/src/app-lifecycle.js +6 -7
- package/dist/src/app-lifecycle2.js +2 -2
- package/dist/src/app-log-reconnect.js +1 -1
- package/dist/src/app-log-runtime.js +3 -3
- package/dist/src/app-resolution.js +2 -2
- package/dist/src/app-state.js +2 -0
- package/dist/src/appearance.js +1 -0
- package/dist/src/apps.js +5 -5
- package/dist/src/artifacts.d.ts +1 -1
- package/dist/src/audio-probe.js +1 -1
- package/dist/src/auth-session.js +1 -1
- package/dist/src/backend-snapshot-options.js +1 -0
- package/dist/src/boot-diagnostics.js +2 -2
- package/dist/src/bounds.js +1 -0
- package/dist/src/byte-limit-stream.js +1 -0
- package/dist/src/cancel.js +1 -0
- package/dist/src/cli-config.js +1 -1
- package/dist/src/cli-help.js +25 -20
- package/dist/src/cli.js +6 -6
- package/dist/src/client-metro.js +1 -1
- package/dist/src/command-catalog.js +1 -0
- package/dist/src/command-metadata.js +1 -1
- package/dist/src/command-schema.js +1 -1
- package/dist/src/command-surface.js +1 -1
- package/dist/src/config.js +1 -0
- package/dist/src/connection-runtime.js +1 -1
- package/dist/src/connection.js +3 -3
- package/dist/src/contracts.js +1 -1
- package/dist/src/debug-symbols.js +3 -3
- package/dist/src/device-claim-inspection.js +1 -1
- package/dist/src/device-input-state.js +1 -1
- package/dist/src/device-ready.js +1 -1
- package/dist/src/device2.js +2 -2
- package/dist/src/dispatch.js +1 -1
- package/dist/src/entities.js +1 -1
- package/dist/src/find.js +1 -1
- package/dist/src/finders.js +1 -1
- package/dist/src/generic-settle.js +1 -1
- package/dist/src/generic.js +1 -1
- package/dist/src/harmonyos.js +1 -1
- package/dist/src/hdc.js +1 -1
- package/dist/src/helper-package-install.js +1 -0
- package/dist/src/helper.js +2 -2
- package/dist/src/host-process.js +1 -1
- package/dist/src/ime-lifecycle.js +2 -9
- package/dist/src/ime-recovery-marker.js +1 -0
- package/dist/src/index.d.ts +24 -15
- package/dist/src/index.js +1 -1
- package/dist/src/input-actions.js +4 -4
- package/dist/src/input-actions2.js +1 -1
- package/dist/src/input-actions3.js +1 -1
- package/dist/src/install-artifact.js +1 -1
- package/dist/src/install-artifact2.js +1 -1
- package/dist/src/install-source2.js +1 -1
- package/dist/src/interaction-common.js +1 -0
- package/dist/src/interaction-runtime.js +1 -1
- package/dist/src/interaction-snapshot.js +1 -1
- package/dist/src/interaction.js +1 -1
- package/dist/src/interaction2.js +1 -0
- package/dist/src/interactor.js +2 -2
- package/dist/src/interactor2.js +1 -1
- package/dist/src/interactors.js +1 -0
- package/dist/src/internal/bin.js +1 -1
- package/dist/src/internal/daemon.js +4 -7
- package/dist/src/internal/png-worker.js +1 -1
- package/dist/src/inventory.js +1 -1
- package/dist/src/keyed-lock.js +1 -0
- package/dist/src/lease-context.js +1 -1
- package/dist/src/lease.js +1 -1
- package/dist/src/limrun-runtime-dependencies.js +1 -1
- package/dist/src/limrun.d.ts +3 -1
- package/dist/src/limrun.js +1 -1
- package/dist/src/linux.js +1 -1
- package/dist/src/location-coordinates.js +1 -0
- package/dist/src/logcat.js +1 -1
- package/dist/src/manifest.js +1 -1
- package/dist/src/observability.js +1 -0
- package/dist/src/owner-identity.js +1 -1
- package/dist/src/perf.js +4 -0
- package/dist/src/physical-device-control.js +1 -1
- package/dist/src/platform-runtime-app-log-process.js +1 -1
- package/dist/src/platform-runtime-host.js +1 -1
- package/dist/src/platform-runtime-network-web-transport.js +1 -1
- package/dist/src/platform-runtime-open-target.js +1 -0
- package/dist/src/platform-runtime-operation-host.js +4 -4
- package/dist/src/platform-runtime-runtime-hints.js +2 -0
- package/dist/src/platform-runtime-screen-recording-apple-runner-host.js +1 -1
- package/dist/src/platform-runtime-screen-recording-apple-runner-transport.js +1 -1
- package/dist/src/platform-runtime-screen-recording-apple-transport.js +1 -1
- package/dist/src/platform-runtime-screen-recording-finalizer-host.js +1 -1
- package/dist/src/platform-runtime-screen-recording-web-host.js +1 -1
- package/dist/src/platform-runtime.js +1 -1
- package/dist/src/platform-runtime2.js +1 -0
- package/dist/src/plist.js +1 -1
- package/dist/src/png-resize.js +1 -0
- package/dist/src/png-worker-contract.js +1 -1
- package/dist/src/prepare-kind.js +13 -13
- package/dist/src/process-lock.js +1 -1
- package/dist/src/project-runtime.js +1 -0
- package/dist/src/provider-webdriver.js +1 -1
- package/dist/src/provider.js +1 -0
- package/dist/src/proxy.js +1 -1
- package/dist/src/react-native.js +1 -1
- package/dist/src/record-runtime.js +1 -1
- package/dist/src/record-trace.js +1 -1
- package/dist/src/recording-export-quality.js +1 -0
- package/dist/src/registry.js +29 -26
- package/dist/src/remote-config2.js +1 -1
- package/dist/src/replay.js +1 -1
- package/dist/src/reporting.js +3 -3
- package/dist/src/rolldown-runtime.js +1 -0
- package/dist/src/runner-client.js +1 -0
- package/dist/src/runner-disposal.js +1 -1
- package/dist/src/runner-lease.js +1 -1
- 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 +4 -3
- package/dist/src/runtime3.js +1 -3
- package/dist/src/runtime4.js +3 -1
- package/dist/src/runtime5.js +1 -1
- package/dist/src/runtime6.js +1 -1
- package/dist/src/runtime7.js +1 -1
- package/dist/src/runtime8.js +1 -0
- package/dist/src/runtime9.js +1 -0
- package/dist/src/scoped-provider.js +1 -0
- package/dist/src/screenshot-density.js +1 -0
- package/dist/src/screenshot-geometry.js +1 -0
- package/dist/src/screenshot-result.js +4 -4
- package/dist/src/screenshot.js +1 -1
- package/dist/src/sdk-android-adb.d.ts +20 -2
- package/dist/src/sdk-android-adb.js +3 -3
- package/dist/src/sdk-batch-runner.js +3 -3
- package/dist/src/sdk-contracts.d.ts +3 -3
- package/dist/src/sdk-contracts.js +2 -2
- package/dist/src/sdk-device.js +1 -1
- package/dist/src/sdk-finders.js +1 -1
- package/dist/src/sdk-io.js +1 -1
- package/dist/src/sdk-remote-config.js +1 -1
- package/dist/src/sdk-selectors.d.ts +19 -19
- package/dist/src/sdk-selectors.js +1 -1
- package/dist/src/sdk.js +1 -0
- package/dist/src/selector-runtime.js +1 -1
- package/dist/src/selectors.d.ts +1 -1
- package/dist/src/selectors.js +1 -1
- package/dist/src/server.js +2 -2
- package/dist/src/session-target-evidence.js +1 -1
- package/dist/src/session.js +1 -30
- package/dist/src/session2.js +28 -0
- package/dist/src/setting-state.js +1 -1
- package/dist/src/shared.js +1 -1
- package/dist/src/simctl.js +1 -0
- package/dist/src/simulator-state.js +1 -0
- package/dist/src/simulator.js +1 -1
- package/dist/src/snapshot-runtime.js +1 -1
- package/dist/src/snapshot-session.js +1 -1
- package/dist/src/snapshot.js +8 -1
- package/dist/src/snapshot2.js +1 -1
- package/dist/src/snapshot3.js +1 -0
- package/dist/src/src.js +1 -1
- package/dist/src/src2.js +1 -2
- package/dist/src/src3.js +2 -1
- package/dist/src/string-enum.js +1 -0
- package/dist/src/tool-provider.js +3 -3
- package/dist/src/tool-provider2.js +1 -1
- package/dist/src/update-check.js +1 -1
- package/dist/src/verdict.js +1 -0
- package/dist/src/verified-file.js +1 -0
- package/dist/src/version.js +1 -1
- package/dist/src/video.js +1 -1
- package/dist/src/web.js +1 -1
- package/package.json +8 -4
- package/server.json +3 -3
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.8.apk.sha256 +0 -1
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.8.apk.sha256 +0 -1
- package/dist/src/interaction-touch-reference-frame.js +0 -1
- package/dist/src/notifications.js +0 -1
- package/dist/src/platform-runtime-toolchain-host.js +0 -1
- package/dist/src/text-surface.js +0 -1
- package/dist/src/tool-provider3.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as
|
|
1
|
+
import{C as e}from"../sdk-contracts.js";import{a as t,i as n,n as r,r as i,t as a}from"../png-worker-contract.js";import{parentPort as o}from"node:worker_threads";function s(e){switch(e.kind){case`decode`:{let t=n(a(e.png),e.label);return{kind:`decode`,width:t.width,height:t.height,data:t.data}}case`encode`:{let n=new t.PNG({width:e.width,height:e.height});return n.data=a(e.data),{kind:`encode`,png:t.PNG.sync.write(n)}}case`rgb-difference`:return{kind:`rgb-difference`,...r(n(a(e.firstPng),e.label),n(a(e.secondPng),e.label))};case`diff-pixels`:return{kind:`diff-pixels`,...i(e)}}}function c(e){return e.buffer instanceof ArrayBuffer&&e.byteOffset===0&&e.byteLength===e.buffer.byteLength}function l(e){return u(e).filter(c).map(e=>e.buffer)}function u(e){switch(e.kind){case`decode`:return[e.data];case`encode`:return[e.png];case`rgb-difference`:return[];case`diff-pixels`:return[e.diffData,e.diffMask]}}const d=o;d&&d.on(`message`,t=>{let n;try{n={id:t.id,ok:!0,result:s(t)}}catch(r){n={id:t.id,ok:!1,error:e(r)}}d.postMessage(n,n.ok?l(n.result):[])});export{l as resultTransferList};
|
package/dist/src/inventory.js
CHANGED
|
@@ -2,4 +2,4 @@ import{_ as e,v as t}from"./sdk-contracts.js";import n from"node:path";const r=[
|
|
|
2
2
|
`)){let e=n.trim().split(/\s+/),r=e[0];!r||r===`List`||e[1]!==`device`||t.push({serial:r,rawModel:(e.find(e=>e.startsWith(`model:`))??``).replace(`model:`,``)})}return t}function d(e){return e.split(`
|
|
3
3
|
`).map(e=>e.trim()).filter(e=>e.length>0)}function f(e){let t=e.split(`
|
|
4
4
|
`).map(e=>e.trim()).filter(e=>e.length>0);return t.at(-1)===`OK`&&t.pop(),t.join(`
|
|
5
|
-
`).trim()||void 0}function p(e){let t=e.toLowerCase();return t.includes(`tv`)||t.includes(`leanback`)?`tv`:null}function m(e){return/feature:android\.(software\.leanback(_only)?|hardware\.type\.television)\b/i.test(e)}function h(e){return/\b(tv|television)\b/i.test(l(e))?`tv`:`mobile`}const g=[`android.software.leanback`,`android.software.leanback_only`,`android.hardware.type.television`];function _(e,t={sdkRoots:[]}){return{discover:async(n,r)=>await v(e,t,n,r)}}async function v(t,r,i,a){await t.toolchains.prepare(`android`);let o=[...r.sdkRoots,n.join(t.homeDirectory,`Android`,`Sdk`)],s=await b(t,`adb`,o,[`platform-tools`,`adb`]);if(!s)throw new e(`TOOL_MISSING`,`adb not found in PATH`);let c={host:t,adb:s,emulator:await b(t,`emulator`,o,[`emulator`,`emulator`]),scope:a},l=y(i),u=await M((await x(c)).filter(e=>!l||l.has(e.serial)),3,async e=>await S(c,e));return[...u,...await O(c,u)]}function y(e){let t=e.serial?.trim(),n=e.androidSerialAllowlist;return t?n?new Set(n.includes(t)?[t]:[]):new Set([t]):n?new Set(n):void 0}async function b(e,t,r,i){for(let t of r){let r=n.join(t,...i);if(await e.files.isExecutable(r))return r}return await e.commands.which(t)}async function x(e){let t=await A(e,e.adb,[`devices`,`-l`]);if(t.exitCode!==0)throw o(`Failed to list Android devices`,t,"Verify adb is running and the device appears in `adb devices`.");return u(t.stdout)}async function S(e,t){let[n,r,i]=await Promise.all([C(e,t),E(e,t.serial),D(e,t.serial)]);return{platform:`android`,id:t.serial,name:n,kind:c(t.serial)?`emulator`:`device`,target:i,booted:r}}async function C(e,t){let n=t.rawModel.replace(/_/g,` `).trim();return c(t.serial)?(await w(e,t.serial))?.replace(/_/g,` `)||n||t.serial:n||t.serial}async function w(e,t){for(let n of[`ro.boot.qemu.avd_name`,`persist.sys.avd_name`]){let r=await T(e,t,[`shell`,`getprop`,n]),i=r?.stdout.trim();if(r?.exitCode===0&&i)return i}let n=await T(e,t,[`emu`,`avd`,`name`]),r=n&&f(n.stdout);return n?.exitCode===0?r:void 0}async function T(e,n,r){try{return await k(e,n,r)}catch(e){let n=t(e);if(n.code===`COMMAND_FAILED`&&typeof n.details?.timeoutMs==`number`)return;throw e}}async function E(e,t){try{return(await k(e,t,[`shell`,`getprop`,`sys.boot_completed`])).stdout.trim()===`1`}catch(t){if(e.scope.signal.aborted)throw t;return!1}}async function D(e,t){return p(j(await k(e,t,[`shell`,`getprop`,`ro.build.characteristics`])))===`tv`||(await M(g,2,async n=>await k(e,t,[`shell`,`cmd`,`package`,`has-feature`,n]))).some(e=>j(e).toLowerCase().includes(`true`))||m(j(await k(e,t,[`shell`,`pm`,`list`,`features`])))?`tv`:`mobile`}async function O(e,t){if(!e.emulator)return[];let n;try{n=await A(e,e.emulator,[`-list-avds`])}catch(t){if(e.scope.signal.aborted)throw t;return[]}if(n.exitCode!==0)return[];let r=new Set(t.filter(e=>e.kind===`emulator`).map(e=>l(e.name)));return d(n.stdout).filter(e=>!r.has(l(e))).map(e=>({platform:`android`,id:e,name:e,kind:`emulator`,target:h(e),booted:!1}))}async function k(e,t,n){return await A(e,e.adb,[`-s`,t,...n])}async function A(e,t,n){try{return await e.host.commands.run({executable:t,args:n,allowFailure:!0,timeoutMs:1e4},e.scope.signal)}catch(e){throw s(e)}}function j(e){return`${e.stdout}\n${e.stderr}`}async function M(e,t,n){let r=Array(e.length),i=0;return await Promise.all(Array.from({length:Math.min(t,e.length)},async()=>{for(;i<e.length;){let t=i++;r[t]=await n(e[t])}})),r}export{_ as createAndroidInventory};
|
|
5
|
+
`).trim()||void 0}function p(e){let t=e.toLowerCase();return t.includes(`tv`)||t.includes(`leanback`)?`tv`:null}function m(e){return/feature:android\.(software\.leanback(_only)?|hardware\.type\.television)\b/i.test(e)}function h(e){return/\b(tv|television)\b/i.test(l(e))?`tv`:`mobile`}const g=[`android.software.leanback`,`android.software.leanback_only`,`android.hardware.type.television`];function _(e,t={sdkRoots:[]}){return{discover:async(n,r)=>await v(e,t,n,r)}}async function v(t,r,i,a){await t.toolchains.prepare(`android`);let o=[...r.sdkRoots,n.join(t.homeDirectory,`Android`,`Sdk`)],s=await b(t,`adb`,o,[`platform-tools`,`adb`]);if(!s)throw new e(`TOOL_MISSING`,`adb not found in PATH`);let c={host:t,adb:s,emulator:await b(t,`emulator`,o,[`emulator`,`emulator`]),scope:a},l=y(i),u=await M((await x(c)).filter(e=>!l||l.has(e.serial)),3,async e=>await S(c,e));return[...u,...i.androidAvdSelection===`running-only`?[]:await O(c,u)]}function y(e){let t=e.serial?.trim(),n=e.androidSerialAllowlist;return t?n?new Set(n.includes(t)?[t]:[]):new Set([t]):n?new Set(n):void 0}async function b(e,t,r,i){for(let t of r){let r=n.join(t,...i);if(await e.files.isExecutable(r))return r}return await e.commands.which(t)}async function x(e){let t=await A(e,e.adb,[`devices`,`-l`]);if(t.exitCode!==0)throw o(`Failed to list Android devices`,t,"Verify adb is running and the device appears in `adb devices`.");return u(t.stdout)}async function S(e,t){let[n,r,i]=await Promise.all([C(e,t),E(e,t.serial),D(e,t.serial)]);return{platform:`android`,id:t.serial,name:n,kind:c(t.serial)?`emulator`:`device`,target:i,booted:r}}async function C(e,t){let n=t.rawModel.replace(/_/g,` `).trim();return c(t.serial)?(await w(e,t.serial))?.replace(/_/g,` `)||n||t.serial:n||t.serial}async function w(e,t){for(let n of[`ro.boot.qemu.avd_name`,`persist.sys.avd_name`]){let r=await T(e,t,[`shell`,`getprop`,n]),i=r?.stdout.trim();if(r?.exitCode===0&&i)return i}let n=await T(e,t,[`emu`,`avd`,`name`]),r=n&&f(n.stdout);return n?.exitCode===0?r:void 0}async function T(e,n,r){try{return await k(e,n,r)}catch(e){let n=t(e);if(n.code===`COMMAND_FAILED`&&typeof n.details?.timeoutMs==`number`)return;throw e}}async function E(e,t){try{return(await k(e,t,[`shell`,`getprop`,`sys.boot_completed`])).stdout.trim()===`1`}catch(t){if(e.scope.signal.aborted)throw t;return!1}}async function D(e,t){return p(j(await k(e,t,[`shell`,`getprop`,`ro.build.characteristics`])))===`tv`||(await M(g,2,async n=>await k(e,t,[`shell`,`cmd`,`package`,`has-feature`,n]))).some(e=>j(e).toLowerCase().includes(`true`))||m(j(await k(e,t,[`shell`,`pm`,`list`,`features`])))?`tv`:`mobile`}async function O(e,t){if(!e.emulator)return[];let n;try{n=await A(e,e.emulator,[`-list-avds`])}catch(t){if(e.scope.signal.aborted)throw t;return[]}if(n.exitCode!==0)return[];let r=new Set(t.filter(e=>e.kind===`emulator`).map(e=>l(e.name)));return d(n.stdout).filter(e=>!r.has(l(e))).map(e=>({platform:`android`,id:e,name:e,kind:`emulator`,target:h(e),booted:!1}))}async function k(e,t,n){return await A(e,e.adb,[`-s`,t,...n])}async function A(e,t,n){try{return await e.host.commands.run({executable:t,args:n,allowFailure:!0,timeoutMs:1e4},e.scope.signal)}catch(e){throw s(e)}}function j(e){return`${e.stdout}\n${e.stderr}`}async function M(e,t,n){let r=Array(e.length),i=0;return await Promise.all(Array.from({length:Math.min(t,e.length)},async()=>{for(;i<e.length;){let t=i++;r[t]=await n(e[t])}})),r}export{_ as createAndroidInventory};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{AsyncLocalStorage as e}from"node:async_hooks";const t=new e;async function n(e,n,r){let i=t.getStore()??[];if(i.some(t=>t.locks===e&&t.key===n))return await r();let a=(e.get(n)??Promise.resolve()).catch(()=>{}).then(()=>t.run([...i,{locks:e,key:n}],r));return e.set(n,a),a.finally(()=>{e.get(n)===a&&e.delete(n)})}export{n as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{Br as e}from"./sdk-batch-runner.js";import{qt as t}from"./prepare-kind.js";function n(e){return t(e)}function r(t,r){let i=n(t),a=i.leaseId??r?.leaseId,o=i.tenantId??r?.tenantId,s=i.runId??r?.runId;if(!(!o||!s||!a))return e({tenantId:o,runId:s,leaseId:a,leaseBackend:i.leaseBackend??r?.backend,leaseProvider:i.leaseProvider??r?.leaseProvider,deviceKey:i.deviceKey??r?.deviceKey,clientId:i.clientId??r?.clientId,expiresAt:r?.expiresAt})}function i(t,r){let i=n(t),a=r?.lease??r?.deviceLease??void 0;return e({tenantId:i.tenantId??a?.tenantId,runId:i.runId??a?.runId,leaseId:i.leaseId??a?.leaseId,leaseTtlMs:i.leaseTtlMs,leaseBackend:i.leaseBackend??a?.leaseBackend,leaseProvider:i.leaseProvider??a?.leaseProvider,deviceKey:i.deviceKey??a?.deviceKey,clientId:i.clientId??a?.clientId})}function a(t){let n=t.meta,r=e({leaseId:o(n?.leaseId),clientId:o(n?.clientId),tenantId:o(n?.tenantId),runId:o(n?.runId),leaseProvider:o(n?.leaseProvider),deviceKey:o(n?.deviceKey)});return Object.keys(r).length>0?r:void 0}function o(e){return typeof e==`string`&&e.trim().length>0?e.trim():void 0}export{a as i,n,i as r,r as t};
|
package/dist/src/lease.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{_ as e}from"./sdk-contracts.js";import{
|
|
1
|
+
import{_ as e}from"./sdk-contracts.js";import{$t as t,Gt as n,Jt as r,Zt as i}from"./prepare-kind.js";import{n as a}from"./command-catalog.js";import{n as o,r as s}from"./lease-context.js";import{nn as c}from"./internal/daemon.js";async function l(e){let{req:n,sessionName:c,sessionStore:l,leaseRegistry:p,providerRuntimeIds:m,providerRuntimeRequiredIds:h,leaseLifecycleProvider:g,cloudArtifactProvider:_}=e,v=o(n);switch(n.command){case a.artifacts:return{ok:!0,data:await f(n,s(n,l.get(c)),_)};case`lease_allocate`:{d(v.leaseProvider,m,h);let e=p.allocateLease(r(v)),i;try{i=await g?.allocate?.(e,u(n))}catch(n){throw p.releaseLease(t({leaseId:e.leaseId,tenantId:e.tenantId,runId:e.runId,leaseBackend:e.backend,leaseProvider:e.leaseProvider,deviceKey:e.deviceKey,clientId:e.clientId})),n}return{ok:!0,data:{lease:e,...i?{provider:i}:{}}}}case`lease_heartbeat`:{let e=p.heartbeatLease(i(v)),t=await g?.heartbeat?.(e,u(n));return{ok:!0,data:{lease:e,...t?{provider:t}:{}}}}case`lease_release`:{let e=t(v),r=p.getLease(e),i=r?await g?.release?.(r,u(n)):void 0;return{ok:!0,data:{released:p.releaseLease(e).released,...i?{provider:i}:{}}}}default:return null}}function u(e){return{flags:e.flags,cwd:typeof e.meta?.cwd==`string`?e.meta.cwd:void 0}}function d(t,n,r){if(!(!t||n===void 0||r===void 0||!r.includes(t)||n.includes(t)))throw new e(`UNSUPPORTED_OPERATION`,`Provider "${t}" is not available in this daemon runtime.`,{provider:t,hint:`Restart the daemon with ${t} configured, then retry lease allocation.`})}async function f(e,t,n){let r=g(e.flags,`providerSessionId`);return p(t,r)?await m(t.tenantId):await h(t,r,n)}function p(e,t){return n(e)||!e.leaseProvider&&!t}async function m(e){let t=await c(e);return{source:`daemon`,status:`ready`,artifacts:t,...t.length===0?{message:`No daemon artifacts available.`}:{}}}async function h(t,n,r){if(!t.leaseProvider)throw new e(`INVALID_ARGS`,`artifacts requires --provider for provider session lookup or an active cloud connection.`);if(!t.leaseId&&!n)throw new e(`INVALID_ARGS`,`artifacts requires an active cloud lease or --provider-session <id>.`);let i=await r?.listCloudArtifacts?.({provider:t.leaseProvider,leaseId:t.leaseId,providerSessionId:n});if(!i)throw new e(`UNSUPPORTED_OPERATION`,`Cloud artifacts are not available for provider "${t.leaseProvider}".`);return i}function g(e,t){let n=e?.[t];return typeof n==`string`&&n.length>0?n:void 0}export{l as handleLeaseCommands};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{n as e}from"./rolldown-runtime.js";import{_ as t}from"./sdk-contracts.js";import{_ as n,f as r}from"./sdk-android-adb.js";import{n as i}from"./version.js";import{n as a}from"./android.js";var o=e({createLimrunRuntimeDependencies:()=>s});function s(){return{clientVersion:i(),android:{createInteractor:(e,t)=>a(e,t),createPortReverse:async e=>{let{createAndroidPortReverseManager:t}=await import(`./sdk-android-adb.js`).then(e=>e.t);return t(e)},inferAppName:async e=>{let{inferAndroidAppName:t}=await import(`./app-lifecycle.js`).then(e=>e.u);return t(e)},listApps:async(e,t)=>{let{listAndroidAppsWithAdb:n}=await import(`./app-helpers.js`).then(e=>e.t);return(await n(e,{filter:t,target:`mobile`})).map(e=>({id:e.package,name:e.name}))},getForegroundApp:async(e,t,n)=>{let{readAndroidAppStateWithHost:r}=await import(`./platform-runtime.js`).then(e=>e.r),i=await r({run:async(e,n,r)=>({stdout:(await t([...n.args],{allowFailure:n.allowFailure,timeoutMs:n.timeoutMs,signal:r})).stdout})},e,n??new AbortController().signal);return i.package?{appId:i.package,activity:i.activity}:void 0},getKeyboardState:async e=>{let{getAndroidKeyboardStatusWithAdb:t}=await import(`./device-input-state.js`).then(e=>e.t);return await t(e)},dismissKeyboard:async e=>{let{dismissAndroidKeyboardWithAdb:t}=await import(`./device-input-state.js`).then(e=>e.t);return await t(e)},readLogs:async(e,t)=>{let{captureAndroidLogcatWithAdb:n}=await import(`./logcat.js`).then(e=>e.n);return await n(e,{lines:t,timeoutMs:5e3})},adbError:async(e,t,n)=>{let{androidAdbResultError:r}=await import(`./sdk-android-adb.js`).then(e=>e.t);return r(e,t,n)}},host:{runAdb:async(e,t)=>await n(`adb`,e,t),archiveDirectory:async({sourceDirectory:e,entryName:i,archivePath:a})=>{let o=[`-qr`,a,i],s=await n(`zip`,o,{cwd:e,timeoutMs:12e4});if(s.exitCode!==0)throw new t(`COMMAND_FAILED`,`Failed to package iOS .app for Limrun install`,{command:[`zip`,...o].join(` `),...r(s)})}},ios:{resolveAppAlias:async e=>{let{resolveIosAppAlias:t}=await import(`./app-resolution.js`).then(e=>e.t);return t(e)},readBundleAppName:async e=>{let{readIosBundleInfo:t}=await import(`./install-artifact2.js`);return(await t(e)).appName}}}}export{o as n,s as t};
|
package/dist/src/limrun.d.ts
CHANGED
|
@@ -23,6 +23,8 @@ type DeviceInventoryRequest = {
|
|
|
23
23
|
/** Internal local-inventory projection filters; not public command grammar. */
|
|
24
24
|
kind?: DeviceKind;
|
|
25
25
|
booted?: boolean;
|
|
26
|
+
/** Internal target-resolution policy; ordinary inventory leaves this absent and lists all AVDs. */
|
|
27
|
+
androidAvdSelection?: 'running-only' | 'include-stopped';
|
|
26
28
|
};
|
|
27
29
|
type ProviderDeviceInventoryRequest = Omit<DeviceInventoryRequest, 'booted' | 'kind'>;
|
|
28
30
|
//#endregion
|
|
@@ -196,7 +198,7 @@ type LimrunDeviceSessionBase = {
|
|
|
196
198
|
type LimrunAndroidDeviceSession$1 = LimrunDeviceSessionBase & {
|
|
197
199
|
readonly platform: 'android';
|
|
198
200
|
readonly adb: LimrunAdbProvider;
|
|
199
|
-
getForegroundApp(): Promise<LimrunForegroundApp | undefined>;
|
|
201
|
+
getForegroundApp(signal?: AbortSignal): Promise<LimrunForegroundApp | undefined>;
|
|
200
202
|
getKeyboardState(): Promise<LimrunAndroidKeyboardState>;
|
|
201
203
|
dismissKeyboard(): Promise<LimrunAndroidKeyboardDismissResult>;
|
|
202
204
|
readLogs(lineLimit: number): Promise<string>;
|
package/dist/src/limrun.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{o as e,r as t}from"./src.js";import{t as n}from"./limrun-runtime-dependencies.js";var r=class{implementation;provider=e;constructor(e){this.implementation=t(e,n())}get leaseLifecycle(){return this.implementation.leaseLifecycle}get recoverExpiredLease(){return this.implementation.recoverExpiredLease}get deviceInventoryProvider(){return this.implementation.deviceInventoryProvider}ownsDevice(e){return this.implementation.ownsDevice(e)}getInteractor(e){return this.implementation.getInteractor(e)}getDeviceSession(e){return this.implementation.getDeviceSession(e)}async installApp(e,t,n,r){return await this.implementation.installApp?.(e,t,n,r)}async installInstallablePath(e,t,n){return await this.implementation.installInstallablePath?.(e,t,n)}async configurePortReverse(e){return await this.implementation.configurePortReverse?.(e)}async shutdown(){await this.implementation.shutdown()}};export{r as LimrunRuntime};
|
package/dist/src/linux.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{_ as e}from"./sdk-contracts.js";import{
|
|
1
|
+
import{_ as e}from"./sdk-contracts.js";import{b as t}from"./interaction.js";import{F as n}from"./sdk-android-adb.js";import{r,t as i}from"./snapshot2.js";import{doubleClickLinux as a,fillLinux as o,focusLinux as s,longPressLinux as c,pressLinux as l,scrollLinux as u,sendKey as d,swipeLinux as f,typeLinux as p}from"./input-actions3.js";async function m(e){await r().desktop.openTarget(e)}async function h(e){await r().desktop.closeApp(e)}async function g(){await d(`alt+Left`,[`56:1`,`105:1`,`105:0`,`56:0`])}async function _(){await d(`super+d`,[`125:1`,`32:1`,`32:0`,`125:0`])}async function v(){return await r().clipboard.readText()}async function y(e){await r().clipboard.writeText(e)}async function b(e,t){await r().screenshot.capture(e,t)}function x(){return{open:e=>m(e),openDevice:()=>Promise.resolve(),close:e=>h(e),tap:(e,t)=>l(e,t),doubleTap:(e,t)=>a(e,t),longPress:(e,t,n)=>c(e,t,n),focus:(e,t)=>s(e,t),type:(e,t)=>p(e,t),fill:(e,t,n,r)=>o(e,t,n,r),scroll:(e,t)=>u(e,t),performGesture:async n=>{if(n.topology===`two`)throw new e(`UNSUPPORTED_OPERATION`,`Multi-touch gestures are not supported on Linux`);let{start:r,end:i}=t(n);await f(r.x,r.y,i.x,i.y,n.durationMs)},screenshot:(e,t)=>b(e,t),snapshot:async e=>{let t=await n(`snapshot_capture`,async()=>await i(e?.surface,e?.signal),{backend:`linux-atspi`});return{nodes:t.nodes??[],truncated:t.truncated??!1,backend:`linux-atspi`}},back:()=>g(),home:()=>_(),setOrientation:()=>{throw new e(`UNSUPPORTED_OPERATION`,`orientation not supported on Linux`)},appSwitcher:()=>{throw new e(`UNSUPPORTED_OPERATION`,`appSwitcher not yet supported on Linux`)},tvRemote:()=>{throw new e(`UNSUPPORTED_OPERATION`,`tv-remote not supported on Linux`)},readClipboard:()=>v(),writeClipboard:e=>y(e),setSetting:()=>{throw new e(`UNSUPPORTED_OPERATION`,`setSetting not supported on Linux`)}}}export{x as createLinuxInteractor};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as e}from"./sdk-contracts.js";import{Vr as t}from"./sdk-batch-runner.js";const n={min:.01,max:1},r={flagKey:`screenshotMaxSize`,cliToken:`--max-size`,envVar:`AGENT_DEVICE_SCREENSHOT_MAX_SIZE`,publicOptionKey:`maxSize`,migration:{screenshot:`screenshot --max-size was removed; use --scale <0.01-1> (or AGENT_DEVICE_SCREENSHOT_SCALE) to downscale proportionally`,record:`record --max-size was removed; recordings capture at native resolution`}};function i(e,t){return t&&Object.hasOwn(t,r.flagKey)?r.migration[e]:void 0}function a(t,n){if(Object.hasOwn(n,r.publicOptionKey)||Object.hasOwn(n,r.flagKey))throw new e(`INVALID_ARGS`,r.migration[t])}const o=[`out`,`overlayRefs`,`screenshotPixelDensity`,`screenshotFullscreen`,`screenshotScale`,`screenshotNoStabilize`,`screenshotNormalizeStatusBar`],s=[`screenshotPixelDensity`,`screenshotFullscreen`,`screenshotScale`,`screenshotNoStabilize`,`screenshotNormalizeStatusBar`],c=[{key:`screenshotPixelDensity`,names:[`--pixel-density`],type:`int`,min:1,usageLabel:`--pixel-density <n>`,usageDescription:`Screenshot: output PNG pixel density in pixels per logical point (currently supported on iOS simulators)`},{key:`screenshotFullscreen`,names:[`--fullscreen`,`--full`,`-f`],type:`boolean`,usageLabel:`--fullscreen, --full, -f`,usageDescription:`Screenshot: on web capture the full page; on macOS app sessions capture the full desktop instead of the app window`},{key:`screenshotScale`,names:[`--scale`],type:`number`,min:n.min,max:n.max,usageLabel:`--scale <0.01-1>`,usageDescription:`Screenshot: resize both dimensions by this factor (or use AGENT_DEVICE_SCREENSHOT_SCALE)`},{key:`screenshotNoStabilize`,names:[`--no-stabilize`],type:`boolean`,usageLabel:`--no-stabilize`,usageDescription:`Screenshot: skip Android demo-mode/status-bar stabilization and settle delay for low-latency capture loops`},{key:`screenshotNormalizeStatusBar`,names:[`--normalize-status-bar`],type:`boolean`,usageLabel:`--normalize-status-bar`,usageDescription:`Screenshot: on iOS simulators temporarily normalize status-bar chrome for deterministic screenshot diffs`}],l=[{tokens:[`--fullscreen`,`--full`,`-f`],key:`screenshotFullscreen`},{tokens:[`--no-stabilize`],key:`screenshotNoStabilize`},{tokens:[`--normalize-status-bar`],key:`screenshotNormalizeStatusBar`}],ee=[{token:`--pixel-density`,key:`screenshotPixelDensity`,label:`screenshot --pixel-density`}],u=[{token:`--scale`,key:`screenshotScale`,label:`screenshot --scale`,min:n.min,max:n.max}];function d(e){return _({overlayRefs:e?.overlayRefs,pixelDensity:e?.screenshotPixelDensity,fullscreen:e?.screenshotFullscreen,scale:e?.screenshotScale,stabilize:e?.screenshotNoStabilize?!1:void 0,normalizeStatusBar:e?.screenshotNormalizeStatusBar})}function f(e={}){return _({overlayRefs:e.overlayRefs,screenshotPixelDensity:e.screenshotPixelDensity??e.pixelDensity,screenshotFullscreen:e.screenshotFullscreen??e.fullscreen,screenshotScale:e.screenshotScale,screenshotNoStabilize:e.screenshotNoStabilize??(e.stabilize===!1?!0:void 0),screenshotNormalizeStatusBar:e.screenshotNormalizeStatusBar??e.normalizeStatusBar})}function p(e={}){return f({...e,screenshotScale:e.screenshotScale??e.scale})}function m(t){let{min:r,max:i}=n;if(t.scale!==void 0&&(!Number.isFinite(t.scale)||t.scale<r||t.scale>i))throw new e(`INVALID_ARGS`,`screenshot scale must be between ${r} and ${i}`)}function h(e,t){typeof t?.screenshotPixelDensity==`number`&&e.push(`--pixel-density`,String(t.screenshotPixelDensity)),t?.screenshotFullscreen&&e.push(`--fullscreen`),typeof t?.screenshotScale==`number`&&e.push(`--scale`,String(t.screenshotScale)),t?.screenshotNoStabilize&&e.push(`--no-stabilize`),t?.screenshotNormalizeStatusBar&&e.push(`--normalize-status-bar`)}function g(t){let{args:n,flags:i,index:a}=t,o=n[a];if(o===r.cliToken)throw new e(`INVALID_ARGS`,r.migration.screenshot);return v(o,i,a)??y({args:n,index:a,flags:i,token:o})??b({args:n,index:a,flags:i,token:o})??{handled:!1}}function _(e){return Object.fromEntries(Object.entries(e).filter(e=>e[1]!==void 0))}function v(e,t,n){let r=l.find(t=>t.tokens.some(t=>t===e));if(r)return t[r.key]=!0,{handled:!0,nextIndex:n}}function y(t){let n=ee.find(e=>e.token===t.token);if(!n)return;let r=Number(t.args[t.index+1]);if(!Number.isInteger(r)||r<1)throw new e(`INVALID_ARGS`,`${n.label} requires a positive integer`);return t.flags[n.key]=r,{handled:!0,nextIndex:t.index+1}}function b(t){let n=u.find(e=>e.token===t.token);if(!n)return;let r=Number(t.args[t.index+1]);if(!Number.isFinite(r)||r<n.min||r>n.max)throw new e(`INVALID_ARGS`,`${n.label} requires a number from ${n.min} to ${n.max}`);return t.flags[n.key]=r,{handled:!0,nextIndex:t.index+1}}function x(e){let t=w(e.quality);return{...e.analysis?{analysis:e.analysis}:{},...e.androidSnapshot?{androidSnapshot:e.androidSnapshot}:{},...e.freshness?{freshness:e.freshness}:{},...t?{quality:t}:{},...e.warnings?{warnings:e.warnings}:{}}}function S(e){return{...e.androidSnapshot?{androidSnapshot:e.androidSnapshot}:{},...e.quality?{snapshotQuality:e.quality}:{},...e.warnings&&e.warnings.length>0?{warnings:e.warnings}:{}}}function C(e){let t=te(e.androidSnapshot),n=Array.isArray(e.warnings)?e.warnings.filter(e=>typeof e==`string`):void 0,r=w(e.snapshotQuality);return S({...t?{androidSnapshot:t}:{},...r?{quality:r}:{},...n?{warnings:n}:{}})}function w(e){if(!e||typeof e!=`object`)return;let t=e;return typeof t.state==`string`&&typeof t.backend==`string`?t:void 0}function te(e){return typeof e==`object`&&e?e:void 0}const T=1500;function E(e,t){e&&(e.snapshotDiagnostics??={samples:[]}).samples.push({...t,durationMs:Math.max(0,Math.round(t.durationMs))})}function D(e){let t=e?.snapshotDiagnostics?.samples;if(!(!t||t.length===0))return O(t)}function O(e){if(e.length===0)return;let t=e.slice(1),n=t.length>=3?j(t):void 0,r=t.filter(e=>e.durationMs>=T).length,i=n!==void 0&&n.p95Ms>=T&&r>=2;return{stats:j(e),...i&&n?{warning:F(n)}:{}}}function k(e){let t=e.filter(e=>e!==void 0),n=t.flatMap(e=>ne(e.stats));if(n.length===0)return;let r=j(n),i=t.filter(e=>e.warning);return{stats:r,...i.length>0?{warning:I({warnedCount:i.length,totalCount:t.length,worst:i.reduce((e,t)=>Math.max(e,t.stats.p95Ms),0),platform:r.platform})}:{}}}function A(e){if(!t(e))return;let n=L(e.stats);if(!n)return;let r=typeof e.warning==`string`?e.warning:void 0;return{stats:n,...r?{warning:r}:{}}}function j(e){let t=e.map(e=>e.durationMs).sort((e,t)=>e-t);return{count:t.length,p50Ms:M(t,50),p95Ms:M(t,95),maxMs:t[t.length-1]??0,slowThresholdMs:T,...N(e),...P(e)}}function M(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 N(e){let t=e.map(e=>e.platform).filter(e=>!!e);return new Set(t).size===1?{platform:t[0]}:{}}function P(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 F(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 I(e){return`Warning: ${e.platform?`${e.platform} `:``}snapshots were slow in ${e.warnedCount} of ${e.totalCount} runs (worst run p95 ${e.worst}ms). Possible causes: device load, app or dev server stuck, helper fallback, or stale daemon.`}function L(e){if(!t(e))return;let n=R(e);if(n)return{...n,...B(e)}}function R(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 z(e){let t=Object.entries(e).filter(e=>typeof e[1]==`number`);return t.length>0?Object.fromEntries(t):void 0}function B(e){let n=typeof e.platform==`string`?e.platform:void 0,r=t(e.backends)?z(e.backends):void 0;return{...n?{platform:n}:{},...r?{backends:r}:{}}}function ne(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}]}const V=[`camera`,`microphone`,`photos`,`contacts`,`contacts-limited`,`notifications`,`calendar`,`location`,`location-always`,`media-library`,`motion`,`reminders`,`siri`],H=`<wifi|airplane|location> <on|off>`,U=`location set <lat> <lon>`,W=`animations <on|off>`,G=`appearance <light|dark|toggle>`,K=`faceid <match|nonmatch|enroll|unenroll>`,q=`touchid <match|nonmatch|enroll|unenroll>`,J=`fingerprint <match|nonmatch>`,Y=`clear-app-state [app-id]`,X=`permission <grant|deny|reset> <camera|microphone|photos|contacts|contacts-limited|notifications|calendar|location|location-always|media-library|motion|reminders|siri> [full|limited]`,Z=`permission <grant|reset> <accessibility|screen-recording|input-monitoring>`,re=`macOS supports only settings ${G} and settings ${Z}. wifi|airplane|location|animations remain unsupported on macOS.`,ie=[`settings ${H}`,`settings ${U}`,`settings ${W}`,`settings ${G}`,`settings ${K}`,`settings ${q}`,`settings ${J}`,`settings ${Y}`,`settings ${X}`,`settings ${Z}`].join(` | `),ae=`settings requires ${H}, ${U}, ${W}, ${G}, ${K}, ${q}, ${J}, ${Y}, ${X}, or ${Z}`;function oe(e){let t=e.trim().toLowerCase();return t===`appearance`||t===`permission`}function se(e){return`Unsupported macOS setting: ${e}. ${re}`}function Q(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 ce(t){let n=t?.trim().toLowerCase();if(n===`camera`||n===`microphone`||n===`photos`||n===`contacts`||n===`contacts-limited`||n===`notifications`||n===`calendar`||n===`location`||n===`location-always`||n===`media-library`||n===`motion`||n===`reminders`||n===`siri`)return n;throw new e(`INVALID_ARGS`,`permission setting requires a target: ${V.join(`|`)}`)}function le(t,n){if(t===void 0||t.trim()===``)throw new e(`INVALID_ARGS`,`settings location set requires ${n}`);return $(Number(t),n)}function ue(e){return{latitude:$(e?.latitude,`latitude`),longitude:$(e?.longitude,`longitude`)}}function $(t,n){let r=n===`latitude`?-90:-180,i=n===`latitude`?90:180;if(typeof t!=`number`||!Number.isFinite(t)||t<r||t>i)throw new e(`INVALID_ARGS`,`${n} must be a number from ${r} to ${i}`);return t}export{g as C,d as D,p as E,a as O,h as S,f as T,r as _,se as a,n as b,ce as c,E as d,D as f,x as g,C as h,ie as i,m as k,k as l,S as m,ue as n,oe as o,O as p,ae as r,Q as s,le as t,A as u,s as v,i as w,c as x,o as y};
|
package/dist/src/logcat.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{n as e}from"./rolldown-runtime.js";import{n as t}from"./sdk-android-adb.js";var n=e({captureAndroidLogcatWithAdb:()=>r});async function r(e,n={}){let r=[`logcat`,`-d`,`-v`,`time`];n.lines!==void 0&&r.push(`-t`,String(Math.max(1,Math.floor(n.lines))));let i=await e(r,{allowFailure:!0,timeoutMs:n.timeoutMs,signal:n.signal});if(i.exitCode!==0)throw t(`Failed to capture Android logcat`,i);return i.stdout}export{n,r as t};
|
package/dist/src/manifest.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{_ as e,m as t}from"./sdk-android-adb.js";import{t as n}from"./sdk.js";import r from"node:path";import{TextDecoder as i}from"node:util";import a from"node:fs/promises";const o=new i(`utf-16le`);let s;async function c(e,t){for(let n of[`AndroidManifest.xml`,`base/manifest/AndroidManifest.xml`]){let r=await l(e,n,t);if(!r)continue;let i=u(r);if(i)return i}return await y(e,t)}async function l(t,n,r){try{let i=await e(`unzip`,[`-p`,t,n],{allowFailure:!0,binaryStdout:!0,signal:r});return i.exitCode!==0||!i.stdoutBuffer||i.stdoutBuffer.length===0?void 0:i.stdoutBuffer}catch{r?.throwIfAborted();return}}function u(e){return e.subarray(0,Math.min(e.length,128)).toString(`utf8`).trimStart().startsWith(`<`)?d(e.toString(`utf8`)):f(e)}function d(e){return e.match(/<manifest\b[^>]*\bpackage\s*=\s*["']([^"']+)["']/i)?.[1]}function f(e){if(e.length<8||e.readUInt16LE(0)!==3)return;let t;for(let n=e.readUInt16LE(2);n+8<=e.length;){let r=e.readUInt16LE(n),i=e.readUInt16LE(n+2),a=e.readUInt32LE(n+4);if(a<=0||n+a>e.length)return;if(r===1)t=m(e.subarray(n,n+a));else if(r===258&&t){let r=p(e,n,i,t);if(r)return r}n+=a}}function p(e,t,n,r){if(n<36||t+n>e.length||r[e.readUInt32LE(t+20)]!==`manifest`)return;let i=e.readUInt16LE(t+24),a=e.readUInt16LE(t+26),o=e.readUInt16LE(t+28),s=t+i;for(let t=0;t<o;t+=1){let n=s+t*a;if(n+20>e.length)return;if(r[e.readUInt32LE(n+4)]!==`package`)continue;let i=e.readUInt32LE(n+8);if(i!==4294967295)return r[i];let o=e.readUInt8(n+15),c=e.readUInt32LE(n+16);return o===3?r[c]:void 0}}function m(e){if(e.length<28)return[];let t=e.readUInt32LE(8),n=e.readUInt32LE(16),r=e.readUInt32LE(20),i=(n&256)!=0,a=[];for(let n=0;n<t;n+=1){let t=28+n*4;if(t+4>e.length)return a;let o=r+e.readUInt32LE(t);a.push(i?h(e,o):g(e,o))}return a}function h(e,t){let[,n]=_(e,t),[r,i]=_(e,t+n),a=t+n+i;return e.subarray(a,a+r).toString(`utf8`)}function g(e,t){let[n,r]=v(e,t),i=t+r;return o.decode(e.subarray(i,i+n*2))}function _(e,t){let n=e.readUInt8(t);if(!(n&128))return[n,1];let r=e.readUInt8(t+1);return[(n&127)<<8|r,2]}function v(e,t){let n=e.readUInt16LE(t);if(!(n&32768))return[n,2];let r=e.readUInt16LE(t+2);return[(n&32767)<<16|r,4]}async function y(t,n){n?.throwIfAborted();let r=await b();if(!r)return;let i=await e(r,[`dump`,`badging`,t],{allowFailure:!0,signal:n});if(i.exitCode===0)return i.stdout.match(/package:\s+name='([^']+)'/)?.[1]}async function b(){if(s!==void 0)return s??void 0;try{for(let e of n()){let n=r.join(e,`build-tools`);try{let e=(await a.readdir(n)).sort((e,t)=>t.localeCompare(e,void 0,{numeric:!0}));for(let i of e){let e=r.join(n,i,`aapt`);if(r.isAbsolute(e)&&await t(e))return s=e,e}}catch{}}}catch{}s=null}export{c as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{t as e}from"./string-enum.js";const t=[`path`,`start`,`stop`,`doctor`,`mark`,`clear`],n=[`metrics`,`frames`,`memory`,`cpu`,`trace`],r=[`sample`,`snapshot`,`start`,`stop`,`report`],i=[`profile`],a=[`xctrace`,`simpleperf`,`perfetto`,`android-hprof`,`memgraph`],o=[`android-hprof`,`memgraph`],s=e(n),c=e(r),l=e(i),u=e(a),d=e(o),f=`perf area must be metrics, frames, memory, cpu, or trace`,p=`perf action must be sample, snapshot, start, stop, or report`,m=`perf cpu requires profile`,h=`perf --kind must be xctrace, simpleperf, perfetto, android-hprof, or memgraph`,g=`perf memory snapshot --kind must be android-hprof or memgraph`,_=s.is,v=c.is,y=l.is,b=u.is,x=d.is;export{h as a,m as c,_ as d,b as f,t as h,n as i,i as l,y as m,r as n,a as o,x as p,f as r,g as s,p as t,v as u};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c as e,i as t,n}from"./host-process.js";import r from"node:fs";function i(){return{pid:process.pid,startTime:e(process.pid)}}function a(e,t){return e.pid===t.pid&&e.startTime===t.startTime}function o(e){return s(e)}function s(i,a){let{owner:o,stateDir:s}=i;if(!n(o.pid)||(a===void 0?t(o.pid):a?.state.startsWith(`Z`)))return`owner-process-dead`;if(o.startTime){let t=a===void 0?e(o.pid):a?.startTime??null;if(t!==null&&t!==o.startTime)return`owner-process-
|
|
1
|
+
import{c as e,i as t,n}from"./host-process.js";import r from"node:fs";function i(){return{pid:process.pid,startTime:e(process.pid)}}function a(e,t){return e.pid===t.pid&&e.startTime===t.startTime}function o(e){return s(e)}function s(i,a){let{owner:o,stateDir:s}=i;if(!n(o.pid)||(a===void 0?t(o.pid):a?.state.startsWith(`Z`)))return`owner-process-dead`;if(o.startTime){let t=a===void 0?e(o.pid):a?.startTime??null;if(t!==null&&t!==o.startTime)return`owner-process-reused`}if(!s)return`live`;try{return r.statSync(s),`live`}catch(e){let t=e?.code;return t===`ENOENT`||t===`ENOTDIR`?`owner-state-dir-gone`:`unknown`}}export{i,s as n,a as r,o as t};
|
package/dist/src/perf.js
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{n as e}from"./rolldown-runtime.js";import{_ as t}from"./sdk-contracts.js";import{zr as n}from"./sdk-batch-runner.js";import{h as r,n as i,o as a}from"./sdk-android-adb.js";import{t as o}from"./timeouts.js";import s from"node:path";import{promises as c}from"node:fs";function l(e){return Math.round(e*10)/10}function u(e){return l(e)}function d(e){let t=e.replaceAll(`,`,``).match(/^-?\d+(?:\.\d+)?/);if(!t)return null;let n=Number(t[0]);return Number.isFinite(n)?n:null}function f(e){let t=ne(e.map(e=>e.intendedVsyncNs)),n=[];for(let e=1;e<t.length;e+=1){let r=t[e]-t[e-1];r>=4e6&&r<=5e7&&n.push(r)}if(n.length!==0)return re(n)}function p(e){let{frames:t,frameDeadlineNs:n,summaryDroppedFrameCount:r}=e;return r===void 0?n===void 0?[]:t.filter(e=>e.durationNs>n):r<=0?[]:[...t].sort((e,t)=>t.durationNs-e.durationNs).slice(0,r).sort((e,t)=>e.intendedVsyncNs-t.intendedVsyncNs)}function ee(e){let{frames:t,windowStartNs:n,measuredAtMs:r,uptimeMs:i}=e;if(t.length===0||n===void 0)return[];let a=[],o=[];for(let e of t){let t=o.at(-1);if(!t||e.intendedVsyncNs-t.frameCompletedNs<=5e8){o.push(e);continue}a.push(o),o=[e]}return o.length>0&&a.push(o),a.map(e=>te({frames:e,windowStartNs:n,measuredAtMs:r,uptimeMs:i})).sort((e,t)=>t.missedDeadlineFrameCount-e.missedDeadlineFrameCount||t.worstFrameMs-e.worstFrameMs).slice(0,3).sort((e,t)=>e.startOffsetMs-t.startOffsetMs)}function m(e){return Math.round(e*10)/10}function te(e){let{frames:t,windowStartNs:n,measuredAtMs:r,uptimeMs:i}=e,a=Math.min(...t.map(e=>e.intendedVsyncNs)),o=Math.max(...t.map(e=>e.frameCompletedNs)),s=Math.max(0,Math.round((a-n)/1e6)),c=Math.max(s,Math.round((o-n)/1e6)),l=i!==void 0&&Number.isFinite(r)?r-i:void 0;return{startOffsetMs:s,endOffsetMs:c,startAt:l===void 0?void 0:new Date(l+a/1e6).toISOString(),endAt:l===void 0?void 0:new Date(l+o/1e6).toISOString(),missedDeadlineFrameCount:t.length,worstFrameMs:m(Math.max(...t.map(e=>e.durationNs))/1e6)}}function ne(e){return[...new Set(e.filter(e=>Number.isFinite(e)))].sort((e,t)=>e-t)}function re(e){let t=[...e].sort((e,t)=>e-t),n=Math.floor(t.length/2);return t.length%2==1?t[n]:(t[n-1]+t[n])/2}const h=`adb-shell-dumpsys-gfxinfo-framestats`,g=`Rendered-frame health from the current adb shell dumpsys gfxinfo <package> framestats window. Dropped frames use Android gfxinfo janky-frame/frame-deadline data when available; this is not video recording FPS.`;function ie(e,t,n){_(e,t);let r=pe(e),i=ue(e),a=oe(i,r,t),o=Date.parse(n),s=he({frames:i,measuredAtMs:o,summary:r}),c=p({frames:i,frameDeadlineNs:a,summaryDroppedFrameCount:r?.droppedFrameCount}),l=r?.sampleWindowMs??s.sampleWindowMs??x(i),u=se(r,i,c),d=le({droppedFrames:c,timing:s,measuredAtMs:o,summary:r});return{...u,sampleWindowMs:l,...ce(a),windowStartedAt:s.windowStartedAt,windowEndedAt:s.windowEndedAt,timestampSource:s.timestampSource,measuredAt:n,method:h,source:r?`android-gfxinfo-summary`:`framestats-rows`,worstWindows:d&&d.length>0?d:void 0}}function _(e,n){if(/no process found for:/i.test(e))throw new t(`COMMAND_FAILED`,`Android gfxinfo did not find a running process for ${n}`,{metric:`fps`,package:n,hint:`Run open <app> for this session again to ensure the Android app is active, then retry perf after the interaction you want to inspect.`})}function ae(e){throw new t(`COMMAND_FAILED`,`Failed to parse Android framestats output for ${e}`,{metric:`fps`,package:e,hint:`Retry perf after exercising the app screen. If the problem persists, capture adb shell dumpsys gfxinfo <package> framestats output for debugging.`})}function oe(e,n,r){let i=f(e);if(!n&&e.length===0&&ae(r),n||i!==void 0)return i;throw new t(`COMMAND_FAILED`,`Failed to infer Android frame deadline from framestats output for ${r}`,{metric:`fps`,package:r,hint:`Retry perf after a longer interaction window so consecutive Android frame timestamps are available.`})}function se(e,t,n){let r=e?.totalFrameCount??t.length,i=e?.droppedFrameCount??n.length;return{totalFrameCount:r,droppedFrameCount:i,droppedFramePercent:e?.droppedFramePercent??(r>0?l(i/r*100):0)}}function ce(e){return{frameDeadlineMs:e===void 0?void 0:m(e/1e6),refreshRateHz:e===void 0?void 0:m(1e9/e)}}function le(e){let{droppedFrames:t,timing:n,measuredAtMs:r,summary:i}=e;if(t.length===0)return;let a=ee({frames:t,windowStartNs:n.windowStartNs,measuredAtMs:r,uptimeMs:i?.uptimeMs});return a.length>0?a:void 0}function ue(e){let t=[],n=null;for(let r of e.split(`
|
|
2
|
+
`)){let e=r.trim();if(e.length===0||e===`---PROFILEDATA---`)continue;let i=e.split(`,`).map(e=>e.trim());if(de(i)){n=new Map(i.map((e,t)=>[e,t]));continue}let a=fe(i,n);a&&t.push(a)}return t.sort((e,t)=>e.intendedVsyncNs-t.intendedVsyncNs)}function de(e){return e.includes(`IntendedVsync`)&&e.includes(`FrameCompleted`)}function fe(e,t){if(!t||e.length<t.size)return;let n=v(e,t,`Flags`),r=v(e,t,`IntendedVsync`),i=v(e,t,`FrameCompleted`);if(!(n!==0||r===null||i===null||r<=0||i<=r))return{intendedVsyncNs:r,frameCompletedNs:i,durationNs:i-r}}function v(e,t,n){let r=t.get(n);if(r===void 0)return null;let i=Number(e[r]);return Number.isFinite(i)?i:null}function pe(e){let t=e.split(/\nProfile data in ms:\n/i)[0]??``,n=S(t,`Total frames rendered`),r=t.match(/^\s*Janky frames:\s*([0-9][0-9,]*)\s*\(([0-9.]+)%\)/im);if(n===void 0||!r)return;let i=r[1],a=r[2];if(i===void 0||a===void 0)return;let o=d(i)??void 0,s=Number(a);if(o===void 0||!Number.isFinite(s)||n<0)return;let c=S(t,`Uptime`),u=S(t,`Stats since`);return{droppedFramePercent:l(s),droppedFrameCount:o,totalFrameCount:n,sampleWindowMs:me({uptimeMs:c,statsSinceNs:u}),uptimeMs:c,statsSinceNs:u}}function me(e){let{uptimeMs:t,statsSinceNs:n}=e;if(t===void 0||n===void 0)return;let r=t-Math.round(n/1e6);return r>=0?r:void 0}function he(e){let{frames:t,measuredAtMs:n,summary:r}=e,i=y(t),a=r?.statsSinceNs,o=a??i.firstFrameNs,s=b(o,i.lastFrameNs),c=r?.sampleWindowMs??s;if(!Number.isFinite(n)||r?.uptimeMs===void 0||o===void 0)return{sampleWindowMs:c,windowStartNs:o};let l=n-r.uptimeMs;return{sampleWindowMs:c,windowStartNs:o,windowStartedAt:new Date(l+o/1e6).toISOString(),windowEndedAt:ge({deviceBootWallClockMs:l,measuredAtMs:n,summaryStartNs:a,lastFrameNs:i.lastFrameNs}),timestampSource:`estimated-from-device-uptime`}}function y(e){return e.length===0?{}:{firstFrameNs:Math.min(...e.map(e=>e.intendedVsyncNs)),lastFrameNs:Math.max(...e.map(e=>e.frameCompletedNs))}}function b(e,t){if(!(e===void 0||t===void 0))return Math.max(0,Math.round((t-e)/1e6))}function ge(e){let{deviceBootWallClockMs:t,measuredAtMs:n,summaryStartNs:r,lastFrameNs:i}=e;return r===void 0?i===void 0?void 0:new Date(t+i/1e6).toISOString():new Date(n).toISOString()}function x(e){if(e.length===0)return;let t=y(e);return b(t.firstFrameNs,t.lastFrameNs)}function S(e,t){let n=t.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`),r=e.match(RegExp(`^\\s*${n}:\\s*([0-9][0-9,]*)`,`im`));if(!r)return;let i=r[1];return i===void 0?void 0:d(i)??void 0}async function C(e,t,n={}){let r=a(e,n.adb);try{let i=ie((await r([`shell`,`dumpsys`,`gfxinfo`,t,`framestats`],{timeoutMs:15e3})).stdout,t,new Date().toISOString());return await w(e,t,n),i}catch(e){throw _e(t,e)}}async function w(e,t,n={}){let r=a(e,n.adb);try{await r([`shell`,`dumpsys`,`gfxinfo`,t,`reset`],{allowFailure:!0,timeoutMs:3e3})}catch{}}function _e(e,n){return n instanceof t?new t(n.code,n.message,{...n.details??{},metric:`fps`,package:e},n):new t(`COMMAND_FAILED`,`Failed to sample Android fps for ${e}`,{metric:`fps`,package:e},n)}function T(e,n,r,i){if(i instanceof t){let a=i.details??{};return new t(i.code,i.message,{...a,action:e,package:r,tool:n,hint:typeof a.hint==`string`?a.hint:ye(n,a)},i)}return new t(`COMMAND_FAILED`,`Failed to ${e} Android ${n} for ${r}`,{action:e,package:r,tool:n,hint:E(n)},i)}function E(e){return e===`simpleperf`?`Verify simpleperf is available, the app process is running, and the app/device permits native CPU profiling.`:`Verify perfetto is available, the app process is running, and the device permits trace capture.`}function ve(e){return e===`simpleperf`?`Use an emulator/system image with simpleperf available, or install the Android NDK simpleperf binary for this device.`:`Use Android 10+ or a system image that exposes the perfetto command-line binary.`}function ye(e,t){let n=(typeof t.stderr==`string`?t.stderr:``).toLowerCase();return e===`simpleperf`?be(n):Se(n)?`Use a device image that permits perfetto trace capture for shell, keep the app running, then retry perf trace start.`:E(e)}function be(e){return xe(e)?`Use a debuggable/profileable Android app or a device image that permits simpleperf for the target process, then retry perf cpu profile start.`:e.includes(`not supported`)||e.includes(`failed to open perf event`)?`This device image does not expose the requested simpleperf event for the app process. Try a different emulator/system image or a profileable app.`:E(`simpleperf`)}function xe(e){return e.includes(`permission denied`)||e.includes(`not profileable`)||e.includes(`profileable`)}function Se(e){return e.includes(`permission denied`)||e.includes(`not allowed`)}async function Ce(e,t,n,r,i){return{capture:{durationMs:r,packageName:t.packageName,appPid:t.appPid,artifactPath:t.outPath,sizeBytes:n},frameHealth:t.kind===`perfetto`?await we(e,t.packageName,i):void 0,notes:[t.kind===`perfetto`?`Frame health is sampled from Android gfxinfo around the trace window; open the Perfetto artifact for timeline root cause.`:`Open the Simpleperf report artifact for symbol-level CPU attribution.`]}}async function we(e,t,n){try{let r=await C(e,t,n);return{available:!0,droppedFramePercent:r.droppedFramePercent,droppedFrameCount:r.droppedFrameCount,totalFrameCount:r.totalFrameCount,method:r.method,worstWindows:r.worstWindows?.slice(0,3).map(e=>({startOffsetMs:e.startOffsetMs,endOffsetMs:e.endOffsetMs,missedDeadlineFrameCount:e.missedDeadlineFrameCount,worstFrameMs:e.worstFrameMs}))}}catch(e){return{available:!1,reason:e instanceof Error?e.message:`Android frame health was not available`}}}const D=`adb-shell-simpleperf`,O=`adb-shell-perfetto`,k=15e3,A=3e4,j=`/data/local/tmp`;async function M(e,t,n){let r=a(e,n.adb);await L(r,t),await R(r,t),await Oe(r,t);let i=await F(t.outPath);await P(r,t.remotePath);let o=Date.now(),s=Math.max(0,o-t.startedAt),c=await Ce(e,t,i,s,{adb:r});return{...t,action:`stop`,platform:`android`,state:`stopped`,stoppedAt:o,durationMs:s,sizeBytes:i,method:t.kind===`simpleperf`?D:O,artifact:{path:t.outPath,sizeBytes:i},summary:c,message:`Stopped Android ${t.kind} ${t.type} for ${t.packageName}`}}async function Te(e,t,n={}){let r=a(e,n.adb);try{t.state===`running`&&(await L(r,t),await R(r,t).catch(()=>{}))}finally{await P(r,t.remotePath)}}function N(e,t,n=j){return`${n}/agent-device-${e.replace(/[^A-Za-z0-9_.-]/g,`_`)}-${Date.now()}-${t}`}async function P(e,t){try{await e([`shell`,`rm -f ${I(t)}`],{allowFailure:!0,timeoutMs:k})}catch{}}async function Ee(e,t){await c.mkdir(s.dirname(e),{recursive:!0}),await c.writeFile(e,`${JSON.stringify(t,null,2)}\n`)}async function F(e){try{return(await c.stat(e)).size}catch(n){throw new t(`COMMAND_FAILED`,`Profiler artifact was not written: ${e}`,{outPath:e,hint:`Retry the profiling command and check daemon logs if the artifact path is still missing.`},n)}}function I(e){return`'${e.replace(/'/g,`'\\''`)}'`}async function L(e,t){try{await e([`shell`,De(t.profilerPid)],{timeoutMs:A})}catch(e){throw T(`stop`,t.kind,t.packageName,e)}}function De(e){return[`pid=${I(e)}`,`kill -INT "$pid" 2>/dev/null || true`,`for i in 1 2 3 4 5 6 7 8 9 10; do kill -0 "$pid" 2>/dev/null || exit 0; sleep 0.2; done`,`kill -TERM "$pid" 2>/dev/null || true`,`for i in 1 2 3 4 5 6 7 8 9 10; do kill -0 "$pid" 2>/dev/null || exit 0; sleep 0.2; done`,`echo "profiler process did not stop after SIGTERM" >&2`,`exit 1`].join(`; `)}async function Oe(e,n){await c.mkdir(s.dirname(n.outPath),{recursive:!0});try{await e([`pull`,n.remotePath,n.outPath],{timeoutMs:A})}catch(e){throw new t(`COMMAND_FAILED`,`Failed to pull Android ${n.kind} artifact for ${n.packageName}`,{package:n.packageName,tool:n.kind,remotePath:n.remotePath,outPath:n.outPath,hint:`Check that the profiling command ran long enough to create an artifact, then retry stop with the same session.`},e)}}async function R(e,n){let r;for(let t=0;t<12;t+=1){let t=await ke(e,n.remotePath);if(t!==void 0&&t>0&&t===r)return;r=t,await o(250)}throw new t(`COMMAND_FAILED`,`Android ${n.kind} artifact is not ready to pull`,{package:n.packageName,tool:n.kind,remotePath:n.remotePath,hint:`The profiler stopped, but the remote artifact was missing, empty, or still changing. Retry stop with the same session or inspect the device-side artifact.`})}async function ke(e,t){let n=I(t),r=await e([`shell`,`if [ -f ${n} ]; then stat -c %s ${n} 2>/dev/null || wc -c < ${n}; fi`],{allowFailure:!0,timeoutMs:k});if(r.exitCode!==0)return;let i=Number(r.stdout.trim().split(/\s+/)[0]);return Number.isFinite(i)?i:void 0}async function z(e,n){try{let t=await e([`shell`,`pidof`,n],{allowFailure:!0,timeoutMs:k}),r=V(t.stdout);if(t.exitCode===0&&r)return r}catch{}throw new t(`COMMAND_FAILED`,`No active Android app process found for ${n}`,{package:n,hint:`Run open <app> for this session again, wait for the app UI to appear, then retry perf.`})}async function B(e,n,r){let i=await e([`shell`,`command -v ${n} || which ${n}`],{allowFailure:!0,timeoutMs:k});if(!(i.exitCode===0&&i.stdout.trim()))throw new t(`UNSUPPORTED_OPERATION`,`Android device does not expose ${n}`,{package:r,tool:n,hint:ve(n)})}function V(e){return e.trim().split(/\s+/).find(e=>/^\d+$/.test(e))}async function H(e,t,n,r={}){let i=a(e,r.adb),o=await z(i,t);await B(i,`perfetto`,t);let s=N(t,`app.perfetto-trace`,`/data/misc/perfetto-traces`),c;try{await w(e,t,{adb:i}),c=await je(i,s,t)}catch(e){throw await P(i,s),e}return{type:`trace`,kind:`perfetto`,packageName:t,appPid:o,profilerPid:c,remotePath:s,outPath:n,startedAt:Date.now(),state:`running`,action:`start`,platform:`android`,method:O,message:`Started Android Perfetto trace for ${t}`}}async function Ae(e,t,n,r={}){return await M(e,{...t,outPath:n},r)}async function je(e,n,r){try{let i=V((await e([`shell`,`perfetto`,`--background-wait`,`-o`,n,`-t`,`3600s`,`sched`,`freq`,`idle`,`am`,`wm`,`gfx`,`view`,`binder_driver`,`hal`,`dalvik`],{timeoutMs:A})).stdout);if(i)return i;throw new t(`COMMAND_FAILED`,`Android perfetto did not return a profiler pid`,{package:r,tool:`perfetto`,hint:`Retry perf trace start. If perfetto exits immediately, verify the device permits trace capture.`})}catch(e){throw T(`start`,`perfetto`,r,e)}}function Me(e){let t=[];for(let r of n(e)){let e=r.match(/^([0-9]+(?:\.[0-9]+)?)%\s+(.+)$/);if(!e)continue;let n=Number(e[1]),i=e[2]?.trim();if(!Number.isFinite(n)||!i)continue;let a=i.split(/\s{2,}/).filter(Boolean);if(t.push({percentage:l(n),command:a[0],dso:a[1],symbol:a.slice(2).join(` `)||void 0}),t.length>=50)break}return t}async function Ne(e,t,n,r={}){let i=a(e,r.adb),o=await z(i,t);await B(i,`simpleperf`,t);let s=N(t,`cpu.perf.data`),c;try{c=await Ie(i,o,s,t)}catch(e){throw await P(i,s),e}return{type:`cpu-profile`,kind:`simpleperf`,packageName:t,appPid:o,profilerPid:c,remotePath:s,outPath:n,startedAt:Date.now(),state:`running`,action:`start`,platform:`android`,method:D,message:`Started Android Simpleperf CPU profile for ${t}`}}async function Pe(e,t,n,r={}){return await M(e,{...t,outPath:n},r)}async function Fe(e,t,n,r={}){let i=a(e,r.adb);await B(i,`simpleperf`,t.packageName);let o=await ze(i,t),s=new Date().toISOString(),c=Me(o.stdout),l=c.slice(0,10).map(e=>({symbol:e.symbol??`<unknown>`,binary:e.dso,selfSamplePercent:e.percentage}));await Ee(n,{kind:`simpleperf-report`,generatedAt:s,packageName:t.packageName,appPid:t.appPid,sourceProfilePath:t.outPath,sourceRemotePath:t.remotePath,entryCount:c.length,summary:{topFunctions:l},entries:c});let u=await F(n);return{action:`report`,platform:`android`,type:`cpu-profile-report`,kind:`simpleperf`,packageName:t.packageName,appPid:t.appPid,sourceProfilePath:t.outPath,outPath:n,sizeBytes:u,generatedAt:s,entryCount:c.length,summary:{topFunctions:l},method:D,message:`Wrote Android Simpleperf report for ${t.packageName}`}}async function Ie(e,n,r,i){try{let a=V((await e([`shell`,Le(n,r)],{timeoutMs:A})).stdout);if(a)return a;throw new t(`COMMAND_FAILED`,`Android simpleperf did not return a profiler pid`,{package:i,tool:`simpleperf`,hint:`Retry perf. If simpleperf exits immediately, verify the app is profileable and the device permits native profiling.`})}catch(e){throw T(`start`,`simpleperf`,i,e)}}function Le(e,t){return Re([`simpleperf`,`record`,`-e`,`cpu-clock:u`,`-p`,e,`-o`,t,`--duration`,`3600`],`simpleperf`)}function Re(e,t){let n=e.map(I).join(` `);return[`err=${I(`${j}/agent-device-${t}-${Date.now()}.err`)}`,`(${n}) >/dev/null 2>"$err" & pid=$!`,`sleep 1`,`if kill -0 "$pid" 2>/dev/null; then rm -f "$err"; echo "$pid"; exit 0; fi`,`cat "$err" >&2`,`rm -f "$err"`,`exit 1`].join(`; `)}async function ze(e,t){try{return await e([`shell`,`simpleperf`,`report`,`-i`,t.remotePath,`--stdio`,`--sort`,`comm,dso,symbol`],{timeoutMs:A})}catch(e){throw T(`report`,`simpleperf`,t.packageName,e)}}var Be=e({ANDROID_FRAME_SAMPLE_DESCRIPTION:()=>g,ANDROID_FRAME_SAMPLE_METHOD:()=>h,ANDROID_HPROF_SNAPSHOT_DESCRIPTION:()=>K,ANDROID_HPROF_SNAPSHOT_METHOD:()=>G,ANDROID_MEMORY_SAMPLE_DESCRIPTION:()=>W,ANDROID_MEMORY_SAMPLE_METHOD:()=>U,captureAndroidHeapSnapshot:()=>X,parseAndroidMemInfoSample:()=>Q,resetAndroidFramePerfStats:()=>w,sampleAndroidMemoryPerf:()=>Y});const U=`adb-shell-dumpsys-meminfo`,W=`Memory snapshot from adb shell dumpsys meminfo <package>. Values are reported in kilobytes.`,G=`adb-shell-am-dumpheap`,K=`Java heap dump captured with adb shell am dumpheap, pulled to a local artifact path.`,q=15e3,J=12e4;async function Y(e,t,n={}){let r=a(e,n.adb);try{return Q((await r([`shell`,`dumpsys`,`meminfo`,t],{timeoutMs:q})).stdout,t,new Date().toISOString())}catch(e){throw Ye(`memory`,t,e)}}async function X(e,n,o,l={}){let u=a(e,l.adb),d=await He(u,n),f=Ue(n);await c.mkdir(s.dirname(o),{recursive:!0});let p=await Ve(o);try{r(await u([`shell`,`am`,`dumpheap`,n,f],{allowFailure:!0,timeoutMs:J}),`Failed to capture Android heap dump for ${n}`,e=>({kind:`android-hprof`,package:n,pid:d,remotePath:f,hint:We(e.stdout,e.stderr)}));let e=await u([`pull`,f,o],{allowFailure:!0,timeoutMs:J});if(e.exitCode!==0)throw await Z(o,p),i(`Failed to pull Android heap dump for ${n}`,e,{kind:`android-hprof`,package:n,pid:d,remotePath:f,path:o,hint:`Verify the daemon can write the requested --out path and retry. The heap dump stays on-device only until cleanup runs.`});let a=await c.stat(o).catch(()=>null);if(!a?.isFile()||a.size<=0)throw await Z(o,p),new t(`COMMAND_FAILED`,`Android heap dump artifact is missing or empty`,{kind:`android-hprof`,package:n,pid:d,path:o,remotePath:f,hint:`Retry with a writable --out path. If the file is still empty, inspect adb pull output with --debug.`});return{available:!0,kind:`android-hprof`,path:o,sizeBytes:a.size,measuredAt:new Date().toISOString(),method:G,packageName:n,pid:d,remotePath:f}}finally{await u([`shell`,`rm`,`-f`,f],{allowFailure:!0,timeoutMs:q}).catch(()=>{})}}async function Ve(e){return await c.stat(e).then(e=>e.isFile()).catch(()=>!1)}async function Z(e,t){t||await c.rm(e,{force:!0}).catch(()=>{})}function Q(e,n,r){if(/no process found for:/i.test(e))throw new t(`COMMAND_FAILED`,`Android meminfo did not find a running process for ${n}`,{metric:`memory`,package:n,hint:`Run open <app> for this session again to ensure the Android app is active, then retry perf.`});let i=$(e,`TOTAL PSS`)??Xe(e);if(i===void 0)throw new t(`COMMAND_FAILED`,`Failed to parse Android meminfo output for ${n}`,{metric:`memory`,package:n,hint:`Retry perf after reopening the app session. If the problem persists, capture adb shell dumpsys meminfo output for debugging.`});return{totalPssKb:i,totalRssKb:$(e,`TOTAL RSS`),measuredAt:r,method:U,topConsumers:Ge(e)}}async function He(e,n){let r=await e([`shell`,`pidof`,n],{allowFailure:!0,timeoutMs:q}),i=r.stdout.trim().split(/\s+/).map(e=>Number(e)).find(e=>Number.isInteger(e)&&e>0);if(r.exitCode===0&&i!==void 0)return i;throw new t(`COMMAND_FAILED`,`No running Android process found for ${n}`,{kind:`android-hprof`,package:n,stdout:r.stdout,stderr:r.stderr,hint:`Run open <app> for this session again to ensure the Android app is active, then retry perf memory snapshot.`})}function Ue(e){return`/data/local/tmp/agent-device-${e.replace(/[^a-zA-Z0-9._-]/g,`_`)}-${Date.now()}.hprof`}function We(e,t){let n=`${e}\n${t}`.toLowerCase();return n.includes(`profileable`)||n.includes(`debuggable`)||n.includes(`not allowed`)?`Android heap dumps require a debuggable/profileable app process on many devices. Use a debug/profileable build, reopen the app, then retry.`:n.includes(`permission`)||n.includes(`denied`)?`The device denied heap dump access. Use a debug/profileable build or a device image that permits app heap dumping.`:`Reopen the app to refresh the process, then retry perf memory snapshot. If it still fails, run with --debug and inspect adb am dumpheap output.`}function Ge(e){let t=e.split(`
|
|
3
|
+
`).flatMap(e=>Ke(e)??[]).sort((e,t)=>t.pssKb-e.pssKb).slice(0,5);return t.length>0?t:void 0}function Ke(e){let t=e.trim();if(qe(t))return;let n=t.match(/^(.+?)\s+([0-9][0-9,]*(?:\(\d+\))?)(?:\s|$)/);if(n)return Je(n[1],n[2])}function qe(e){if(!e||e.startsWith(`**`)||e.startsWith(`-`)||e.includes(`:`))return!0;let t=/^\S.+\s+\d/.test(e);return/^(pss|total|native|dalvik|unknown|app summary\b)/i.test(e)&&!t}function Je(e,t){let n=e?.trim(),r=t?d(t):null;if(!(!n||n===`TOTAL`||r===null||r<=0)&&!/^(pss|private|shared|heap|size|alloc|free)$/i.test(n))return{name:n,pssKb:r}}function Ye(e,n,r){return r instanceof t?new t(r.code,r.message,{...r.details??{},metric:e,package:n},r):new t(`COMMAND_FAILED`,`Failed to sample Android ${e} for ${n}`,{metric:e,package:n},r)}function $(e,t){let n=t.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`),r=e.match(RegExp(`${n}:\\s*([0-9][0-9,]*)`,`i`));if(!r)return;let i=r[1];return i===void 0?void 0:d(i)??void 0}function Xe(e){for(let t of e.split(`
|
|
4
|
+
`)){let e=t.trim();if(!/^TOTAL\b(?!\s+PSS:)/.test(e))continue;let n=e.split(/\s+/).slice(1).find(e=>d(e)!==null);return n?d(n)??void 0:void 0}}export{u as _,X as a,Ne as c,H as d,Ae as f,h as g,g as h,U as i,Pe as l,C as m,G as n,Be as o,Te as p,W as r,Y as s,K as t,Fe as u,l as v};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{o as e}from"./png-worker-contract.js";import{_ as t}from"./sdk-contracts.js";import{n,t as r}from"./version.js";import{c as i,l as a,s as o,v as s}from"./sdk-device.js";import{C as ee,f as c,j as te}from"./sdk-android-adb.js";import{a as ne,i as re}from"./boot-diagnostics.js";import{a as l,s as ie}from"./tool-provider.js";import u from"node:path";import d from"node:crypto";import f,{promises as p}from"node:fs";import m from"node:os";function h(e){return e?.trim()||void 0}function g(e){return h(e)}function _(e){return new Set(e.split(/[\s,]+/).map(e=>e.trim()).filter(Boolean))}function ae(e,t=process.env){let n=h(e)??h(t.AGENT_DEVICE_ANDROID_DEVICE_ALLOWLIST);if(n)return _(n)}var oe=e({buildSimctlArgs:()=>v,buildSimctlArgsForDevice:()=>y,runSimctlForDevice:()=>b});function v(e,t={}){let n=g(t.simulatorSetPath);return n?[`simctl`,`--set`,n,...e]:[`simctl`,...e]}function y(e,t){return!i(e)||e.kind!==`simulator`?[`simctl`,...t]:v(t,{simulatorSetPath:e.simulatorSetPath})}function b(e,t,n){return l(y(e,t),n)}const x={iOS:{sdkName:{simulator:`iphonesimulator`,device:`iphoneos`},derivedBaseName:{simulator:`ios-simulator`,device:`ios-device`},xctestrunHints:{simulator:{preferred:[`iphonesimulator`],disallowed:[`iphoneos`,`appletvos`,`appletvsimulator`,`macos`]},device:{preferred:[`iphoneos`],disallowed:[`iphonesimulator`,`appletvos`,`appletvsimulator`,`macos`]}}},tvOS:{sdkName:{simulator:`appletvsimulator`,device:`appletvos`},derivedBaseName:{simulator:`tvos-simulator`,device:`tvos-device`},xctestrunHints:{simulator:{preferred:[`appletvsimulator`],disallowed:[`appletvos`,`iphoneos`,`iphonesimulator`,`macos`]},device:{preferred:[`appletvos`],disallowed:[`appletvsimulator`,`iphoneos`,`iphonesimulator`,`macos`]}}},macOS:{sdkName:{simulator:`macosx`,device:`macosx`},derivedBaseName:{simulator:`macos`,device:`macos`},xctestrunHints:{simulator:{preferred:[`macos`],disallowed:[`iphoneos`,`iphonesimulator`,`appletvos`,`appletvsimulator`]},device:{preferred:[`macos`],disallowed:[`iphoneos`,`iphonesimulator`,`appletvos`,`appletvsimulator`]}}},visionOS:{sdkName:{simulator:`xrsimulator`,device:`xros`},derivedBaseName:{simulator:`visionos-simulator`,device:`visionos-device`},xctestrunHints:{simulator:{preferred:[`xrsimulator`],disallowed:[`xros`,`iphoneos`,`iphonesimulator`,`appletvos`,`appletvsimulator`,`macos`]},device:{preferred:[`xros`],disallowed:[`xrsimulator`,`iphoneos`,`iphonesimulator`,`appletvos`,`appletvsimulator`,`macos`]}}}};function S(e){if(!o(e.platform))throw new t(`UNSUPPORTED_PLATFORM`,`Unsupported platform for Apple runner: ${e.platform}`);return a(e)?`macOS`:s(e.target,e.appleOs)}function se(e,t){return x[e].sdkName[C(t)]}function ce(e){return x[S(e)].derivedBaseName[C(e.kind)]}function le(e){return x[S(e)].xctestrunHints[C(e.kind)]}function ue(e){let t=S(e);return t===`macOS`?`platform=macOS,arch=${w()}`:e.kind===`simulator`?`platform=${t} Simulator,id=${e.id}`:`platform=${t},id=${e.id}`}function de(e){let t=S(e);return t===`macOS`?`platform=macOS,arch=${w()}`:e.kind===`simulator`?`platform=${t} Simulator,id=${e.id}`:`generic/platform=${t}`}function fe(e){let t=S(e);return t===`macOS`?`platform=macOS,arch=${w()}`:e.kind===`simulator`?`generic/platform=${t} Simulator`:`generic/platform=${t}`}function C(e){return e===`simulator`?`simulator`:`device`}function w(){return process.arch===`arm64`?`arm64`:`x86_64`}const pe=new Set;function me(e={}){let t=new Map,n=e.now??(()=>Date.now()),r=e=>{e?.timer&&clearTimeout(e.timer)},i={get(e){let r=t.get(e);if(r){if(r.expiresAt!==void 0&&r.expiresAt<=n()){i.delete(e);return}return r.value}},set(i,a){r(t.get(i));let o=he(e.ttlMs,n),s={value:a,expiresAt:o};e.scheduleExpiry&&o!==void 0&&(s.timer=setTimeout(()=>{t.delete(i)},Math.max(0,o-n())),s.timer.unref?.()),t.set(i,s)},delete(e){let n=t.get(e);return n?(r(n),t.delete(e)):!1},clear(){for(let e of t.values())r(e);t.clear()}};return pe.add(i.clear),i}function he(e,t){if(!(e===void 0||!Number.isFinite(e)))return t()+Math.max(0,e)}const ge=u.join(`apple`,`runner`,`AgentDeviceRunner`),_e=u.join(`dist`,`apple`,`runner`,`AgentDeviceRunner`);function T(e){let t=u.join(e,ge);return f.existsSync(t)?t:u.join(e,_e)}function ve(e){return u.join(T(e),`AgentDeviceRunner.xcodeproj`)}const ye=u.join(m.homedir(),`.agent-device`,`apple-runner`),be=`.agent-device-runner-cache.json`,xe=[`-IDEPackageSupportDisableManifestSandbox=1`,`-IDEPackageSupportDisablePluginExecutionSandbox=1`,`ENABLE_USER_SCRIPT_SANDBOXING=NO`],E=me();function D(e){return e?.trim()??``}function O(e=process.env){return D(e.AGENT_DEVICE_IOS_BUNDLE_ID)||D(e.AGENT_DEVICE_IOS_RUNNER_APP_BUNDLE_ID)||`com.callstack.agentdevice.runner`}function k(e=process.env){return D(e.AGENT_DEVICE_IOS_RUNNER_TEST_BUNDLE_ID)||`${O(e)}.uitests`}function Se(e=process.env){let t=O(e),n=k(e);return Array.from(new Set([D(e.AGENT_DEVICE_IOS_RUNNER_CONTAINER_BUNDLE_ID),`${n}.xctrunner`,t].filter(e=>e.length>0)))}const Ce=Se(process.env);function we(e,t=r()){let i=S(e);return{schemaVersion:2,packageVersion:n(t),runnerSourceFingerprint:Ae(t),...Te(i,e.kind),platformName:i,deviceKind:e.kind,target:e.target??`mobile`,buildDestinationFamily:fe(e),runnerBundleBuildSettings:I(process.env),runnerSigningBuildSettings:F(process.env,e.kind===`device`,e),runnerPerformanceBuildSettings:L(),runnerSandboxBuildArgs:R()}}function Te(e,t){let n=Ee(A(`xcodebuild`,[`-version`])),r=se(e,t);return{xcodeVersion:n.version,xcodeBuildVersion:n.buildVersion,sdkName:r,sdkVersion:A(`xcrun`,[`--sdk`,r,`--show-sdk-version`]),sdkBuildVersion:A(`xcrun`,[`--sdk`,r,`--show-sdk-build-version`])}}function A(e,t){let n=JSON.stringify([e,t]),r=E.get(n);if(r!==void 0)return r;try{let r=ee(e,t,{allowFailure:!0,timeoutMs:5e3,maxBuffer:128*1024}),i=r.exitCode===0&&r.stdout.trim()||`unknown`;return E.set(n,i),i}catch{return E.set(n,`unknown`),`unknown`}}function Ee(e){return{version:e.match(/^Xcode\s+(.+)$/m)?.[1]?.trim()||`unknown`,buildVersion:e.match(/^Build version\s+(.+)$/m)?.[1]?.trim()||`unknown`}}function De(e,t){let n=process.env.AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH?.trim();if(n)return u.resolve(n);let r=ke(t),i=Oe(e);return u.join(i,r)}function Oe(e){return u.join(ye,`derived`,ce(e))}function ke(e){return`cache-${d.createHash(`sha256`).update(M(j(e))).digest(`hex`).slice(0,16)}`}function j(e){let{artifacts:t,packageVersion:n,...r}=e;return r}function M(e){return JSON.stringify(N(e))}function N(e){return Array.isArray(e)?e.map(e=>N(e)):!e||typeof e!=`object`?e:Object.fromEntries(Object.entries(e).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>[e,N(t)]))}const P=new Map;function Ae(e){let t=T(e),n=Me(t),r=je(t,n),i=P.get(t);if(i?.fileStatsFingerprint===r)return i.sourceFingerprint;let a=d.createHash(`sha256`);for(let e of n){let n=u.relative(t,e);a.update(n),a.update(`\0`),a.update(f.readFileSync(e)),a.update(`\0`)}let o=a.digest(`hex`);return P.set(t,{fileStatsFingerprint:r,sourceFingerprint:o}),o}function je(e,t){let n=d.createHash(`sha256`);for(let r of t){let t=u.relative(e,r),i=f.statSync(r);n.update(t),n.update(`\0`),n.update(String(i.size)),n.update(`\0`),n.update(String(Math.trunc(i.mtimeMs))),n.update(`\0`)}return n.digest(`hex`)}function Me(e){if(!f.existsSync(e))return[];let t=[],n=[e];for(;n.length>0;){let e=n.pop();for(let r of f.readdirSync(e,{withFileTypes:!0})){let i=u.join(e,r.name);if(r.isDirectory()){if(r.name===`xcuserdata`)continue;n.push(i);continue}r.isFile()&&Ne(r.name,i)&&t.push(i)}}return t.sort((e,t)=>e.localeCompare(t))}function Ne(e,t){return e===`project.pbxproj`?t.includes(`${u.sep}.xcodeproj${u.sep}`):[`.jpg`,`.json`,`.png`,`.swift`,`.m`,`.h`,`.plist`,`.entitlements`,`.xctestplan`,`.xcconfig`,`.storyboard`,`.xib`].includes(u.extname(e))}function Pe(e){return a(e)||e.kind===`device`?`-maximum-concurrent-test-device-destinations`:`-maximum-concurrent-test-simulator-destinations`}function F(e=process.env,t=!1,n={platform:`apple`}){if(a(n))return[`CODE_SIGNING_ALLOWED=NO`,`CODE_SIGNING_REQUIRED=NO`,`CODE_SIGN_IDENTITY=`,`DEVELOPMENT_TEAM=`];if(!t)return[];let r=e.AGENT_DEVICE_IOS_TEAM_ID?.trim()||``,i=e.AGENT_DEVICE_IOS_SIGNING_IDENTITY?.trim()||``,o=e.AGENT_DEVICE_IOS_PROVISIONING_PROFILE?.trim()||``,s=[`CODE_SIGN_STYLE=Automatic`];return r&&s.push(`DEVELOPMENT_TEAM=${r}`),i&&s.push(`CODE_SIGN_IDENTITY=${i}`),o&&s.push(`PROVISIONING_PROFILE_SPECIFIER=${o}`),s}function I(e=process.env){let t=O(e),n=k(e);return[`AGENT_DEVICE_IOS_RUNNER_APP_BUNDLE_ID=${t}`,`AGENT_DEVICE_IOS_RUNNER_TEST_BUNDLE_ID=${n}`]}function L(){return[`COMPILER_INDEX_STORE_ENABLE=NO`,`ENABLE_CODE_COVERAGE=NO`,`ONLY_ACTIVE_ARCH=YES`,`ENABLE_PREVIEWS=NO`,`ENABLE_DEBUG_DYLIB=NO`]}function R(){return[...xe,`OTHER_SWIFT_FLAGS=${Fe(process.env)}`]}function Fe(e){return ne(e.AGENT_DEVICE_XCUITEST_INCLUDE_UNIT_TESTS)?`$(inherited) -disable-sandbox -D AGENT_DEVICE_RUNNER_UNIT_TESTS`:`$(inherited) -disable-sandbox`}const Ie=18e4,Le=6e4,Re=6e4,ze=1e4,Be=15e3,Ve=2e4,He=15e3,z=2e4,Ue=1e3,We=5e3;async function B(e,n,r={}){let i=[`devicectl`,...e],a=await l(i,{allowFailure:!0,timeoutMs:r.timeoutMs??2e4});if(a.exitCode===0)return;let{stdout:o,stderr:s}=a;if(!r.tolerateOutput?.(o,s))throw new t(`COMMAND_FAILED`,`Failed to ${n.action}`,c(a,{cmd:`xcrun`,args:i,stdout:o,stderr:s,deviceId:n.deviceId,hint:q(o,s)??`Ensure the iOS device is unlocked, trusted, and available in Xcode > Devices, then retry.`}))}async function V(e,t){return Ze(Ye(await U(e,{jsonPrefix:`agent-device-ios-apps`,args:[`devicectl`,`device`,`info`,`apps`,`--device`,e.id,`--include-all-apps`],failureMessage:`Failed to list iOS apps`,parseFailureMessage:`Failed to parse iOS apps list`})),t)}async function Ge(e){let n=await U(e,{jsonPrefix:`agent-device-ios-processes`,args:[`devicectl`,`device`,`info`,`processes`,`--device`,e.id],failureMessage:`Failed to list iOS processes`,parseFailureMessage:`Failed to parse iOS process list`,fallbackHint:Qe});if(!qe(n))throw new t(`COMMAND_FAILED`,`Unsupported iOS process list response`,{deviceId:e.id,hint:Qe});return Xe(n)}async function Ke(e,t){let{appBundleUrl:n,processes:r}=await H(e,t),i=r.sort((e,t)=>G(e,n)-G(t,n))[0];i&&await U(e,{jsonPrefix:`agent-device-ios-process-terminate`,args:[`devicectl`,`device`,`process`,`terminate`,`--device`,e.id,`--pid`,String(i.pid),`--kill`],failureMessage:`Failed to terminate iOS app`,parseFailureMessage:`Failed to parse iOS process termination response`,tolerateFailurePayload:Je})}async function H(e,n){let r=(await V(e,`all`)).find(e=>e.bundleId===n);if(!r)throw new t(`APP_NOT_INSTALLED`,`No iOS device app found for ${n}`,{appBundleId:n,deviceId:e.id});if(!r.url)throw new t(`COMMAND_FAILED`,`Missing app bundle URL for ${n}`,{appBundleId:n,deviceId:e.id,hint:`Installed-app metadata from devicectl did not include the bundle URL required to match running processes. Use an Xcode/CoreDevice toolchain that reports app URLs.`});let i=r.url.replace(/\/+$/,``);return{appBundleUrl:i,processes:(await Ge(e)).filter(e=>e.executable.startsWith(`${i}/`))}}async function U(e,n){let r=u.join(m.tmpdir(),`${n.jsonPrefix}-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`),i=[...n.args,`--json-output`,r],a=await l(i,{allowFailure:!0,timeoutMs:2e4});try{if(a.exitCode!==0){let{stdout:o,stderr:s}=a;if(n.tolerateFailurePayload){let e=await W(r).catch(()=>void 0);if(e!==void 0&&n.tolerateFailurePayload(e))return e}throw new t(`COMMAND_FAILED`,n.failureMessage,c(a,{cmd:`xcrun`,args:i,stdout:o,stderr:s,deviceId:e.id,hint:q(o,s)??n.fallbackHint??`Ensure the iOS device is unlocked, trusted, and available in Xcode > Devices, then retry.`}))}return await W(r)}catch(r){throw r instanceof t?r:new t(`COMMAND_FAILED`,n.parseFailureMessage,{deviceId:e.id,cause:String(r)})}finally{await p.unlink(r).catch(()=>{})}}async function W(e){return JSON.parse(await p.readFile(e,`utf8`))}function G(e,t){return e.executable.slice(t.length+1).split(`/`).length}function qe(e){return Array.isArray(e?.result?.runningProcesses)}function Je(e){let t=e?.error?.userInfo?.NSUnderlyingError?.error;return t?.domain===`NSPOSIXErrorDomain`&&t.code===3}function Ye(e){let t=e?.result?.apps;if(!Array.isArray(t))return[];let n=[];for(let e of t){if(!e||typeof e!=`object`)continue;let t=typeof e.bundleIdentifier==`string`?e.bundleIdentifier.trim():``;if(!t)continue;let r=typeof e.name==`string`&&e.name.trim().length>0?e.name.trim():t,i=typeof e.url==`string`&&e.url.trim().length>0?e.url.trim():void 0;n.push({bundleId:t,name:r,url:i})}return n}function Xe(e){let t=e?.result?.runningProcesses;if(!Array.isArray(t))return[];let n=[];for(let e of t){if(!e||typeof e!=`object`)continue;let t=typeof e.executable==`string`?e.executable.trim():``,r=typeof e.processIdentifier==`number`&&Number.isFinite(e.processIdentifier)?e.processIdentifier:NaN;!t||!Number.isFinite(r)||n.push({executable:t,pid:r})}return n}function Ze(e,t){return ie(e,t)}const K=`Ensure the iOS device is unlocked, trusted, and available in Xcode > Devices, then retry.`,Qe=`This Xcode/CoreDevice toolchain must support 'devicectl device info processes' with JSON runningProcesses so agent-device can resolve app process IDs. Inspect diagnostics for the exact devicectl API failure.`;function q(e,t){let n=`${e}\n${t}`.toLowerCase();return n.includes(`device is busy`)&&n.includes(`connecting`)?`iOS device is still connecting. Keep it unlocked and connected by cable until it is fully available in Xcode Devices, then retry.`:n.includes(`coredeviceservice`)&&n.includes(`timed out`)?`CoreDevice service timed out. Reconnect the device and retry; if it persists restart Xcode and the iOS device.`:n.includes(`developer disk image`)||n.includes(`developer mode is disabled`)?`Enable Developer Mode on the iOS device (Settings > Privacy & Security > Developer Mode), restart it when prompted, unlock it, then retry.`:n.includes(`must be paired`)?`Pair the iOS device with this Mac: connect it by cable, unlock it, accept the Trust prompt, and enter the device passcode, then retry.`:null}function J(e,t){return y(e,t)}function $e(e,t,n){return l(J(e,t),n)}function Y(e){return e.includes(`not installed`)||e.includes(`not found`)||e.includes(`no such file`)}async function et(e,t){return await V(e,t)}async function tt(e,t){await B([`device`,`install`,`app`,`--device`,e.id,t],{action:`install iOS app`,deviceId:e.id},{timeoutMs:12e4})}async function nt(e,t){await B([`device`,`uninstall`,`app`,`--device`,e.id,t],{action:`uninstall iOS app ${t}`,deviceId:e.id},{tolerateOutput:(e,t)=>Y(`${e}\n${t}`.toLowerCase())})}async function rt(e,t){await Ke(e,t)}async function it(e,t){return await H(e,t)}const X=1e4;async function at(e,t,n={}){let r=[`device`,`process`,`launch`,`--device`,e.id,t];n.payloadUrl&&r.push(`--payload-url`,n.payloadUrl),n.launchArgs&&n.launchArgs.length>0&&r.push(`--`,...n.launchArgs),await B(r,{action:`launch iOS app`,deviceId:e.id})}async function ot(e){try{let{result:n,parsed:r}=await Z(e.id,15e3,3e3);if(n.exitCode===0){if(!r.parsed)throw new t(`COMMAND_FAILED`,`iOS device readiness probe failed`,{kind:`probe_inconclusive`,deviceId:e.id,stdout:n.stdout,stderr:n.stderr,hint:`CoreDevice returned success but readiness JSON output was missing or invalid. Retry; if it persists restart Xcode and the iOS device.`});let i=r.tunnelState?.toLowerCase();if(i===`connecting`)throw new t(`COMMAND_FAILED`,`iOS device is not ready for automation`,{kind:`not_ready`,deviceId:e.id,tunnelState:i,hint:`Device tunnel is still connecting. Keep the device unlocked and connected by cable until it is fully available in Xcode Devices, then retry.`});return}throw new t(`COMMAND_FAILED`,`iOS device is not ready for automation`,c(n,{kind:`not_ready`,deviceId:e.id,tunnelState:r.tunnelState,hint:pt(n.stdout,n.stderr)}))}catch(t){throw st(e.id,t)}}function st(e,n){return!(n instanceof t)||n.code!==`COMMAND_FAILED`?lt(e,n):(typeof n.details?.kind==`string`?n.details.kind:``)===`not_ready`?n:ct(e,n)}function ct(e,n){let r=n.details??{},i=String(r.stdout??``),a=String(r.stderr??``),o=Number(r.timeoutMs??15e3),s=`CoreDevice did not respond within ${o}ms. Keep the device unlocked and trusted, then retry; if it persists restart Xcode and the iOS device.`;return new t(`COMMAND_FAILED`,`iOS device readiness probe failed`,{deviceId:e,cause:n.message,timeoutMs:o,stdout:i,stderr:a,hint:i||a?pt(i,a):s},n)}function lt(e,n){return new t(`COMMAND_FAILED`,`iOS device readiness probe failed`,{deviceId:e,hint:`Reconnect the device, keep it unlocked, and retry.`},n instanceof Error?n:void 0)}async function ut(e,t){if(typeof t==`number`&&t<=0)return null;let n=typeof t==`number`?Math.max(1,Math.min(X,t)):X;try{let t=await Z(e.id,n);return t.result.exitCode!==0||!t.parsed.parsed||t.parsed.outcome&&t.parsed.outcome!==`success`?null:t.parsed.tunnelIp??null}catch{return null}}async function Z(e,t,n=0){let r=u.join(m.tmpdir(),`agent-device-coredevice-info-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`),i=Math.max(1,Math.ceil(t/1e3));try{return{result:await l([`devicectl`,`device`,`info`,`details`,`--device`,e,`--json-output`,r,`--timeout`,String(i)],{allowFailure:!0,timeoutMs:t+n}),parsed:await dt(r)}}finally{await p.rm(r,{force:!0}).catch(()=>{})}}async function dt(e){try{return{parsed:!0,...ft(JSON.parse(await p.readFile(e,`utf8`)))}}catch{return{parsed:!1}}}function ft(e){let t=e?.result;if(!t||typeof t!=`object`)return{};let n=t.connectionProperties,r=t.device?.connectionProperties,i=Q(n?.tunnelState)??Q(r?.tunnelState),a=Q(n?.tunnelIPAddress)??Q(r?.tunnelIPAddress),o=Q(e?.info?.outcome);return{...o?{outcome:o}:{},...i?{tunnelState:i}:{},...a?{tunnelIp:a}:{}}}function Q(e){return typeof e==`string`&&e.trim()?e.trim():void 0}function pt(e,t){return q(e,t)||(`${e}\n${t}`.toLowerCase().includes(`timed out waiting for all destinations`)?`Xcode destination did not become available in time. Keep device unlocked and retry.`:K)}async function mt(e,n,r,i=z){let a=re.fromTimeoutMs(i),o={exitCode:1,stdout:``,stderr:``};for(let t of Ce)if(o=await l([`devicectl`,`device`,`copy`,`from`,`--device`,e.id,`--source`,n,`--destination`,r,`--domain-type`,`appDataContainer`,`--domain-identifier`,t],{allowFailure:!0,timeoutMs:ht(a,i)}),o.exitCode===0)return;throw new t(`COMMAND_FAILED`,`Failed to copy runner file from iOS device: ${o.stderr.trim()||o.stdout.trim()||`devicectl exited with code ${o.exitCode}`}`)}function ht(e,n){let r=e.remainingMs();if(r>0)return r;throw new t(`COMMAND_FAILED`,`iOS runner file copy timed out after ${n}ms`,{timeoutMs:n,step:`runner file copy`})}function gt(e){if(!(e instanceof t))return{reason:e instanceof Error?e.message:String(e)};let n=e.details??{},r=Array.isArray(n.args)?n.args.filter(e=>typeof e==`string`).join(` `):void 0;return{errorCode:e.code,reason:e.message,timeoutMs:typeof n.timeoutMs==`number`?n.timeoutMs:void 0,exitCode:typeof n.exitCode==`number`?n.exitCode:void 0,stderr:typeof n.stderr==`string`&&n.stderr.trim()?n.stderr:void 0,stdout:typeof n.stdout==`string`&&n.stdout.trim()?n.stdout:void 0,commandArgs:r}}function _t(e){let t=e.details??{},n=typeof t.stdout==`string`?t.stdout:``,r=typeof t.stderr==`string`?t.stderr:``,i=Array.isArray(t.args)?t.args.filter(e=>typeof e==`string`).join(` `):``;return`${e.message}\n${n}\n${r}\n${i}`.toLowerCase()}async function vt(e,t,n){if(!n.preferRunner)try{await B([`device`,`screenshot`,`--device`,e.id,t],{action:`capture iOS screenshot`,deviceId:e.id});return}catch(t){if(!Ct(t))throw t;St(e,t)}let r=await bt(e,n,!1);await $(r,t)||await mt(e,xt(r),t)}async function yt(e,n,r){if(!await $(await bt(e,r,!0),n))throw new t(`COMMAND_FAILED`,`Failed to capture iOS screenshot: XCTest runner returned no inline image`,{deviceId:e.id,backend:`xctest`})}async function bt(e,t,n){return await t.runRunnerCommand(e,{command:`screenshot`,appBundleId:t.appBundleId,fullscreen:t.fullscreen,inlineScreenshot:n},t.runnerOptions??{})}async function $(e,t){let n=e.imageBase64;return typeof n!=`string`||n.length===0?!1:(await p.writeFile(t,Buffer.from(n,`base64`)),!0)}function xt(e){let n=e.message;if(typeof n==`string`&&n.length>0)return n;throw new t(`COMMAND_FAILED`,`Failed to capture iOS screenshot: runner returned no file path`)}function St(e,t){te({level:`warn`,phase:`ios_screenshot_fallback`,data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,from:`devicectl_screenshot`,to:`runner`,...gt(t)}})}function Ct(e){if(!(e instanceof t)||e.code!==`COMMAND_FAILED`)return!1;let n=_t(e);return n.includes(`unknown option '--device'`)||n.includes(`unknown subcommand`)&&n.includes(`screenshot`)||n.includes(`unrecognized subcommand`)&&n.includes(`screenshot`)}var wt=e({resolveIosPhysicalDeviceControl:()=>Et});const Tt={coredevice:{backend:`coredevice`,assertAppInstallationSupported:()=>{},ensureReady:ot,listApps:et,installApp:tt,uninstallApp:nt,launchApp:at,terminateApp:async(e,t)=>await rt(e,t),resolveAppProcesses:it,captureScreenshot:vt,copyRunnerFile:mt,resolveTunnel:async(e,t)=>({tunnelIp:await ut(e,t)})},xctest:{backend:`xctest`,assertAppInstallationSupported:Dt,ensureReady:Nt,listApps:kt,installApp:Ot,uninstallApp:Ot,launchApp:Pt,terminateApp:Ft,resolveAppProcesses:At,captureScreenshot:yt,copyRunnerFile:Mt,resolveTunnel:jt}};function Et(e){return Tt[e.iosPhysicalDeviceBackend===`xctest`?`xctest`:`coredevice`]}function Dt(e){throw new t(`UNSUPPORTED_OPERATION`,`Installing apps is unavailable on this XCTest-backed physical iOS device.`,{deviceId:e.id,backend:`xctest`,hint:`Install the app with Xcode, then open it in agent-device by bundle ID.`})}async function Ot(e){return Dt(e)}async function kt(e){throw new t(`UNSUPPORTED_OPERATION`,`App inventory is unavailable on this XCTest-backed physical iOS device.`,{deviceId:e.id,backend:`xctest`,hint:`Use an installed app bundle ID when opening the device.`})}async function At(e){throw new t(`UNSUPPORTED_OPERATION`,`Process lookup is unavailable on this XCTest-backed physical iOS device.`,{deviceId:e.id,backend:`xctest`,hint:`Use a CoreDevice-backed iOS device for performance sampling.`})}async function jt(e){throw new t(`UNSUPPORTED_OPERATION`,`XCTest-backed physical iOS devices have no CoreDevice tunnel.`,{deviceId:e.id,backend:`xctest`,hint:`Connect the device by cable so it is reachable through usbmux.`})}async function Mt(e){throw new t(`UNSUPPORTED_OPERATION`,`Runner file copy is unavailable on this XCTest-backed physical iOS device.`,{deviceId:e.id,backend:`xctest`})}async function Nt(e){let n=[`xcdevice`,`wait`,`--both`,`--timeout=15`,e.id],r=await l(n,{allowFailure:!0,timeoutMs:18e3});if(r.exitCode!==0)throw new t(`COMMAND_FAILED`,`iOS device is not ready for XCTest automation`,c(r,{cmd:`xcrun`,args:n,deviceId:e.id,backend:`xctest`,hint:"Keep the device unlocked, trusted, connected, and visible in `xcrun xcdevice list`, then retry."}))}async function Pt(e,n,r){if(r.payloadUrl||r.launchArgs&&r.launchArgs.length>0)throw new t(`UNSUPPORTED_OPERATION`,`XCTest-backed physical iOS devices do not support deep links or launch arguments during open.`,{deviceId:e.id,backend:`xctest`,hint:`Open the installed app by bundle ID without a URL or --launch-args.`});await r.runRunnerCommand(e,{command:`activate`,appBundleId:n},r.runnerOptions??{})}async function Ft(e,t,n){await n.runRunnerCommand(e,{command:`terminate`,appBundleId:t},n.runnerOptions??{})}export{F as A,oe as B,we as C,Pe as D,De as E,ue as F,ae as H,le as I,v as L,ve as M,me as N,L as O,de as P,y as R,j as S,I as T,g as U,_ as V,He as _,Y as a,Ce as b,K as c,Ie as d,z as f,We as g,Ue as h,gt as i,M as j,R as k,q as l,ze as m,Et as n,$e as o,Le as p,_t as r,J as s,wt as t,Re as u,Ve as v,O as w,be as x,Be as y,b as z};
|
|
1
|
+
import{n as e}from"./rolldown-runtime.js";import{_ as t}from"./sdk-contracts.js";import{l as n,s as r,v as i}from"./sdk-device.js";import{A as a,S as o,f as s}from"./sdk-android-adb.js";import{n as c,t as ee}from"./version.js";import{a as te,i as ne}from"./boot-diagnostics.js";import{n as re}from"./simctl.js";import{a as l,s as ie}from"./tool-provider.js";import{a as ae,i as oe,p as se,r as ce}from"./config.js";import u from"node:path";import d from"node:crypto";import f,{promises as p}from"node:fs";import m from"node:os";const h={iOS:{sdkName:{simulator:`iphonesimulator`,device:`iphoneos`},derivedBaseName:{simulator:`ios-simulator`,device:`ios-device`},xctestrunHints:{simulator:{preferred:[`iphonesimulator`],disallowed:[`iphoneos`,`appletvos`,`appletvsimulator`,`macos`]},device:{preferred:[`iphoneos`],disallowed:[`iphonesimulator`,`appletvos`,`appletvsimulator`,`macos`]}}},tvOS:{sdkName:{simulator:`appletvsimulator`,device:`appletvos`},derivedBaseName:{simulator:`tvos-simulator`,device:`tvos-device`},xctestrunHints:{simulator:{preferred:[`appletvsimulator`],disallowed:[`appletvos`,`iphoneos`,`iphonesimulator`,`macos`]},device:{preferred:[`appletvos`],disallowed:[`appletvsimulator`,`iphoneos`,`iphonesimulator`,`macos`]}}},macOS:{sdkName:{simulator:`macosx`,device:`macosx`},derivedBaseName:{simulator:`macos`,device:`macos`},xctestrunHints:{simulator:{preferred:[`macos`],disallowed:[`iphoneos`,`iphonesimulator`,`appletvos`,`appletvsimulator`]},device:{preferred:[`macos`],disallowed:[`iphoneos`,`iphonesimulator`,`appletvos`,`appletvsimulator`]}}},visionOS:{sdkName:{simulator:`xrsimulator`,device:`xros`},derivedBaseName:{simulator:`visionos-simulator`,device:`visionos-device`},xctestrunHints:{simulator:{preferred:[`xrsimulator`],disallowed:[`xros`,`iphoneos`,`iphonesimulator`,`appletvos`,`appletvsimulator`,`macos`]},device:{preferred:[`xros`],disallowed:[`xrsimulator`,`iphoneos`,`iphonesimulator`,`appletvos`,`appletvsimulator`,`macos`]}}}};function g(e){if(!r(e.platform))throw new t(`UNSUPPORTED_PLATFORM`,`Unsupported platform for Apple runner: ${e.platform}`);return n(e)?`macOS`:i(e.target,e.appleOs)}function le(e,t){return h[e].sdkName[_(t)]}function ue(e){return h[g(e)].derivedBaseName[_(e.kind)]}function de(e){return h[g(e)].xctestrunHints[_(e.kind)]}function fe(e){let t=g(e);return t===`macOS`?`platform=macOS,arch=${v()}`:e.kind===`simulator`?`platform=${t} Simulator,id=${e.id}`:`platform=${t},id=${e.id}`}function pe(e){let t=g(e);return t===`macOS`?`platform=macOS,arch=${v()}`:e.kind===`simulator`?`platform=${t} Simulator,id=${e.id}`:`generic/platform=${t}`}function me(e){let t=g(e);return t===`macOS`?`platform=macOS,arch=${v()}`:e.kind===`simulator`?`generic/platform=${t} Simulator`:`generic/platform=${t}`}function _(e){return e===`simulator`?`simulator`:`device`}function v(){return process.arch===`arm64`?`arm64`:`x86_64`}const he=u.join(`apple`,`runner`,`AgentDeviceRunner`),ge=u.join(`dist`,`apple`,`runner`,`AgentDeviceRunner`);function y(e){let t=u.join(e,he);return f.existsSync(t)?t:u.join(e,ge)}function _e(e){return u.join(y(e),`AgentDeviceRunner.xcodeproj`)}const ve=u.join(m.homedir(),`.agent-device`,`apple-runner`),ye=`.agent-device-runner-cache.json`,be=[`-IDEPackageSupportDisableManifestSandbox=1`,`-IDEPackageSupportDisablePluginExecutionSandbox=1`,`ENABLE_USER_SCRIPT_SANDBOXING=NO`],b=se();function x(e){return e?.trim()??``}function S(e=process.env){return x(e.AGENT_DEVICE_IOS_BUNDLE_ID)||x(e.AGENT_DEVICE_IOS_RUNNER_APP_BUNDLE_ID)||`com.callstack.agentdevice.runner`}function C(e=process.env){return x(e.AGENT_DEVICE_IOS_RUNNER_TEST_BUNDLE_ID)||`${S(e)}.uitests`}function xe(e=process.env){let t=S(e),n=C(e);return Array.from(new Set([x(e.AGENT_DEVICE_IOS_RUNNER_CONTAINER_BUNDLE_ID),`${n}.xctrunner`,t].filter(e=>e.length>0)))}const w=xe(process.env);function Se(e,t=ee()){let n=g(e);return{schemaVersion:2,packageVersion:c(t),runnerSourceFingerprint:Oe(t),...Ce(n,e.kind),platformName:n,deviceKind:e.kind,target:e.target??`mobile`,buildDestinationFamily:me(e),runnerBundleBuildSettings:j(process.env),runnerSigningBuildSettings:A(process.env,e.kind===`device`,e),runnerPerformanceBuildSettings:M(),runnerSandboxBuildArgs:N()}}function Ce(e,t){let n=we(T(`xcodebuild`,[`-version`])),r=le(e,t);return{xcodeVersion:n.version,xcodeBuildVersion:n.buildVersion,sdkName:r,sdkVersion:T(`xcrun`,[`--sdk`,r,`--show-sdk-version`]),sdkBuildVersion:T(`xcrun`,[`--sdk`,r,`--show-sdk-build-version`])}}function T(e,t){let n=JSON.stringify([e,t]),r=b.get(n);if(r!==void 0)return r;try{let r=o(e,t,{allowFailure:!0,timeoutMs:5e3,maxBuffer:128*1024}),i=r.exitCode===0&&r.stdout.trim()||`unknown`;return b.set(n,i),i}catch{return b.set(n,`unknown`),`unknown`}}function we(e){return{version:e.match(/^Xcode\s+(.+)$/m)?.[1]?.trim()||`unknown`,buildVersion:e.match(/^Build version\s+(.+)$/m)?.[1]?.trim()||`unknown`}}function Te(e,t){let n=process.env.AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH?.trim();if(n)return u.resolve(n);let r=De(t),i=Ee(e);return u.join(i,r)}function Ee(e){return u.join(ve,`derived`,ue(e))}function De(e){return`cache-${d.createHash(`sha256`).update(D(E(e))).digest(`hex`).slice(0,16)}`}function E(e){let{artifacts:t,packageVersion:n,...r}=e;return r}function D(e){return JSON.stringify(O(e))}function O(e){return Array.isArray(e)?e.map(e=>O(e)):!e||typeof e!=`object`?e:Object.fromEntries(Object.entries(e).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>[e,O(t)]))}const k=new Map;function Oe(e){let t=y(e),n=Ae(t),r=ke(t,n),i=k.get(t);if(i?.fileStatsFingerprint===r)return i.sourceFingerprint;let a=d.createHash(`sha256`);for(let e of n){let n=u.relative(t,e);a.update(n),a.update(`\0`),a.update(f.readFileSync(e)),a.update(`\0`)}let o=a.digest(`hex`);return k.set(t,{fileStatsFingerprint:r,sourceFingerprint:o}),o}function ke(e,t){let n=d.createHash(`sha256`);for(let r of t){let t=u.relative(e,r),i=f.statSync(r);n.update(t),n.update(`\0`),n.update(String(i.size)),n.update(`\0`),n.update(String(Math.trunc(i.mtimeMs))),n.update(`\0`)}return n.digest(`hex`)}function Ae(e){if(!f.existsSync(e))return[];let t=[],n=[e];for(;n.length>0;){let e=n.pop();for(let r of f.readdirSync(e,{withFileTypes:!0})){let i=u.join(e,r.name);if(r.isDirectory()){if(r.name===`xcuserdata`)continue;n.push(i);continue}r.isFile()&&je(r.name,i)&&t.push(i)}}return t.sort((e,t)=>e.localeCompare(t))}function je(e,t){return e===`project.pbxproj`?t.includes(`${u.sep}.xcodeproj${u.sep}`):[`.jpg`,`.json`,`.png`,`.swift`,`.m`,`.h`,`.plist`,`.entitlements`,`.xctestplan`,`.xcconfig`,`.storyboard`,`.xib`].includes(u.extname(e))}function Me(e){return n(e)||e.kind===`device`?`-maximum-concurrent-test-device-destinations`:`-maximum-concurrent-test-simulator-destinations`}function A(e=process.env,t=!1,r={platform:`apple`}){if(n(r))return[`CODE_SIGNING_ALLOWED=NO`,`CODE_SIGNING_REQUIRED=NO`,`CODE_SIGN_IDENTITY=`,`DEVELOPMENT_TEAM=`];if(!t)return[];let i=e.AGENT_DEVICE_IOS_TEAM_ID?.trim()||``,a=e.AGENT_DEVICE_IOS_SIGNING_IDENTITY?.trim()||``,o=e.AGENT_DEVICE_IOS_PROVISIONING_PROFILE?.trim()||``,s=[`CODE_SIGN_STYLE=Automatic`];return i&&s.push(`DEVELOPMENT_TEAM=${i}`),a&&s.push(`CODE_SIGN_IDENTITY=${a}`),o&&s.push(`PROVISIONING_PROFILE_SPECIFIER=${o}`),s}function j(e=process.env){let t=S(e),n=C(e);return[`AGENT_DEVICE_IOS_RUNNER_APP_BUNDLE_ID=${t}`,`AGENT_DEVICE_IOS_RUNNER_TEST_BUNDLE_ID=${n}`]}function M(){return[`COMPILER_INDEX_STORE_ENABLE=NO`,`ENABLE_CODE_COVERAGE=NO`,`ONLY_ACTIVE_ARCH=YES`,`ENABLE_PREVIEWS=NO`,`ENABLE_DEBUG_DYLIB=NO`]}function N(){return[...be,`OTHER_SWIFT_FLAGS=${Ne(process.env)}`]}function Ne(e){return te(e.AGENT_DEVICE_XCUITEST_INCLUDE_UNIT_TESTS)?`$(inherited) -disable-sandbox -D AGENT_DEVICE_RUNNER_UNIT_TESTS`:`$(inherited) -disable-sandbox`}async function P(e,n,r={}){let i=[`devicectl`,...e],a=await l(i,{allowFailure:!0,signal:r.signal,timeoutMs:r.timeoutMs??2e4});if(a.exitCode===0)return;let{stdout:o,stderr:c}=a;if(!r.tolerateOutput?.(o,c))throw new t(`COMMAND_FAILED`,`Failed to ${n.action}`,s(a,{cmd:`xcrun`,args:i,stdout:o,stderr:c,deviceId:n.deviceId,hint:H(o,c)??`Ensure the iOS device is unlocked, trusted, and available in Xcode > Devices, then retry.`}))}async function F(e,t){return Be(Re(await L(e,{jsonPrefix:`agent-device-ios-apps`,args:[`devicectl`,`device`,`info`,`apps`,`--device`,e.id,`--include-all-apps`],failureMessage:`Failed to list iOS apps`,parseFailureMessage:`Failed to parse iOS apps list`})),t)}async function Pe(e){let n=await L(e,{jsonPrefix:`agent-device-ios-processes`,args:[`devicectl`,`device`,`info`,`processes`,`--device`,e.id],failureMessage:`Failed to list iOS processes`,parseFailureMessage:`Failed to parse iOS process list`,fallbackHint:V});if(!Ie(n))throw new t(`COMMAND_FAILED`,`Unsupported iOS process list response`,{deviceId:e.id,hint:V});return ze(n)}async function Fe(e,t){let{appBundleUrl:n,processes:r}=await I(e,t),i=r.sort((e,t)=>z(e,n)-z(t,n))[0];i&&await L(e,{jsonPrefix:`agent-device-ios-process-terminate`,args:[`devicectl`,`device`,`process`,`terminate`,`--device`,e.id,`--pid`,String(i.pid),`--kill`],failureMessage:`Failed to terminate iOS app`,parseFailureMessage:`Failed to parse iOS process termination response`,tolerateFailurePayload:Le})}async function I(e,n){let r=(await F(e,`all`)).find(e=>e.bundleId===n);if(!r)throw new t(`APP_NOT_INSTALLED`,`No iOS device app found for ${n}`,{appBundleId:n,deviceId:e.id});if(!r.url)throw new t(`COMMAND_FAILED`,`Missing app bundle URL for ${n}`,{appBundleId:n,deviceId:e.id,hint:`Installed-app metadata from devicectl did not include the bundle URL required to match running processes. Use an Xcode/CoreDevice toolchain that reports app URLs.`});let i=r.url.replace(/\/+$/,``);return{appBundleUrl:i,processes:(await Pe(e)).filter(e=>e.executable.startsWith(`${i}/`))}}async function L(e,n){let r=u.join(m.tmpdir(),`${n.jsonPrefix}-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`),i=[...n.args,`--json-output`,r],a=await l(i,{allowFailure:!0,timeoutMs:ce});try{if(a.exitCode!==0){let{stdout:o,stderr:c}=a;if(n.tolerateFailurePayload){let e=await R(r).catch(()=>void 0);if(e!==void 0&&n.tolerateFailurePayload(e))return e}throw new t(`COMMAND_FAILED`,n.failureMessage,s(a,{cmd:`xcrun`,args:i,stdout:o,stderr:c,deviceId:e.id,hint:H(o,c)??n.fallbackHint??`Ensure the iOS device is unlocked, trusted, and available in Xcode > Devices, then retry.`}))}return await R(r)}catch(r){throw r instanceof t?r:new t(`COMMAND_FAILED`,n.parseFailureMessage,{deviceId:e.id,cause:String(r)})}finally{await p.unlink(r).catch(()=>{})}}async function R(e){return JSON.parse(await p.readFile(e,`utf8`))}function z(e,t){return e.executable.slice(t.length+1).split(`/`).length}function Ie(e){return Array.isArray(e?.result?.runningProcesses)}function Le(e){let t=e?.error?.userInfo?.NSUnderlyingError?.error;return t?.domain===`NSPOSIXErrorDomain`&&t.code===3}function Re(e){let t=e?.result?.apps;if(!Array.isArray(t))return[];let n=[];for(let e of t){if(!e||typeof e!=`object`)continue;let t=typeof e.bundleIdentifier==`string`?e.bundleIdentifier.trim():``;if(!t)continue;let r=typeof e.name==`string`&&e.name.trim().length>0?e.name.trim():t,i=typeof e.url==`string`&&e.url.trim().length>0?e.url.trim():void 0;n.push({bundleId:t,name:r,url:i})}return n}function ze(e){let t=e?.result?.runningProcesses;if(!Array.isArray(t))return[];let n=[];for(let e of t){if(!e||typeof e!=`object`)continue;let t=typeof e.executable==`string`?e.executable.trim():``,r=typeof e.processIdentifier==`number`&&Number.isFinite(e.processIdentifier)?e.processIdentifier:NaN;!t||!Number.isFinite(r)||n.push({executable:t,pid:r})}return n}function Be(e,t){return ie(e,t)}const B=`Ensure the iOS device is unlocked, trusted, and available in Xcode > Devices, then retry.`,V=`This Xcode/CoreDevice toolchain must support 'devicectl device info processes' with JSON runningProcesses so agent-device can resolve app process IDs. Inspect diagnostics for the exact devicectl API failure.`;function H(e,t){let n=`${e}\n${t}`.toLowerCase();return n.includes(`device is busy`)&&n.includes(`connecting`)?`iOS device is still connecting. Keep it unlocked and connected by cable until it is fully available in Xcode Devices, then retry.`:n.includes(`coredeviceservice`)&&n.includes(`timed out`)?`CoreDevice service timed out. Reconnect the device and retry; if it persists restart Xcode and the iOS device.`:n.includes(`developer disk image`)||n.includes(`developer mode is disabled`)?`Enable Developer Mode on the iOS device (Settings > Privacy & Security > Developer Mode), restart it when prompted, unlock it, then retry.`:n.includes(`must be paired`)?`Pair the iOS device with this Mac: connect it by cable, unlock it, accept the Trust prompt, and enter the device passcode, then retry.`:null}function U(e,t){return re(e,t)}function Ve(e,t,n){return l(U(e,t),n)}function He(e){return e.includes(`not installed`)||e.includes(`not found`)||e.includes(`no such file`)}async function Ue(e,t){return await F(e,t)}async function We(e,t,n){await P([`device`,`install`,`app`,`--device`,e.id,t],{action:`install iOS app`,deviceId:e.id},{signal:n,timeoutMs:oe})}async function Ge(e,t,n){await P([`device`,`uninstall`,`app`,`--device`,e.id,t],{action:`uninstall iOS app ${t}`,deviceId:e.id},{signal:n,tolerateOutput:(e,t)=>He(`${e}\n${t}`.toLowerCase())})}async function Ke(e,t){await Fe(e,t)}async function qe(e,t){return await I(e,t)}const W=1e4;async function Je(e,t,n={}){let r=[`device`,`process`,`launch`,`--device`,e.id,t];n.payloadUrl&&r.push(`--payload-url`,n.payloadUrl),n.launchArgs&&n.launchArgs.length>0&&r.push(`--`,...n.launchArgs),await P(r,{action:`launch iOS app`,deviceId:e.id})}async function Ye(e,n){try{let{result:r,parsed:i}=await G(e.id,15e3,3e3,n);if(r.exitCode===0){if(!i.parsed)throw new t(`COMMAND_FAILED`,`iOS device readiness probe failed`,{kind:`probe_inconclusive`,deviceId:e.id,stdout:r.stdout,stderr:r.stderr,hint:`CoreDevice returned success but readiness JSON output was missing or invalid. Retry; if it persists restart Xcode and the iOS device.`});let n=i.tunnelState?.toLowerCase();if(n===`connecting`)throw new t(`COMMAND_FAILED`,`iOS device is not ready for automation`,{kind:`not_ready`,deviceId:e.id,tunnelState:n,hint:`Device tunnel is still connecting. Keep the device unlocked and connected by cable until it is fully available in Xcode Devices, then retry.`});return}throw new t(`COMMAND_FAILED`,`iOS device is not ready for automation`,s(r,{kind:`not_ready`,deviceId:e.id,tunnelState:i.tunnelState,hint:q(r.stdout,r.stderr)}))}catch(t){throw Xe(e.id,t)}}function Xe(e,n){return!(n instanceof t)||n.code!==`COMMAND_FAILED`?Qe(e,n):(typeof n.details?.kind==`string`?n.details.kind:``)===`not_ready`?n:Ze(e,n)}function Ze(e,n){let r=n.details??{},i=String(r.stdout??``),a=String(r.stderr??``),o=Number(r.timeoutMs??15e3),s=`CoreDevice did not respond within ${o}ms. Keep the device unlocked and trusted, then retry; if it persists restart Xcode and the iOS device.`;return new t(`COMMAND_FAILED`,`iOS device readiness probe failed`,{deviceId:e,cause:n.message,timeoutMs:o,stdout:i,stderr:a,hint:i||a?q(i,a):s},n)}function Qe(e,n){return new t(`COMMAND_FAILED`,`iOS device readiness probe failed`,{deviceId:e,hint:`Reconnect the device, keep it unlocked, and retry.`},n instanceof Error?n:void 0)}async function $e(e,t){if(typeof t==`number`&&t<=0)return null;let n=typeof t==`number`?Math.max(1,Math.min(W,t)):W;try{let t=await G(e.id,n);return t.result.exitCode!==0||!t.parsed.parsed||t.parsed.outcome&&t.parsed.outcome!==`success`?null:t.parsed.tunnelIp??null}catch{return null}}async function G(e,t,n=0,r){let i=u.join(m.tmpdir(),`agent-device-coredevice-info-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`),a=Math.max(1,Math.ceil(t/1e3));try{return{result:await l([`devicectl`,`device`,`info`,`details`,`--device`,e,`--json-output`,i,`--timeout`,String(a)],{allowFailure:!0,signal:r,timeoutMs:t+n}),parsed:await et(i)}}finally{await p.rm(i,{force:!0}).catch(()=>{})}}async function et(e){try{return{parsed:!0,...tt(JSON.parse(await p.readFile(e,`utf8`)))}}catch{return{parsed:!1}}}function tt(e){let t=e?.result;if(!t||typeof t!=`object`)return{};let n=t.connectionProperties,r=t.device?.connectionProperties,i=K(n?.tunnelState)??K(r?.tunnelState),a=K(n?.tunnelIPAddress)??K(r?.tunnelIPAddress),o=K(e?.info?.outcome);return{...o?{outcome:o}:{},...i?{tunnelState:i}:{},...a?{tunnelIp:a}:{}}}function K(e){return typeof e==`string`&&e.trim()?e.trim():void 0}function q(e,t){return H(e,t)||(`${e}\n${t}`.toLowerCase().includes(`timed out waiting for all destinations`)?`Xcode destination did not become available in time. Keep device unlocked and retry.`:B)}async function J(e,n,r,i=ae){let a=ne.fromTimeoutMs(i),o={exitCode:1,stdout:``,stderr:``};for(let t of w)if(o=await l([`devicectl`,`device`,`copy`,`from`,`--device`,e.id,`--source`,n,`--destination`,r,`--domain-type`,`appDataContainer`,`--domain-identifier`,t],{allowFailure:!0,timeoutMs:nt(a,i)}),o.exitCode===0)return;throw new t(`COMMAND_FAILED`,`Failed to copy runner file from iOS device: ${o.stderr.trim()||o.stdout.trim()||`devicectl exited with code ${o.exitCode}`}`)}function nt(e,n){let r=e.remainingMs();if(r>0)return r;throw new t(`COMMAND_FAILED`,`iOS runner file copy timed out after ${n}ms`,{timeoutMs:n,step:`runner file copy`})}function Y(e){if(!(e instanceof t))return{reason:e instanceof Error?e.message:String(e)};let n=e.details??{},r=Array.isArray(n.args)?n.args.filter(e=>typeof e==`string`).join(` `):void 0;return{errorCode:e.code,reason:e.message,timeoutMs:typeof n.timeoutMs==`number`?n.timeoutMs:void 0,exitCode:typeof n.exitCode==`number`?n.exitCode:void 0,stderr:typeof n.stderr==`string`&&n.stderr.trim()?n.stderr:void 0,stdout:typeof n.stdout==`string`&&n.stdout.trim()?n.stdout:void 0,commandArgs:r}}function X(e){let t=e.details??{},n=typeof t.stdout==`string`?t.stdout:``,r=typeof t.stderr==`string`?t.stderr:``,i=Array.isArray(t.args)?t.args.filter(e=>typeof e==`string`).join(` `):``;return`${e.message}\n${n}\n${r}\n${i}`.toLowerCase()}async function rt(e,t,n){if(!n.preferRunner)try{await P([`device`,`capture`,`screenshot`,`--device`,e.id,`--destination`,t],{action:`capture iOS screenshot`,deviceId:e.id});return}catch(t){if(!st(t))throw t;ot(e,t)}let r=await Z(e,n,!1);await Q(r,t)||await J(e,at(r),t)}async function it(e,n,r){if(!await Q(await Z(e,r,!0),n))throw new t(`COMMAND_FAILED`,`Failed to capture iOS screenshot: XCTest runner returned no inline image`,{deviceId:e.id,backend:`xctest`})}async function Z(e,t,n){return await t.runRunnerCommand(e,{command:`screenshot`,appBundleId:t.appBundleId,fullscreen:t.fullscreen,inlineScreenshot:n},t.runnerOptions??{})}async function Q(e,t){let n=e.imageBase64;return typeof n!=`string`||n.length===0?!1:(await p.writeFile(t,Buffer.from(n,`base64`)),!0)}function at(e){let n=e.message;if(typeof n==`string`&&n.length>0)return n;throw new t(`COMMAND_FAILED`,`Failed to capture iOS screenshot: runner returned no file path`)}function ot(e,t){a({level:`warn`,phase:`ios_screenshot_fallback`,data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,from:`devicectl_screenshot`,to:`runner`,...Y(t)}})}function st(e){if(!(e instanceof t)||e.code!==`COMMAND_FAILED`)return!1;let n=X(e);return n.includes(`unknown option '--device'`)||n.includes(`unknown subcommand`)&&n.includes(`screenshot`)||n.includes(`unrecognized subcommand`)&&n.includes(`screenshot`)}var ct=e({resolveIosPhysicalDeviceControl:()=>$});const lt={coredevice:{backend:`coredevice`,assertAppInstallationSupported:()=>{},ensureReady:Ye,listApps:Ue,installApp:We,uninstallApp:Ge,launchApp:Je,terminateApp:async(e,t)=>await Ke(e,t),resolveAppProcesses:qe,captureScreenshot:rt,copyRunnerFile:J,resolveTunnel:async(e,t)=>({tunnelIp:await $e(e,t)})},xctest:{backend:`xctest`,assertAppInstallationSupported:ut,ensureReady:gt,listApps:ft,installApp:dt,uninstallApp:dt,launchApp:_t,terminateApp:vt,resolveAppProcesses:pt,captureScreenshot:it,copyRunnerFile:ht,resolveTunnel:mt}};function $(e){return lt[e.iosPhysicalDeviceBackend===`xctest`?`xctest`:`coredevice`]}function ut(e){throw new t(`UNSUPPORTED_OPERATION`,`Installing apps is unavailable on this XCTest-backed physical iOS device.`,{deviceId:e.id,backend:`xctest`,hint:`Install the app with Xcode, then open it in agent-device by bundle ID.`})}async function dt(e){return ut(e)}async function ft(e){throw new t(`UNSUPPORTED_OPERATION`,`App inventory is unavailable on this XCTest-backed physical iOS device.`,{deviceId:e.id,backend:`xctest`,hint:`Use an installed app bundle ID when opening the device.`})}async function pt(e){throw new t(`UNSUPPORTED_OPERATION`,`Process lookup is unavailable on this XCTest-backed physical iOS device.`,{deviceId:e.id,backend:`xctest`,hint:`Use a CoreDevice-backed iOS device for performance sampling.`})}async function mt(e){throw new t(`UNSUPPORTED_OPERATION`,`XCTest-backed physical iOS devices have no CoreDevice tunnel.`,{deviceId:e.id,backend:`xctest`,hint:`Connect the device by cable so it is reachable through usbmux.`})}async function ht(e){throw new t(`UNSUPPORTED_OPERATION`,`Runner file copy is unavailable on this XCTest-backed physical iOS device.`,{deviceId:e.id,backend:`xctest`})}async function gt(e,n){let r=[`xcdevice`,`wait`,`--both`,`--timeout=15`,e.id],i=await l(r,{allowFailure:!0,signal:n,timeoutMs:18e3});if(i.exitCode!==0)throw new t(`COMMAND_FAILED`,`iOS device is not ready for XCTest automation`,s(i,{cmd:`xcrun`,args:r,deviceId:e.id,backend:`xctest`,hint:"Keep the device unlocked, trusted, connected, and visible in `xcrun xcdevice list`, then retry."}))}async function _t(e,n,r){if(r.payloadUrl||r.launchArgs&&r.launchArgs.length>0)throw new t(`UNSUPPORTED_OPERATION`,`XCTest-backed physical iOS devices do not support deep links or launch arguments during open.`,{deviceId:e.id,backend:`xctest`,hint:`Open the installed app by bundle ID without a URL or --launch-args.`});await r.runRunnerCommand(e,{command:`activate`,appBundleId:n},r.runnerOptions??{})}async function vt(e,t,n){await n.runRunnerCommand(e,{command:`terminate`,appBundleId:t},n.runnerOptions??{})}export{fe as C,pe as S,M as _,Ve as a,D as b,H as c,E as d,Se as f,Me as g,Te as h,Y as i,w as l,j as m,$ as n,U as o,S as p,X as r,B as s,ct as t,ye as u,N as v,de as w,_e as x,A as y};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{v as e}from"./sdk-android-adb.js";import{c as t,d as n,n as r,s as i}from"./host-process.js";import{_ as a}from"./src3.js";import{n as o}from"./verified-file.js";import s from"node:path";import c from"node:fs";function l(e){let t=s.resolve(e.sessionsDir),n=s.resolve(e.pathname);if(s.basename(n)!==e.basename)throw Error(`${e.label} is outside the daemon-owned sessions directory`);if(c.existsSync(t)&&c.existsSync(s.dirname(n))){let r=c.realpathSync.native(t),i=c.realpathSync.native(s.dirname(n));if(i!==r&&!i.startsWith(`${r}${s.sep}`))throw Error(`${e.label} resolves outside the daemon-owned sessions directory`);return s.join(i,e.basename)}if(n!==t&&!n.startsWith(`${t}${s.sep}`))throw Error(`${e.label} is outside the daemon-owned sessions directory`);return n}const u=`app-log.pid`;function d(e,t={}){let n=s.resolve(e),r=t.launch??h;return Object.freeze({start:async(e,t)=>await m(n,e,r,t),readMarker:async e=>T(n,e),clearMarker:async e=>D(n,e),inspect:async e=>k(e),terminate:async e=>await A(e)})}async function f(e){let t=[],n=[];if(!c.existsSync(e))return{recovered:t,retained:n};let r=s.resolve(e);for(let e of c.readdirSync(r,{withFileTypes:!0})){if(!e.isDirectory())continue;let i=s.join(r,e.name);if(c.existsSync(s.join(i,`app-log.resource.json`)))continue;let a=s.join(i,u),o=T(r,a);if(o.status!==`missing`){if(o.status===`invalid`){n.push({markerPath:a,reason:`invalid`,message:o.message});continue}if(await A(o.marker)===`ownership-lost`){let e=p(o.marker.command);n.push({markerPath:a,reason:`ownership-lost`,...e?{device:e}:{}});continue}D(r,a),t.push(a)}}return Object.freeze({recovered:Object.freeze(t),retained:Object.freeze(n)})}function p(e){let t=/(?:^|\s)(?:\S*\/)?adb\s+-s\s+([^\s]+)/.exec(e)?.[1];if(t)return Object.freeze({id:t,family:`android`,kind:t.startsWith(`emulator-`)?`emulator`:`device`,target:`mobile`});let n=/(?:^|\s)xcrun\s+(?:--set\s+\S+\s+)?simctl\s+spawn\s+([^\s]+)/.exec(e)?.[1];if(n)return Object.freeze({id:n,family:`apple`,appleOs:`ios`,kind:`simulator`,target:`mobile`});let r=/(?:^|\s)xcrun\s+devicectl\b[^\n]*?\s--device\s+([^\s]+)/.exec(e)?.[1];if(r)return Object.freeze({id:r,family:`apple`,appleOs:`ios`,kind:`device`,target:`mobile`,iosPhysicalDeviceBackend:`coredevice`})}async function m(e,t,n,r){_(e,t.markerPath),r?.throwIfAborted();let i=await n(t.command,r),a=i.child,o=v(a,t.output),s=await y(e,t.markerPath,i),c=i.wait.then(async e=>(await o(),e)).finally(()=>{t.markerPath&&s&&S(e,t.markerPath,s)}),l=b(a,c);return{marker:s,wait:c,terminate:l,[Symbol.asyncDispose]:l}}function h(t,n){let r=g(t);return e(r.executable,[...r.args],{allowFailure:r.allowFailure,cwd:r.cwd,env:r.env?{...process.env,...r.env}:void 0,timeoutMs:r.timeoutMs,captureOutput:!1,signal:n})}function g(e){return e.kind===`host`?e.request:{executable:`adb`,args:[`-s`,e.serial,...e.args],...e.options}}function _(e,t){if(t&&T(e,t).status!==`missing`)throw Error(`Existing app-log process marker evidence must be recovered before start`)}function v(e,t){let n=Promise.resolve(),r,i=i=>{n=n.then(async()=>await t.write(i)).catch(t=>{r??=t,typeof e.exitCode!=`number`&&e.kill(`SIGKILL`)})};return e.stdout?.on(`data`,i),e.stderr?.on(`data`,i),async()=>{if(await n,r!==void 0)throw r}}async function y(e,t,n){let r=n.child.pid?await w(n.child.pid):void 0;try{if(!r)throw Error(`Managed app-log process did not expose a complete ownership marker`);return t&&E(e,t,r),r}catch(e){throw n.child.kill(`SIGKILL`),await n.wait.catch(()=>void 0),e}}function b(e,t){let n;return async()=>await(n??=(async()=>{typeof e.exitCode!=`number`&&(e.kill(`SIGINT`),await x(t,2e3)||e.kill(`SIGKILL`),await t.catch(()=>void 0))})())}async function x(e,t){return await new Promise(n=>{let r=setTimeout(()=>n(!1),t),i=()=>{clearTimeout(r),n(!0)};e.then(i,i)})}function S(e,t,n){let r=T(e,t);r.status===`decoded`&&r.marker.pid===n.pid&&r.marker.startTime===n.startTime&&r.marker.command===n.command&&D(e,t)}function C(e){let n=t(e),r=i(e);if(!(!n||!r))return Object.freeze({pid:e,startTime:n,command:r})}async function w(e){for(let t=0;t<5;t+=1){let t=C(e);if(t)return t;await new Promise(e=>setTimeout(e,10))}}function T(e,t){let n=O(e,t),r;try{let e=o(n);if(e===void 0)return{status:`missing`};r=e}catch(e){return{status:`invalid`,message:e instanceof Error?e.message:`App-log process marker is invalid`}}try{return a(JSON.parse(c.readFileSync(r,`utf8`)))}catch(e){return{status:`invalid`,message:e instanceof Error?e.message:`App-log process marker is invalid`}}finally{c.closeSync(r)}}function E(e,t,n){let r=O(e,t);if(T(e,r).status!==`missing`)throw Error(`Existing app-log process marker evidence must be recovered before replacement`);c.mkdirSync(s.dirname(r),{recursive:!0});let i=`${r}.${process.pid}.${Date.now()}.tmp`,a,o=!1,l=!1;try{a=c.openSync(i,`wx`,384),c.writeFileSync(a,`${JSON.stringify(n)}\n`),c.fsyncSync(a),c.closeSync(a),a=void 0,c.linkSync(i,r),o=!0,c.unlinkSync(i);let e=c.openSync(s.dirname(r),`r`);try{c.fsyncSync(e)}finally{c.closeSync(e)}l=!0}finally{if(a!==void 0)try{c.closeSync(a)}catch{}if(!l)for(let e of o?[r,i]:[i])try{c.unlinkSync(e)}catch{}}}function D(e,t){let n=O(e,t);try{c.unlinkSync(n)}catch(e){if(e.code!==`ENOENT`)throw e}}function O(e,t){return l({sessionsDir:e,pathname:t,basename:u,label:`App-log process marker`})}function k(e){return r(e.pid)?j(e)?`owned-alive`:`ownership-lost`:`missing`}async function A(e){if(!r(e.pid))return`already-missing`;if(!j(e))return`ownership-lost`;try{process.kill(e.pid,`SIGTERM`)}catch{return`already-missing`}if(!await n(e.pid,2e3)){if(!j(e))return`ownership-lost`;try{process.kill(e.pid,`SIGKILL`)}catch{return`already-missing`}await n(e.pid,2e3)}return r(e.pid)?`ownership-lost`:`terminated`}function j(e){return!e.startTime||!e.command?!1:t(e.pid)===e.startTime&&i(e.pid)===e.command}export{f as n,l as r,d as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{C as e,_ as t}from"./sdk-android-adb.js";import n from"node:path";import{constants as r}from"node:fs";import i from"node:os";import{access as a,mkdtemp as o,readFile as s,rm as c,writeFile as l}from"node:fs/promises";function u(){return Object.freeze({isXcrunAvailable:async e=>{let{resolveAppleToolProvider:t}=await d(async()=>await import(`./tool-provider.js`).then(e=>e.o),e);return await d(async()=>await t().whichCommand(`xcrun`),e)},run:async(e,t)=>{let{runXcrun:n}=await d(async()=>await import(`./tool-provider.js`).then(e=>e.o),t),r=await d(async()=>await n([e.tool,...e.args],{allowFailure:e.allowFailure,signal:t,timeoutMs:e.timeoutMs}),t);return{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode}}})}async function d(e,t){t?.throwIfAborted();try{let n=await e();return t?.throwIfAborted(),n}catch(e){throw t?.throwIfAborted(),e}}function f(){return Object.freeze({prepare:async e=>{if(e===`android`){let{ensureAndroidSdkPathConfigured:e}=await import(`./sdk.js`).then(e=>e.n);await e();return}if(e===`harmonyos`){let{ensureHarmonyToolchainPathConfigured:e}=await import(`./hdc.js`).then(e=>e.t);await e()}}})}function p(){return Object.freeze({commands:Object.freeze({which:async t=>await e(t)?t:void 0,run:async(e,n)=>{let r=await t(e.executable,[...e.args],{allowFailure:e.allowFailure,cwd:e.cwd,env:e.env?{...process.env,...e.env}:void 0,signal:n,timeoutMs:e.timeoutMs});return{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode}}}),appleTools:u(),toolchains:f(),files:Object.freeze({isExecutable:async e=>await h(e),createTemporaryTextFile:async e=>await g(e)}),hostOs:m(process.platform),hostName:i.hostname(),homeDirectory:i.homedir(),observations:Object.freeze({deviceBooted:async e=>{let{markSimulatorBooted:t}=await import(`./simulator.js`).then(e=>e.i);t(e)}})})}function m(e){return e===`darwin`||e===`linux`||e===`win32`?e:`other`}async function h(e){try{return await a(e,r.X_OK),!0}catch{return!1}}async function g(e){let t=await o(n.join(i.tmpdir(),e.prefix)),r=n.join(t,`value${e.suffix}`),a=!1;return{path:r,readText:async()=>await s(r,`utf8`),writeText:async e=>await l(r,e,`utf8`),[Symbol.asyncDispose]:async()=>{a||(a=!0,await c(t,{recursive:!0,force:!0}))}}}export{p as createDeviceInventoryHost,g as createTemporaryTextFile,u as n,f as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
async function e(e){if(e.platform!==`web`)return Object.freeze({mode:`local`});let{hasScopedWebProvider:t,resolveWebProvider:n}=await import(`./
|
|
1
|
+
async function e(e){if(e.platform!==`web`)return Object.freeze({mode:`local`});let{hasScopedWebProvider:t,resolveWebProvider:n}=await import(`./provider.js`).then(e=>e.t),r=n().dumpNetwork,i=t()?`transport-composed`:`local`;return Object.freeze(r?{mode:i,dump:async e=>{let t=await r({limit:e.maxEntries,include:e.include});return Object.freeze({backend:t.backend??`agent-browser`,entries:t.entries,...t.notes===void 0?{}:{notes:t.notes}})}}:{mode:i})}export{e as resolveWebNetworkTransport};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{n as e}from"./rolldown-runtime.js";import{_ as t}from"./sdk-contracts.js";import{J as n,K as r,q as i}from"./sdk-batch-runner.js";import{l as a,s as o}from"./sdk-device.js";import{n as s}from"./session.js";var c=e({inferAndroidPackageAfterOpen:()=>x,resolveAndroidPackageForOpen:()=>b,resolveRequestedOpenSurface:()=>d,resolveSessionAppBundleIdForTarget:()=>w,resolveSoleForegroundIosApp:()=>u,validateOpenRelaunchTarget:()=>g});const l=new Set([`app`,`desktop`,`frontmost-app`]);async function u(e={}){let{listLocalDeviceInventory:t,shouldPropagateDeviceInventoryProbeError:n}=await import(`./verified-file.js`).then(e=>e.i);try{let n=await t({platform:`ios`,iosSimulatorSetPath:e.simulatorSetPath,kind:`simulator`,booted:!0});if(n.length!==1)return;let[r]=n;if(!r)return;let{detectSoleRunningIosSimulatorApp:i}=await import(`./app-resolution.js`).then(e=>e.t),a=await i(r);return a?{device:r,app:a}:void 0}catch(e){if(n(e))throw e;return}}function d(e){let{device:t,surfaceFlag:n,openTarget:r,existingSurface:i}=e;return t.platform===`linux`?f(n,r,i):a(t)?p(n,r,i):m(n)}function f(e,n,r){if(!e)return r??`app`;let i=s(e);if(!l.has(i))throw new t(`INVALID_ARGS`,`Linux supports --surface app, desktop, and frontmost-app (got "${e}")`);return h(i,n),i}function p(e,t,n){if(!e)return n??`app`;let r=s(e);return r!==`app`&&r!==`menubar`&&h(r,t),r}function m(e){if(e)throw new t(`INVALID_ARGS`,`surface is only supported on macOS and Linux`);return`app`}function h(e,n){if(e!==`app`&&e!==`menubar`&&n)throw new t(`INVALID_ARGS`,`open --surface ${e} does not accept an app target`)}async function g(e){let{target:t,platform:n,surface:i}=e;if(t&&r(t))return`open --relaunch does not support URL targets.`;if(i!==void 0&&i!==`app`)return`open --relaunch is supported only for app surfaces.`;if(n===`android`&&t){let{classifyAndroidAppTarget:e,formatAndroidInstalledPackageRequiredMessage:n}=await import(`./app-lifecycle.js`).then(e=>e.p);if(e(t)===`binary`)return n(t)}}async function _(e,t,s){if(!(!o(e.platform)||!t))return r(t)?a(e)?void 0:e.kind===`device`?n(s,t):i(t)?void 0:s??await v(e,t):await y(e,t)}async function v(e,t){try{let{resolveIosSimulatorDeepLinkBundleId:n}=await import(`./apps.js`).then(e=>e.t);return await n(e,t)}catch{return}}async function y(e,t){try{let{resolveIosApp:n}=await import(`./apps.js`).then(e=>e.t);return await n(e,t)}catch{return}}async function b(e,t){if(!(e.platform!==`android`||!t||r(t)))try{let{resolveAndroidApp:n}=await import(`./app-lifecycle.js`).then(e=>e.u),r=await n(e,t);return r.type===`package`?r.value:void 0}catch{return}}async function x(e,t,n){if(n||e.platform!==`android`||!t||!r(t))return n;try{let{getAndroidAppState:t}=await import(`./app-lifecycle.js`).then(e=>e.t);return(await t(e)).package?.trim()||n}catch{return n}}function S(e,t){return e.platform===`android`&&!!(t&&r(t))}function C(e){let t=e?.trim();if(!(!t||r(t)||!t.includes(`.`)))return t}async function w(e,t,n,r){return e.platform===`harmonyos`?C(t)??n:await _(e,t,n)??await r(e,t)??(S(e,t)?n:void 0)}export{u as a,w as i,b as n,g as o,d as r,c as t};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{
|
|
2
|
-
`);
|
|
3
|
-
`);return
|
|
1
|
+
import{_ as e}from"./sdk-contracts.js";import{c as t,l as n}from"./sdk-device.js";import{A as r,C as i,_ as a,y as o}from"./sdk-android-adb.js";import{u as s}from"./host-process.js";import{n as c,o as l,t as u}from"./verified-file.js";import{t as d}from"./app-log-files.js";import{n as f,r as p,t as m}from"./platform-runtime-app-log-process.js";import{createTemporaryTextFile as h,n as g,t as _}from"./platform-runtime-host.js";import v from"node:fs";import{setTimeout as y}from"node:timers/promises";async function b(e,t){t=S(e,t),d(t);let n=u(t),r;try{r=v.createWriteStream(t,{fd:n,autoClose:!0})}catch(e){throw v.closeSync(n),e}let i;r.on(`error`,e=>{i??=e});let a=C(),o=``,s=Promise.resolve(),c,l=e=>{let t=s.then(e);return s=t.catch(()=>void 0),t},f=async e=>{let t=`${o}${e}`.split(`
|
|
2
|
+
`);o=t.pop()??``;for(let e of t)await E(r,w(`${e}\n`,a))};return{write:async e=>await l(async()=>await f(T(e))),[Symbol.asyncDispose]:async()=>{c??=l(async()=>{if(o&&=(await E(r,w(o,a)),``),await D(r),i)throw i}),await c}}}async function x(e,t,n){if(t=S(e,t),!Number.isInteger(n)||n<1||n>1024*1024)throw TypeError(`App-log tail size must be between 1 byte and 1 MiB`);let r=c(t);if(r===void 0)return``;let i=v.fstatSync(r).size,a=Math.min(i,n),o=i-a,s=+(o>0),l=Buffer.alloc(a+s);try{v.readSync(r,l,0,l.length,o-s)}finally{v.closeSync(r)}let u=l.subarray(s).toString(`utf8`);if(s===0||l[0]===10)return u;let d=u.indexOf(`
|
|
3
|
+
`);return d<0?``:u.slice(d+1)}function S(e,t){return p({sessionsDir:e,pathname:t,basename:`app.log`,label:`App-log output`})}function C(){return(process.env.AGENT_DEVICE_APP_LOG_REDACT_PATTERNS??``).split(`,`).map(e=>e.trim()).filter(Boolean).flatMap(e=>{try{return[new RegExp(e,`gi`)]}catch{return[]}})}function w(e,t){return t.reduce((e,t)=>e.replace(t,`[REDACTED]`),e)}function T(e){return typeof e==`string`?e:Buffer.from(e).toString(`utf8`)}async function E(e,t){t&&await new Promise((n,r)=>{e.write(t,e=>e?r(e):n())})}async function D(e){e.closed||await new Promise((t,n)=>{e.once(`error`,n),e.end(()=>{e.off(`error`,n),t()})})}function O(e){return Object.freeze({appLogs:Object.freeze({resolveSession:e.resolveSessionArtifacts,readRecent:async(t,n)=>{let{outputPath:r}=e.resolveSessionArtifacts(t);return k(r,n)},readProcessMarker:async t=>{let{pidPath:n}=e.resolveSessionArtifacts(t);return await e.processes.readMarker(n)}}),networkTransports:Object.freeze({resolve:e.resolveTransport})})}function k(e,t){if(!Number.isInteger(t)||t<1||t>2e4)throw TypeError(`Network app-log scan lines must be between 1 and 20000`);let n=c(e);if(n===void 0)return Object.freeze({path:e,exists:!1,text:``,skippedLines:0});try{let r=A(v.readFileSync(n,`utf8`),t);return Object.freeze({path:e,exists:!0,...r})}finally{v.closeSync(n)}}function A(e,t){let n=e.split(`
|
|
4
4
|
`),r=Math.max(0,n.length-t);return Object.freeze({text:n.slice(r).join(`
|
|
5
|
-
`),skippedLines:r})}function C(){let e=Object.freeze({resolve:async e=>{let{createAndroidScreenRecordingTransport:t}=await import(`./platform-runtime-screen-recording-android-host.js`);return await t(e)}}),t=Object.freeze({resolve:async e=>{let{resolveWebScreenRecordingTransport:t}=await import(`./platform-runtime-screen-recording-web-host.js`);return await t(e)}}),n=Object.freeze({prepare:async e=>{let{createScreenRecordingOutputHost:t}=await import(`./platform-runtime-screen-recording-output-host.js`);await t().prepare(e)}}),r=Object.freeze({complete:async(e,t)=>{let{createScreenRecordingFinalizer:n}=await import(`./platform-runtime-screen-recording-finalizer-host.js`);return await n().complete(e,t)}});return Object.freeze({apple:w(),android:e,harmony:T(),web:t,outputs:n,finalize:r})}function w(){let e=async()=>{let{createAppleScreenRecordingHost:e}=await import(`./platform-runtime-screen-recording-apple-host.js`);return e()};return Object.freeze({availability:async t=>(await e()).availability(t),runRunner:async(t,n,r)=>await(await e()).runRunner(t,n,r),startSimulator:async(t,n,r)=>await(await e()).startSimulator(t,n,r),inspectProcess:async t=>await(await e()).inspectProcess(t),terminateProcess:async t=>await(await e()).terminateProcess(t),inspectRunner:async(t,n,r)=>await(await e()).inspectRunner(t,n,r),retrieveRunnerRecording:async(t,n,r,i)=>await(await e()).retrieveRunnerRecording(t,n,r,i),captureClockAnchor:async(t,n,r)=>await(await e()).captureClockAnchor(t,n,r),isRunnerBundleId:async t=>await(await e()).isRunnerBundleId(t)})}function T(){let e=async()=>{let{createHarmonyScreenRecordingHost:e}=await import(`./platform-runtime-screen-recording-harmony-host.js`);return e()};return Object.freeze({start:async(t,n,r)=>await(await e()).start(t,n,r),stop:async(t,n)=>await(await e()).stop(t,n),findMedia:async(t,n,r)=>await(await e()).findMedia(t,n,r),stageMedia:async(t,n,r)=>await(await e()).stageMedia(t,n,r),stagedFileSize:async(t,n,r)=>await(await e()).stagedFileSize(t,n,r),pull:async(t,n,r)=>await(await e()).pull(t,n,r),remove:async(t,n,r)=>await(await e()).remove(t,n,r),removeMedia:async(t,n,r)=>await(await e()).removeMedia(t,n,r)})}function E(n){let r=s(n.sessionsDir),i=Object.freeze({mode:`local`,start:r.start}),a=Object.freeze({which:async e=>await t(e)?e:void 0,run:async(t,n)=>{let r=await e(t.executable,[...t.args],{allowFailure:t.allowFailure,cwd:t.cwd,env:t.env?{...process.env,...t.env}:void 0,signal:n,timeoutMs:t.timeoutMs});return{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode}}}),o=b({resolveSessionArtifacts:n.resolveSessionArtifacts,processes:r,resolveTransport:async e=>{if(e.platform!==`web`)return Object.freeze({mode:`local`});let{resolveWebNetworkTransport:t}=await import(`./platform-runtime-network-web-transport.js`);return await t(e)}});return Object.freeze({commands:a,appleTools:c(),toolchains:l(),artifacts:Object.freeze({resolveSession:n.resolveSessionArtifacts}),outputs:Object.freeze({openAppend:async e=>await f(n.sessionsDir,e),readTail:async(e,t)=>await p(n.sessionsDir,e,t)}),processes:r,processTransports:Object.freeze({resolve:async e=>{if(e.platform!==`android`)return i;let{resolveAndroidAppLogProcessTransport:t}=await import(`./platform-runtime-app-log-android-transport.js`);return t(n.sessionsDir,e,i)}}),...o,screenRecording:C(),clock:Object.freeze({now:()=>Date.now(),sleep:async(e,t)=>{await d(e,void 0,t?{signal:t}:void 0)}})})}export{E as createPlatformRuntimeHost,a as recoverLegacyAppLogMarkersAfterDaemonLock};
|
|
5
|
+
`),skippedLines:r})}function j(){let e=Object.freeze({resolve:async e=>{let{createAndroidScreenRecordingTransport:t}=await import(`./platform-runtime-screen-recording-android-host.js`);return await t(e)}}),t=Object.freeze({resolve:async e=>{let{resolveWebScreenRecordingTransport:t}=await import(`./platform-runtime-screen-recording-web-host.js`);return await t(e)}}),n=Object.freeze({prepare:async e=>{let{createScreenRecordingOutputHost:t}=await import(`./platform-runtime-screen-recording-output-host.js`);await t().prepare(e)}}),r=Object.freeze({complete:async(e,t)=>{let{createScreenRecordingFinalizer:n}=await import(`./platform-runtime-screen-recording-finalizer-host.js`);return await n().complete(e,t)}});return Object.freeze({apple:M(),android:e,harmony:N(),web:t,outputs:n,finalize:r})}function M(){let e=async()=>{let{createAppleScreenRecordingHost:e}=await import(`./platform-runtime-screen-recording-apple-host.js`);return e()};return Object.freeze({availability:async t=>(await e()).availability(t),runRunner:async(t,n,r)=>await(await e()).runRunner(t,n,r),startSimulator:async(t,n,r)=>await(await e()).startSimulator(t,n,r),inspectProcess:async t=>await(await e()).inspectProcess(t),terminateProcess:async t=>await(await e()).terminateProcess(t),inspectRunner:async(t,n,r)=>await(await e()).inspectRunner(t,n,r),retrieveRunnerRecording:async(t,n,r,i)=>await(await e()).retrieveRunnerRecording(t,n,r,i),captureClockAnchor:async(t,n,r)=>await(await e()).captureClockAnchor(t,n,r),isRunnerBundleId:async t=>await(await e()).isRunnerBundleId(t)})}function N(){let e=async()=>{let{createHarmonyScreenRecordingHost:e}=await import(`./platform-runtime-screen-recording-harmony-host.js`);return e()};return Object.freeze({start:async(t,n,r)=>await(await e()).start(t,n,r),stop:async(t,n)=>await(await e()).stop(t,n),findMedia:async(t,n,r)=>await(await e()).findMedia(t,n,r),stageMedia:async(t,n,r)=>await(await e()).stageMedia(t,n,r),stagedFileSize:async(t,n,r)=>await(await e()).stagedFileSize(t,n,r),pull:async(t,n,r)=>await(await e()).pull(t,n,r),remove:async(t,n,r)=>await(await e()).remove(t,n,r),removeMedia:async(t,n,r)=>await(await e()).removeMedia(t,n,r)})}function P(){return Object.freeze({ensureConnected:async(e,t)=>{t.throwIfAborted();try{let{resolveIosPhysicalDeviceControl:n}=await import(`./physical-device-control.js`).then(e=>e.t);await n(e).ensureReady(e,t),t.throwIfAborted()}catch(e){throw t.throwIfAborted(),e}}})}function ee(){return Object.freeze({keepHot:e=>{import(`./runner-client.js`).then(e=>e.r).then(({prewarmAppleRunnerCache:t})=>t(e,{})).catch(()=>{})},markBooted:e=>{import(`./simulator.js`).then(e=>e.i).then(({markSimulatorBooted:t})=>t(e)).catch(()=>{})}})}function F(){return Object.freeze({discover:async(e,t)=>{t.throwIfAborted();let n=await l(e);return t.throwIfAborted(),n},launch:(e,t)=>{let n=[`-avd`,e];return t&&n.push(`-no-window`,`-no-audio`),o(`emulator`,n)},terminate:async e=>{await s({pids:[e],termTimeoutMs:1500,killTimeoutMs:1500})}})}function I(){return Object.freeze({apple:Object.freeze({listApps:async(e,t)=>{let{listIosApps:n}=await import(`./apps.js`).then(e=>e.t);return L(await n(e,t))}}),android:Object.freeze({listApps:async(e,t)=>{let{listAndroidApps:n}=await import(`./app-lifecycle.js`).then(e=>e.t);return(await n(e,t)).map(e=>({id:e.package,name:e.name}))}}),harmonyos:Object.freeze({listApps:async(e,t,n)=>{let{listHarmonyApps:r}=await import(`./app-lifecycle2.js`);return(await r(e,t,{signal:n})).map(e=>({id:e.package,name:e.name}))}})})}function L(e){return e.map(e=>({id:e.bundleId,name:e.name}))}function R(){return Object.freeze({android:Object.freeze({run:async(e,t,n)=>{n.throwIfAborted();let{runAndroidAdb:r}=await import(`./app-lifecycle.js`).then(e=>e.m),i=await r(e,[...t.args],{allowFailure:t.allowFailure,timeoutMs:t.timeoutMs,signal:n});return n.throwIfAborted(),{stdout:i.stdout}}}),harmonyos:Object.freeze({run:async(e,t,n)=>{n.throwIfAborted();let{runHarmonyHdc:r}=await import(`./hdc.js`).then(e=>e.t),i=await r(e,[...t.args],{allowFailure:t.allowFailure,timeoutMs:t.timeoutMs,signal:n});return n.throwIfAborted(),{stdout:i.stdout}}})})}function z(e,t){let n,r,i=async()=>(n??=t.apple({appleTools:e.appleTools}),await n),a=async()=>(r??=t.android({commands:e.commands}),await r),o=Object.freeze({shutdownTarget:async(e,t)=>await(await i()).shutdownTarget(e,t)}),s=Object.freeze({shutdownTarget:async(e,t)=>await(await a()).shutdownTarget(e,t)}),c=Object.freeze({canShutdownTarget:async e=>await B(e,i,a),shutdownTarget:async e=>await V(e,i,a)});return Object.freeze({apple:o,android:s,close:c})}async function B(e,t,n){return e.platform===`apple`?(await t()).canShutdownTarget(e):e.platform===`android`?(await n()).canShutdownTarget(e):!1}async function V(e,t,n){let r=new AbortController().signal;return e.platform===`apple`?await(await t()).shutdownTarget(e,r):e.platform===`android`?await(await n()).shutdownTarget(e,r):{success:!1,exitCode:-1,stdout:``,stderr:`Cannot shut down unsupported device ${e.platform}/${e.kind}`}}function H(){return Object.freeze({withInvalidatedAppResolutionCache:async(e,t)=>{let{invalidateIosAppResolutionCache:n}=await import(`./app-resolution.js`).then(e=>e.t);return await n(e,t)},prepareArtifact:async(e,t)=>{let{prepareIosInstallArtifact:n}=await import(`./install-artifact2.js`);return await n(e.source,t)},resolveAppBundleId:async(e,t)=>{let{resolveIosApp:n}=await import(`./app-resolution.js`).then(e=>e.t);return await n(e,t)}})}function U(){return Object.freeze({bundletoolJar:process.env.AGENT_DEVICE_BUNDLETOOL_JAR?.trim()||void 0,withInvalidatedAppResolutionCache:async(e,t)=>{let{withAndroidAppResolutionCacheInvalidated:n}=await import(`./app-lifecycle.js`).then(e=>e.u);return await n(e,t)},prepareArtifact:async(e,t)=>{let{prepareAndroidInstallArtifact:n}=await import(`./install-artifact.js`);return await n(e.source,t)},resolveAppPackage:async(e,t)=>{let{resolveAndroidApp:n}=await import(`./app-lifecycle.js`).then(e=>e.u),r=await n(e,t);if(r.type===`intent`){let{AppError:e}=await import(`./sdk-contracts.js`).then(e=>e.b);throw new e(`INVALID_ARGS`,`App uninstall requires a package name, not an intent`)}return r.value}})}function W(){return Object.freeze({runAdb:async(e,t,n,r)=>{let{runAndroidAdb:i}=await import(`./app-lifecycle.js`).then(e=>e.m),a=await i(e,[...t],{allowFailure:n.allowFailure,timeoutMs:n.timeoutMs,signal:r});return{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode}},installPackage:async(e,t,n,r)=>{let{resolveAndroidAdbProvider:i}=await import(`./sdk-android-adb.js`).then(e=>e.t),a=i(e),o=a.install?await a.install(t,{replace:n.replace,signal:r}):await a.exec([`install`,...n.replace?[`-r`]:[],t],{signal:r});return{stdout:o.stdout,stderr:o.stderr,exitCode:o.exitCode}},installBundle:async(e,t,n,r)=>{let{resolveAndroidAdbProvider:i}=await import(`./sdk-android-adb.js`).then(e=>e.t),a=i(e).installBundle;return a?(await a(t,{mode:n,signal:r}),!0):!1}})}function G(){return Object.freeze({resolveOpenTarget:async(e,t)=>await K(e,t),prewarmRunnerCache:async(e,t,n)=>{let{prewarmAppleRunnerCache:r}=await import(`./runner-client.js`).then(e=>e.r);await r(e,Y(t,n))},prewarmRunnerSession:async(e,t,n,r)=>{let{prewarmIosRunnerSession:i}=await import(`./runner-client.js`).then(e=>e.r);await i(e,{...Y(t,n),propagateError:r})},notifyRunnerAppRelaunched:async(e,t,n)=>{let{notifyIosRunnerAppRelaunched:r}=await import(`./runner-client.js`).then(e=>e.r);await r(e,Y(t,n))},stopRunnerSession:async e=>{let{stopIosRunnerSession:t}=await import(`./runner-client.js`).then(e=>e.r);await t(e)},scheduleRunnerIdleStop:e=>{import(`./runner-client.js`).then(e=>e.r).then(({scheduleIosRunnerIdleStop:t})=>t(e))},prepareRunner:async(e,t,n)=>{let{Deadline:r}=await import(`./boot-diagnostics.js`).then(e=>e.s),{prepareIosRunner:i}=await import(`./runner-client.js`).then(e=>e.r),a=Date.now();return await i(e,{...Y(t.execution,n),cleanStaleBundles:!0,buildTimeoutMs:t.timeoutMs,healthTimeoutMs:t.timeoutMs,prepareDeadline:r.fromTimeoutMs(t.timeoutMs,a),startupTimeoutMs:t.timeoutMs})},applyRuntimeHints:async(e,t)=>{let{applyRuntimeHintValues:n}=await import(`./platform-runtime-runtime-hints.js`);await n({device:e,...t})},clearRuntimeHints:async(e,t)=>{let{clearRuntimeHintValues:n}=await import(`./platform-runtime-runtime-hints.js`);await n({device:e,...t})},dismissCloseAlerts:async(e,t)=>await X(e,t),detachRunnerSessionsForShutdown:async()=>{let{detachIosSimulatorRunnerSessionsForShutdown:e}=await import(`./runner-client.js`).then(e=>e.r);await e()},finalizeRunnerSessionsForShutdown:async()=>{let{stopAllIosRunnerSessions:e}=await import(`./runner-client.js`).then(e=>e.r);await e()}})}async function K(t,n){if(n.foreground){let n=await q(t);if(n)return n;throw new e(`AMBIGUOUS_MATCH`,`open --foreground requires exactly one running app on the selected iOS simulator.`,{reason:`foreground_app_ambiguous`,hint:`Pass an explicit app instead: agent-device open <app> --platform ios.`})}let r=await J(t,n.surface),{resolveSessionAppBundleIdForTarget:i}=await import(`./platform-runtime-open-target.js`).then(e=>e.t);return{appBundleId:r.appBundleId??await i(t,n.target,n.currentAppBundleId,async()=>void 0),appName:r.appName??n.target}}async function q(e){if(!t(e)||e.kind!==`simulator`)return;let{detectSoleRunningIosSimulatorApp:n}=await import(`./app-resolution.js`).then(e=>e.t),r=await n(e);return r?{appBundleId:r.bundleId,appName:r.name}:void 0}async function J(e,t){if(!n(e)||t===`app`||t===`desktop`||t===`menubar`)return{};let{resolveFrontmostMacOsApp:r}=await import(`./helper.js`).then(e=>e.t),i=await r();return{appBundleId:i.bundleId,appName:i.appName}}function Y(e,t){return{requestId:e.requestId,logPath:e.logPath,traceLogPath:e.traceLogPath,verbose:e.verbose,iosXctestrunFile:e.iosXctestrunFile,iosXctestDerivedDataPath:e.iosXctestDerivedDataPath,iosXctestEnvDir:e.iosXctestEnvDir,runnerLeaseContext:e.runnerLeaseContext,signal:t}}async function X(e,t){if(!n(e))return;let{runMacOsAlertAction:r}=await import(`./helper.js`).then(e=>e.t);await r(`dismiss`,t.surface===`frontmost-app`?{surface:`frontmost-app`}:t.appBundleId?{bundleId:t.appBundleId}:{})}function Z(){return Object.freeze({resolveOpenTarget:async(e,t)=>await Q(e,t),inferOpenedAppBundleId:async(e,t,n)=>{let{inferAndroidPackageAfterOpen:r}=await import(`./platform-runtime-open-target.js`).then(e=>e.t);return await r(e,t,n)},resetFramePerfStats:async(e,t)=>{let{resetAndroidFramePerfStats:n}=await import(`./perf.js`).then(e=>e.o);await n(e,t)},applyRuntimeHints:async(e,t)=>{let{applyRuntimeHintValues:n}=await import(`./platform-runtime-runtime-hints.js`);await n({device:e,...t})},clearRuntimeHints:async(e,t)=>{let{clearRuntimeHintValues:n}=await import(`./platform-runtime-runtime-hints.js`);await n({device:e,...t})},activateTestIme:async(t,n)=>{let{activateAndroidTestIme:i}=await import(`./ime-lifecycle.js`).then(e=>e.n),a=await i(t,n);if(a.outcome===`helper-unavailable`){r({level:`warn`,phase:`android_test_ime_activate_failed`,data:{device:t.id,error:a.reason}});return}if(a.persistFailed&&!(!a.alreadyActive&&!a.activated))throw new e(`COMMAND_FAILED`,`Android test IME recovery records could not be persisted for ${t.name??t.id}.`,{reason:`android_test_ime_recovery_fence_failed`,deviceId:t.id})},restoreTestIme:async(t,n)=>{let{restoreAndroidTestIme:r}=await import(`./ime-lifecycle.js`).then(e=>e.n);if((await r(t,{stateDir:n.stateDir})).reason===`set-failed`)throw new e(`COMMAND_FAILED`,`Android test IME could not be restored on ${t.name??t.id}.`,{reason:`android_test_ime_restore_incomplete`,deviceId:t.id})},recoverTestImeStartup:async e=>{let{listAndroidAdbSerialsQuick:t,restoreOrphanedAndroidTestImeOnDaemonStartup:n}=await import(`./ime-lifecycle.js`).then(e=>e.n);await n({stateDir:e.stateDir,listSerials:t})},hasTestImeRecoveryEvidence:async e=>{let{readAndroidTestImeRecoveryMarkers:t}=await import(`./ime-recovery-marker.js`).then(e=>e.n);return(await t(e)).length>0}})}async function Q(e,t){let{resolveAndroidPackageForOpen:n,resolveSessionAppBundleIdForTarget:r}=await import(`./platform-runtime-open-target.js`).then(e=>e.t);return{appBundleId:await r(e,t.target,t.currentAppBundleId,n),appName:t.target}}function $(){return Object.freeze({resolve:async(e,t)=>{let{getLocalInteractor:n}=await import(`./interactors.js`).then(e=>e.n);return await n(e,t)}})}function te(e){return Object.freeze({recoverStartupResources:async t=>{await e.android.hasTestImeRecoveryEvidence(t.stateDir)&&await e.android.recoverTestImeStartup(t)},detachForDaemonShutdown:async()=>await e.apple.detachRunnerSessionsForShutdown(),finalizeDaemonShutdown:async()=>await e.apple.finalizeRunnerSessionsForShutdown()})}function ne(e){let t=m(e.sessionsDir),n=Object.freeze({mode:`local`,start:t.start}),r=g(),o=Object.freeze({which:async e=>await i(e)?e:void 0,run:async(e,t)=>{let n=await a(e.executable,[...e.args],{allowFailure:e.allowFailure,cwd:e.cwd,env:e.env?{...process.env,...e.env}:void 0,signal:t,timeoutMs:e.timeoutMs});return{stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode}}}),s=O({resolveSessionArtifacts:e.resolveSessionArtifacts,processes:t,resolveTransport:async e=>{if(e.platform!==`web`)return Object.freeze({mode:`local`});let{resolveWebNetworkTransport:t}=await import(`./platform-runtime-network-web-transport.js`);return await t(e)}}),c=G(),l=Z();return Object.freeze({commands:o,appleTools:r,toolchains:_(),artifacts:Object.freeze({resolveSession:e.resolveSessionArtifacts}),outputs:Object.freeze({openAppend:async t=>await b(e.sessionsDir,t),readTail:async(t,n)=>await x(e.sessionsDir,t,n)}),processes:t,processTransports:Object.freeze({resolve:async t=>{if(t.platform!==`android`)return n;let{resolveAndroidAppLogProcessTransport:r}=await import(`./platform-runtime-app-log-android-transport.js`);return r(e.sessionsDir,t,n)}}),...s,appInventory:I(),appState:R(),appleDeployment:H(),androidDeployment:U(),androidTools:W(),temporaryFiles:Object.freeze({create:async e=>await h(e)}),deviceReadiness:Object.freeze({applePhysical:P(),appleAutomation:ee(),androidEmulator:F()}),deviceShutdown:z({appleTools:r,commands:o},e.shutdownLoaders),screenRecording:j(),localInteractors:$(),appleApplications:c,androidApplications:l,applicationResources:te({android:l,apple:c}),clock:Object.freeze({now:()=>Date.now(),sleep:async(e,t)=>{await y(e,void 0,t?{signal:t}:void 0)}})})}export{ne as createPlatformRuntimeHost,f as recoverLegacyAppLogMarkersAfterDaemonLock};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{_ as e,v as t}from"./sdk-contracts.js";import{c as n}from"./sdk-device.js";import{f as r}from"./sdk-android-adb.js";import{n as i}from"./entities.js";const a=`debug_http_host`,o=`dev_server_https`,s=`RCT_jsLocation`,c=`RCT_packager_scheme`,l=`React Native runtime hints require adb run-as access to the app sandbox. Verify the app is debuggable and the selected package/device are correct.`,u=[`<?xml version="1.0" encoding="utf-8" standalone="yes" ?>`,`<map>`,`</map>`,``].join(`
|
|
2
|
+
`);async function d(e){let{device:t,appId:r,values:i}=e;if(!r)return;let a=p(i);if(a){if(t.platform===`android`){await b(t,r,a);return}n(t)&&t.kind===`simulator`&&await k(t,r,a)}}async function f(e){let{device:t,appId:r}=e;if(r){if(t.platform===`android`){await x(t,r);return}n(t)&&t.kind===`simulator`&&await A(t,r)}}function p(e){let t=m(h(e,`bundleUrl`)),n=h(e,`metroHost`)??t?.host,r=g(e,`metroPort`)??t?.port,i=t?.scheme??`http`;return n&&r?{host:n,port:r,scheme:i}:void 0}function m(t){if(!t)return;let n;try{n=new URL(t)}catch(n){throw new e(`INVALID_ARGS`,`Invalid runtime bundle URL: ${t}`,{},n)}if(!(n.protocol!==`http:`&&n.protocol!==`https:`))return{host:_(n.hostname),port:v(n.port.length>0?Number(n.port):n.protocol===`https:`?443:80),scheme:n.protocol===`https:`?`https`:`http`}}function h(e,t){return _(e[t])}function g(e,t){let n=h(e,t);return n===void 0?void 0:v(Number(n))}function _(e){let t=e?.trim();return t&&t.length>0?t:void 0}function v(e){return Number.isInteger(e)&&e>0&&e<=65535?e:void 0}function y(e){return[`shared_prefs/${e}_preferences.xml`,`shared_prefs/ReactNativeDevPrefs.xml`]}async function b(e,t,n){await L(t);let r=[];for(let i of y(t)){let s=N(await C(e,t,i),a,`${n.host}:${n.port}`);s=P(s,o,n.scheme===`https`),r.push({path:i,xml:s})}await w(e,t,r)}async function x(e,t){await L(t);let n=[];for(let r of y(t)){let i=await C(e,t,r),s=I(I(i,a),o);s!==i&&n.push({path:r,xml:s})}n.length!==0&&await w(e,t,n)}async function S(e,t,n){let{runAndroidAdb:r}=await import(`./app-lifecycle.js`).then(e=>e.m);return await r(e,t,n)}async function C(e,t,n){let r=await S(e,[`shell`,`run-as`,t,`cat`,n],{allowFailure:!0});return r.exitCode===0?M(r.stdout):u}async function w(e,t,n){await T(e,t);try{await D(e,t,n)}catch(e){throw O(e,t)}}async function T(e,t){let n=[`shell`,`run-as`,t,`id`],r=await S(e,n,{allowFailure:!0});if(r.exitCode!==0)throw E(r,t,n)}function E(t,n,i){let a=z(t.stdout,t.stderr);return new e(`COMMAND_FAILED`,a?`Failed to access Android app sandbox for ${n}`:`Failed to probe Android app sandbox for ${n}`,r(t,{package:n,cmd:`adb`,args:i,hint:a?l:`adb shell run-as probe failed. Check adb connectivity and that the device is reachable. Inspect stderr/details for more information.`}))}async function D(e,t,n){await S(e,[`shell`,`run-as`,t,`mkdir`,`-p`,`shared_prefs`]);for(let r of n)await S(e,[`shell`,`run-as`,t,`tee`,r.path],{stdin:r.xml.trimEnd()})}function O(n,r){let i=t(n);if(i.code===`TOOL_MISSING`)return i;let a=z(typeof i.details?.stdout==`string`?i.details.stdout:``,typeof i.details?.stderr==`string`?i.details.stderr:``);return new e(`COMMAND_FAILED`,a?`Failed to access Android app sandbox for ${r}`:`Failed to write Android runtime hints for ${r}`,{...i.details??{},package:r,cmd:`adb`,phase:`write-runtime-hints`,hint:a?l:`adb run-as succeeded, but writing React Native dev-server preferences failed. Inspect stderr/details for the failing shell command.`},i)}async function k(e,t,n){await j(e,[`spawn`,e.id,`defaults`,`write`,t,s,`-string`,`${n.host}:${n.port}`]),await j(e,[`spawn`,e.id,`defaults`,`write`,t,c,`-string`,n.scheme])}async function A(e,t){await j(e,[`spawn`,e.id,`defaults`,`delete`,t,s],{allowFailure:!0}),await j(e,[`spawn`,e.id,`defaults`,`delete`,t,c],{allowFailure:!0})}async function j(e,t,n){let[{buildSimctlArgsForDevice:r},{runXcrun:i}]=await Promise.all([import(`./simctl.js`).then(e=>e.i),import(`./tool-provider.js`).then(e=>e.o)]);await i(r(e,t),n)}function M(e){let t=e.trim();return!t.includes(`<map`)||!t.includes(`</map>`)?u:`${t}\n`}function N(e,t,n){let r=` <string name="${i(t)}">${i(n)}</string>`;return F(I(e,t),r)}function P(e,t,n){let r=` <boolean name="${i(t)}" value="${n?`true`:`false`}" />`;return F(I(e,t),r)}function F(e,t){return M(e).replace(`</map>`,`${t}\n</map>`)}function I(e,t){let n=R(t);return M(e).replace(RegExp(`^\\s*<string name="${n}">[\\s\\S]*?<\\/string>\\n?`,`m`),``).replace(RegExp(`^\\s*<boolean name="${n}" value="(?:true|false)"\\s*\\/?>\\n?`,`m`),``)}async function L(t){let{classifyAndroidAppTarget:n,formatAndroidInstalledPackageRequiredMessage:r}=await import(`./app-lifecycle.js`).then(e=>e.p);if(n(t)!==`binary`)return;let i=r(t);throw new e(`INVALID_ARGS`,i,{package:t,hint:i})}function R(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}function z(e,t){let n=`${e}\n${t}`.toLowerCase();return[`run-as: package not debuggable`,`run-as: permission denied`,`run-as: package is unknown`,`run-as: unknown package`,`is unknown`,`is not an application`,`could not set capabilities`].some(e=>n.includes(e))}export{d as applyRuntimeHintValues,f as clearRuntimeHintValues};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
async function e(e,t,n){let{resolveAppleRunnerScreenRecordingTransport:r}=await import(`./platform-runtime-screen-recording-apple-runner-transport.js`),i=r();if(t.kind===`stop`){if(i.authority!==t.runnerAuthority)throw Error(`Apple runner recording ownership changed before cleanup`);return await i.stop({device:e,runnerSessionId:t.runnerSessionId,appBundleId:t.appBundleId,signal:n}),{}}let a=await i.start({device:e,appBundleId:t.appBundleId,outputPath:t.outputPath,fps:t.fps,signal:n});return Object.freeze({runnerSessionId:a.runnerSessionId,runnerAuthority:i.authority,...a.remotePath===void 0?{}:{remotePath:a.remotePath},...typeof a.recorderStartUptimeMs==`number`?{recorderStartUptimeMs:a.recorderStartUptimeMs}:{},...typeof a.targetAppReadyUptimeMs==`number`?{targetAppReadyUptimeMs:a.targetAppReadyUptimeMs}:{}})}async function t(e,t,n){let{resolveAppleRunnerScreenRecordingTransport:r}=await import(`./platform-runtime-screen-recording-apple-runner-transport.js`),i=r();return i.authority===n?await i.inspect(e,t):`ownership-lost`}async function n(e,t,n,r){r?.throwIfAborted();let{resolveIosPhysicalDeviceControl:i}=await import(`./physical-device-control.js`).then(e=>e.t);await i(e).copyRunnerFile(e,t,n),r?.throwIfAborted()}async function r(e,t,n){try{let[r,i]=await Promise.all([import(`./platform-runtime-screen-recording-apple-transport.js`).then(e=>e.resolveAppleSimulatorScreenRecordingTransport()),import(`./platform-runtime-screen-recording-apple-runner-transport.js`).then(e=>e.resolveAppleRunnerScreenRecordingTransport())]);if(r.mode===`transport-composed`&&i.authority!==`scoped-provider`)return;let{runAppleRunnerCommand:a}=await import(`./
|
|
1
|
+
async function e(e,t,n){let{resolveAppleRunnerScreenRecordingTransport:r}=await import(`./platform-runtime-screen-recording-apple-runner-transport.js`),i=r();if(t.kind===`stop`){if(i.authority!==t.runnerAuthority)throw Error(`Apple runner recording ownership changed before cleanup`);return await i.stop({device:e,runnerSessionId:t.runnerSessionId,appBundleId:t.appBundleId,signal:n}),{}}let a=await i.start({device:e,appBundleId:t.appBundleId,outputPath:t.outputPath,fps:t.fps,signal:n});return Object.freeze({runnerSessionId:a.runnerSessionId,runnerAuthority:i.authority,...a.remotePath===void 0?{}:{remotePath:a.remotePath},...typeof a.recorderStartUptimeMs==`number`?{recorderStartUptimeMs:a.recorderStartUptimeMs}:{},...typeof a.targetAppReadyUptimeMs==`number`?{targetAppReadyUptimeMs:a.targetAppReadyUptimeMs}:{}})}async function t(e,t,n){let{resolveAppleRunnerScreenRecordingTransport:r}=await import(`./platform-runtime-screen-recording-apple-runner-transport.js`),i=r();return i.authority===n?await i.inspect(e,t):`ownership-lost`}async function n(e,t,n,r){r?.throwIfAborted();let{resolveIosPhysicalDeviceControl:i}=await import(`./physical-device-control.js`).then(e=>e.t);await i(e).copyRunnerFile(e,t,n),r?.throwIfAborted()}async function r(e,t,n){try{let[r,i]=await Promise.all([import(`./platform-runtime-screen-recording-apple-transport.js`).then(e=>e.resolveAppleSimulatorScreenRecordingTransport()),import(`./platform-runtime-screen-recording-apple-runner-transport.js`).then(e=>e.resolveAppleRunnerScreenRecordingTransport())]);if(r.mode===`transport-composed`&&i.authority!==`scoped-provider`)return;let{runAppleRunnerCommand:a}=await import(`./runner-client.js`).then(e=>e.r),o=await a(e,{command:`snapshot`,appBundleId:t,interactiveOnly:!0,depth:1},{signal:n}),s=Date.now();return typeof o.currentUptimeMs==`number`&&Number.isFinite(o.currentUptimeMs)&&o.currentUptimeMs>0?{wallClockAtMs:s,uptimeMs:o.currentUptimeMs}:void 0}catch{n?.throwIfAborted();return}}async function i(e){let{IOS_RUNNER_CONTAINER_BUNDLE_IDS:t}=await import(`./runner-client.js`).then(e=>e.r);return t.includes(e)}export{r as captureAppleClockAnchor,t as inspectAppleRunnerOwnership,i as isAppleRunnerBundleId,n as retrieveAppleRunnerRecording,e as runAppleRecordingRunner};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as e}from"./host-process.js";import{
|
|
1
|
+
import{n as e}from"./host-process.js";import{t}from"./scoped-provider.js";import n from"node:path";const r=Object.freeze({authority:`local-lease`,available:!0,start:i,inspect:async(e,t)=>await d(e,t),stop:async({device:e,runnerSessionId:t,appBundleId:n,signal:r})=>{let{runAppleRunnerCommand:i}=await import(`./runner-client.js`).then(e=>e.r);await i(e,{command:`recordStop`,appBundleId:n},{signal:r,expectedRunnerSessionId:t})}});async function i({device:e,appBundleId:t,outputPath:n,fps:r,signal:i}){let{getRunnerSessionSnapshot:s,runAppleRunnerCommand:c}=await import(`./runner-client.js`).then(e=>e.r),l=`agent-device-recording-${Date.now()}.mp4`,u=e.appleOs===`macos`||e.kind!==`device`?void 0:`tmp/${l}`,d=await c(e,{command:`recordStart`,outPath:a(e,n,l,u),...r===void 0?{}:{fps:r},appBundleId:t},{signal:i}),f=s(e.id);if(!f?.alive)throw Error(`Apple runner recording did not expose a durable runner session identity`);try{i?.throwIfAborted()}catch(n){throw await c(e,{command:`recordStop`,appBundleId:t},{expectedRunnerSessionId:f.sessionId}).catch(()=>{}),n}return o(f.sessionId,u,d)}function a(e,t,r,i){return e.appleOs===`macos`?t:i===void 0?n.basename(t):r}function o(e,t,n){return Object.freeze({runnerSessionId:e,...t===void 0?{}:{remotePath:t},...typeof n.recorderStartUptimeMs==`number`?{recorderStartUptimeMs:n.recorderStartUptimeMs}:{},...typeof n.targetAppReadyUptimeMs==`number`?{targetAppReadyUptimeMs:n.targetAppReadyUptimeMs}:{}})}const s=Object.freeze({authority:`scoped-provider`,available:!1,start:async()=>{throw Error(`Scoped Apple runner provider does not expose durable recording authority`)},inspect:async()=>`ownership-lost`,stop:async()=>{throw Error(`Scoped Apple runner recording authority is unavailable`)}}),c=t(r);function l(){return c.resolve()}async function u(e,t){return await c.run(e??s,t)}async function d(t,n){let[{getRunnerSessionSnapshot:r},{readStaleRunnerLease:i,verifyLeaseRunnerPidIdentity:a}]=await Promise.all([import(`./runner-client.js`).then(e=>e.r),import(`./runner-lease.js`).then(e=>e.c)]),o=r(t.id);if(o)return o.alive?o.sessionId===n?`owned-alive`:`ownership-lost`:`missing`;let s=i(t.id);return s?s.sessionId===n?s.runnerPid===null||!e(s.runnerPid)?`missing`:a(s,s.runnerPid)?`owned-alive`:`ownership-lost`:`ownership-lost`:`missing`}export{l as resolveAppleRunnerScreenRecordingTransport,u as withAppleRunnerScreenRecordingTransport};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{t as e}from"./scoped-provider.js";const t=Object.freeze({available:!0,mode:`local`,async start({device:e,outputPath:t,signal:n}){let[{buildSimctlArgsForDevice:r},{runCmdBackground:i}]=await Promise.all([import(`./simctl.js`).then(e=>e.i),import(`./sdk-android-adb.js`).then(e=>e.p)]);return n?.throwIfAborted(),i(`xcrun`,r(e,[`io`,e.id,`recordVideo`,t]),{allowFailure:!0})}}),n=Object.freeze({available:!1,mode:`transport-composed`,start:async()=>{throw Error(`Scoped Apple provider does not expose an Apple simulator screen-recording transport`)}}),r=e(t);function i(){return r.resolve()}async function a(e,t){return await r.run(e??n,t)}export{i as resolveAppleSimulatorScreenRecordingTransport,a as withAppleSimulatorScreenRecordingTransport};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{_ as e}from"./sdk-contracts.js";import{t}from"./
|
|
1
|
+
import{_ as e}from"./sdk-contracts.js";import{t}from"./recording-export-quality.js";import{_ as n}from"./sdk-android-adb.js";import{t as r}from"./version.js";import{n as i}from"./recording-telemetry.js";import{a,i as o,n as s,r as c,t as l}from"./video.js";import u from"node:path";import d from"node:fs";import{fileURLToPath as f}from"node:url";function p(e,t,n,r){let i=`apple/runner/AgentDeviceRunner/RecordingScripts/${e}`,a=`dist/${i}`;return[u.resolve(t,e),u.resolve(n,i),u.resolve(t,`../${i}`),u.resolve(t,`../../${i}`),u.resolve(t,`../../../${i}`),u.resolve(n,a),u.resolve(r,i)]}function m(t){let n=p(t,u.dirname(f(import.meta.url)),r(),process.cwd());for(let e of n)if(d.existsSync(e))return e;throw new e(`COMMAND_FAILED`,`Missing recording helper script: ${t}`,{hint:`Ensure apple/runner/AgentDeviceRunner/RecordingScripts is present in this checkout or bundled under dist/apple/runner in the package.`,scriptName:t,searchedPaths:n})}let h,g;function _(e=process.platform){if(e!==`darwin`)return`touch overlay burn-in is only available on macOS hosts; returning raw video plus gesture telemetry`}function v(){return h??=m(`recording-overlay.swift`),h}function y(){return g??=m(`recording-trim.swift`),g}async function b(t){let{videoPath:r,scriptPath:i,scriptArgs:l,commandDescription:u}=t;await c(r),await s(r);let f=x(r);try{await n(await a({sourcePath:i}),[`--input`,r,`--output`,f,...l],{timeoutMs:12e4,env:o()}),await s(f),d.renameSync(f,r)}catch(t){let n=t instanceof e?t:new e(`COMMAND_FAILED`,String(t),void 0,t instanceof Error?t:void 0);throw new e(`COMMAND_FAILED`,u,{...n.details,videoPath:r,script:i},n)}finally{d.rmSync(f,{force:!0})}}function x(e){let t=u.parse(e),n=`${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2)}`;return u.join(t.dir,`.${t.name}.agent-device-${n}${t.ext||`.mp4`}`)}async function S(e){let{videoPath:t,trimStartMs:n}=e;n>0&&await b({videoPath:t,scriptPath:y(),scriptArgs:[`--trim-start-ms`,String(n)],commandDescription:`Failed to trim the start of the iOS recording`})}async function C(e){let{videoPath:n,telemetryPath:r,exportQuality:i=t,targetLabel:a=`recording`}=e;await b({videoPath:n,scriptPath:v(),scriptArgs:[`--events`,r,`--quality`,i],commandDescription:`Failed to add touch overlays to the ${a}`})}function w(){return Object.freeze({complete:T})}async function T(e){if(await c(e.outputPath),await s(e.outputPath),!await l(e.outputPath))throw Error(`recording was not finalized into a playable video: ${e.outputPath}`);e.trimStartMs&&e.trimStartMs>0&&await S({videoPath:e.outputPath,trimStartMs:e.trimStartMs});let t=i({recording:{outPath:e.outputPath,gestureEvents:[...e.gestureEvents]},...e.trimStartMs===void 0?{}:{trimStartMs:e.trimStartMs}});return!e.showTouches||e.gestureEvents.length===0?{telemetryPath:t}:await E(e,t)}async function E(e,t){let n=_();if(n)return{telemetryPath:t,overlayWarning:n};try{if(await C({videoPath:e.outputPath,telemetryPath:t,exportQuality:e.exportQuality,targetLabel:e.targetLabel}),!await l(e.outputPath))throw Error(`recording post-processing produced an unplayable video`);return{telemetryPath:t}}catch(e){return{telemetryPath:t,overlayWarning:`failed to overlay recording touches: ${e instanceof Error?e.message:String(e)}`}}}export{w as createScreenRecordingFinalizer};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
async function e(e){if(e.platform!==`web`)return;let{hasScopedWebProvider:t,resolveWebProvider:n}=await import(`./
|
|
1
|
+
async function e(e){if(e.platform!==`web`)return;let{hasScopedWebProvider:t,resolveWebProvider:n}=await import(`./provider.js`).then(e=>e.t);if(!t())return;let r=n();if(!(!r.startRecording||!r.stopRecording))return Object.freeze({start:async e=>await r.startRecording(e),stop:async()=>await r.stopRecording()})}export{e as resolveWebScreenRecordingTransport};
|