agent-device 0.20.6 → 0.20.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.6.apk → agent-device-android-ime-helper-0.20.8.apk} +0 -0
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.8.apk.sha256 +1 -0
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.6.manifest.json → agent-device-android-ime-helper-0.20.8.manifest.json} +4 -4
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.6.apk → agent-device-android-snapshot-helper-0.20.8.apk} +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.8.apk.sha256 +1 -0
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.6.manifest.json → agent-device-android-snapshot-helper-0.20.8.manifest.json} +6 -6
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunner/AgentDeviceRunnerApp.m +20 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.h +67 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.m +339 -4
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSelectorMatchPolicy.swift +78 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +31 -2
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +34 -8
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CoordinateTextEntryTests.swift +4 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +36 -28
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +7 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+RecordingTests.swift +4 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SelectorMatchPolicyTests.swift +4 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +2 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +100 -12
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedGesturePolicy.swift +4 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedTextEntry.swift +57 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +1 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextTyping.swift +18 -3
- package/dist/src/agent-browser-tool.js +1 -1
- package/dist/src/agent-device-client.js +2 -2
- 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 +7 -7
- package/dist/src/app-lifecycle2.js +2 -0
- package/dist/src/app-log-files.js +1 -0
- package/dist/src/app-log-reconnect.js +1 -0
- package/dist/src/app-log-runtime.js +4 -0
- package/dist/src/app-resolution.js +2 -1
- package/dist/src/apps.js +5 -5
- package/dist/src/audio-probe.js +1 -1
- package/dist/src/auth-session.js +1 -0
- package/dist/src/auth.js +2 -0
- package/dist/src/boot-diagnostics.js +2 -2
- package/dist/src/cli-config.js +1 -1
- package/dist/src/cli-grammar.js +1 -0
- package/dist/src/cli-help.js +199 -259
- package/dist/src/cli-output.js +1 -0
- package/dist/src/cli-runner.js +1 -2
- package/dist/src/cli.js +6 -16
- package/dist/src/client-metro.js +1 -1
- package/dist/src/cloud-artifacts.d.ts +2 -137
- package/dist/src/command-schema.js +3 -3
- package/dist/src/connection-runtime.js +1 -0
- package/dist/src/connection.js +5 -0
- package/dist/src/daemon-shutdown-report.js +1 -0
- package/dist/src/daemon.js +2 -0
- package/dist/src/debug-symbols.js +1 -1
- package/dist/src/device-claim-inspection.js +1 -0
- package/dist/src/device-input-state.js +2 -2
- package/dist/src/device-ready.js +1 -0
- package/dist/src/device.js +1 -1
- package/dist/src/device2.js +2 -0
- package/dist/src/dispatch.js +1 -0
- package/dist/src/find.js +1 -1
- package/dist/src/finders.js +1 -1
- package/dist/src/generic-settle.js +1 -1
- package/dist/src/generic.js +1 -1
- package/dist/src/handler-utils.js +1 -0
- package/dist/src/harmonyos.js +1 -0
- package/dist/src/hdc.js +1 -0
- package/dist/src/host-process.js +3 -2
- package/dist/src/ime-lifecycle.js +7 -7
- package/dist/src/index.d.ts +52 -21
- package/dist/src/input-actions.js +4 -4
- package/dist/src/input-actions2.js +1 -1
- package/dist/src/input-actions3.js +1 -0
- package/dist/src/install-artifact.js +1 -5
- package/dist/src/install-artifact2.js +1 -1
- package/dist/src/install-source2.js +1 -1
- package/dist/src/interaction-runtime.js +1 -1
- package/dist/src/interaction-snapshot.js +1 -1
- package/dist/src/interaction-touch-reference-frame.js +1 -1
- package/dist/src/interaction.js +1 -1
- package/dist/src/interactor.js +2 -2
- package/dist/src/interactor2.js +1 -1
- package/dist/src/internal/bin.js +2 -2
- package/dist/src/internal/daemon.js +7 -36
- package/dist/src/inventory.js +5 -0
- package/dist/src/inventory2.js +1 -0
- package/dist/src/inventory3.js +2 -0
- package/dist/src/inventory4.js +1 -0
- package/dist/src/inventory5.js +1 -0
- package/dist/src/inventory6.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 -0
- package/dist/src/limrun.d.ts +10 -125
- package/dist/src/limrun.js +1 -1
- package/dist/src/linux.js +1 -1
- package/dist/src/logcat.js +1 -1
- package/dist/src/manifest.js +1 -1
- package/dist/src/notifications.js +1 -1
- package/dist/src/output-path.js +1 -0
- package/dist/src/owner-identity.js +1 -0
- package/dist/src/physical-device-control.js +1 -1
- package/dist/src/platform-runtime-app-log-android-transport.js +1 -0
- package/dist/src/platform-runtime-app-log-process.js +1 -0
- package/dist/src/platform-runtime-host.js +1 -0
- package/dist/src/platform-runtime-network-web-transport.js +1 -0
- package/dist/src/platform-runtime-operation-host.js +5 -0
- package/dist/src/platform-runtime-screen-recording-android-host.js +1 -0
- package/dist/src/platform-runtime-screen-recording-apple-host.js +1 -0
- package/dist/src/platform-runtime-screen-recording-apple-runner-host.js +1 -0
- package/dist/src/platform-runtime-screen-recording-apple-runner-transport.js +1 -0
- package/dist/src/platform-runtime-screen-recording-apple-simulator-host.js +1 -0
- package/dist/src/platform-runtime-screen-recording-apple-transport.js +1 -0
- package/dist/src/platform-runtime-screen-recording-finalizer-host.js +1 -0
- package/dist/src/platform-runtime-screen-recording-harmony-host.js +1 -0
- package/dist/src/platform-runtime-screen-recording-output-host.js +1 -0
- package/dist/src/platform-runtime-screen-recording-web-host.js +1 -0
- package/dist/src/platform-runtime-toolchain-host.js +1 -0
- package/dist/src/platform-runtime.js +1 -0
- package/dist/src/prepare-kind.js +15 -0
- package/dist/src/process-entry.js +1 -0
- package/dist/src/process-lock.js +1 -1
- package/dist/src/provider-webdriver.js +1 -0
- package/dist/src/proxy.js +2 -0
- package/dist/src/react-native.js +1 -1
- package/dist/src/record-runtime.js +1 -0
- package/dist/src/record-trace.js +1 -1
- package/dist/src/recording-telemetry.js +1 -0
- package/dist/src/registry.js +24 -24
- package/dist/src/replay.js +3 -0
- package/dist/src/reporting.js +3 -3
- package/dist/src/runner-disposal.js +1 -1
- package/dist/src/runner-lease.js +1 -1
- package/dist/src/runtime.js +3 -3
- package/dist/src/runtime2.js +4 -0
- package/dist/src/runtime3.js +3 -0
- package/dist/src/runtime4.js +1 -0
- package/dist/src/runtime5.js +1 -0
- package/dist/src/runtime6.js +1 -0
- package/dist/src/runtime7.js +1 -0
- package/dist/src/screenshot-result.js +4 -4
- package/dist/src/screenshot.js +1 -0
- package/dist/src/sdk-android-adb.js +4 -4
- package/dist/src/sdk-batch-runner.js +3 -3
- package/dist/src/sdk-contracts.d.ts +31 -5
- package/dist/src/sdk-contracts.js +1 -1
- package/dist/src/sdk-device.js +1 -1
- package/dist/src/sdk-finders.js +1 -1
- package/dist/src/sdk-remote-config.js +1 -1
- package/dist/src/sdk-selectors.d.ts +285 -5
- package/dist/src/sdk-selectors.js +1 -1
- package/dist/src/selector-runtime.js +1 -1
- package/dist/src/selector-vocabulary.js +1 -1
- package/dist/src/selectors.js +1 -1
- package/dist/src/server.js +3 -3
- package/dist/src/session-target-evidence.js +1 -1
- package/dist/src/session.js +10 -9
- package/dist/src/shared.js +2 -0
- package/dist/src/shell-quote.js +1 -0
- package/dist/src/simulator.js +1 -1
- package/dist/src/snapshot-runtime.js +1 -0
- package/dist/src/snapshot-session.js +1 -0
- package/dist/src/snapshot2.js +1 -1
- package/dist/src/src.js +1 -1
- package/dist/src/src2.js +2 -0
- package/dist/src/src3.js +1 -0
- package/dist/src/text-surface.js +1 -1
- package/dist/src/timing-safe-equal.js +1 -0
- package/dist/src/tool-provider.js +2 -2
- package/dist/src/update-check.js +1 -1
- package/dist/src/version.js +1 -1
- package/dist/src/video.js +23 -0
- package/dist/src/web.js +1 -1
- package/package.json +34 -20
- package/server.json +2 -2
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.6.apk.sha256 +0 -1
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.6.apk.sha256 +0 -1
- package/dist/src/app-log-request-scope.js +0 -1
- package/dist/src/context.js +0 -1
- package/dist/src/devices.js +0 -1
- package/dist/src/devices2.js +0 -1
- package/dist/src/devices3.js +0 -1
- package/dist/src/devices4.js +0 -1
- package/dist/src/provider-limrun-runtime.js +0 -1
- package/dist/src/register-builtins.js +0 -1
- package/dist/src/runner-client.js +0 -1
- package/dist/src/runner-provider.js +0 -1
- package/dist/src/screenshot-geometry.js +0 -1
- package/dist/src/viewport-dimension.js +0 -15
- package/skills/agent-device/SKILL.md +0 -45
- package/skills/dogfood/SKILL.md +0 -27
package/dist/src/apps.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{o as e}from"./png-worker-contract.js";import{_ as t}from"./sdk-contracts.js";import{_ as n,
|
|
2
|
-
`).map(e=>e.trim()).filter(e=>e.length>0&&e!==`Current Status Bar Overrides:`&&!/^=+$/.test(e));for(let e of r){let r=/^DataNetworkType:\s+(\d+)$/.exec(e);if(r){let e=Number(r[1]),i=ke[e];if(!i)throw new t(`COMMAND_FAILED`,`Unsupported simulator data network type: ${e}`);n.dataNetwork=i;continue}let i=/^WiFi Mode:\s+(\d+),\s+WiFi Bars:\s+(\d+)$/.exec(e);if(i){let e=Ae[Number(i[1])];e&&(n.wifiMode=e),n.wifiBars=i[2];continue}let a=/^Cell Mode:\s+(\d+),\s+Cell Bars:\s+(\d+)$/.exec(e);if(a){let e=Number(a[1]),r=je[e];if(!r)throw new t(`COMMAND_FAILED`,`Unsupported simulator cellular mode: ${e}`);n.cellularMode=r,n.cellularBars=a[2];continue}let o=/^Operator Name:\s*(.*)$/.exec(e);if(o){n.operatorName=o[1]??``;continue}}return Object.keys(n).length===0?null:n}function Re(e){let t=[];return e.dataNetwork&&t.push(`--dataNetwork`,e.dataNetwork),e.wifiMode&&t.push(`--wifiMode`,e.wifiMode),e.wifiBars!==void 0&&(e.dataNetwork===`wifi`||e.wifiMode)&&t.push(`--wifiBars`,e.wifiBars),e.cellularMode&&t.push(`--cellularMode`,e.cellularMode),e.cellularBars!==void 0&&(e.cellularMode||ze(e.dataNetwork)||e.operatorName!==void 0)&&t.push(`--cellularBars`,e.cellularBars),e.operatorName!==void 0&&t.push(`--operatorName`,e.operatorName),t}function ze(e){return!!(e&&e!==`hide`&&e!==`wifi`)}function B(e,t,n){m({level:`warn`,phase:`ios_screenshot_status_bar_${t}`,data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,...T(n)}})}function V(e,t,n){return ae(e,t,n)}const Be={ensureBooted:k,prepareStatusBarForScreenshot:Me,captureWithRetry:Ue,normalizeDensity:Ye,captureWithRunner:W,shouldFallbackToRunner:q},H=new Map,U=new Map;async function Ve(e,t,n={}){if(l(e)){await W(e,t,n.appBundleId,n.fullscreen,n.runnerOptions);return}if(e.kind===`simulator`){await He(e,t,n);return}await E(e).captureScreenshot(e,t,{appBundleId:n.appBundleId,fullscreen:n.fullscreen,runnerOptions:n.runnerOptions,runRunnerCommand:D})}async function He(e,n,r={}){if(e.kind!==`simulator`)throw new t(`UNSUPPORTED_OPERATION`,`Simulator screenshot fallback flow supports only iOS simulators`);let i={...Be,...r.deps??{}};r.skipIosSimulatorBootCheck||await i.ensureBooted(e);let a=async()=>{};if(r.normalizeStatusBar===!0)try{a=await i.prepareStatusBarForScreenshot(e)}catch(t){K(e,`prepare_failed`,t)}try{try{await i.captureWithRetry(e,n),await i.normalizeDensity(e,n,r.pixelDensity);return}catch(t){let a=t;if(r.skipIosSimulatorBootCheck&&Je(t)){await i.ensureBooted(e);try{await i.captureWithRetry(e,n),await i.normalizeDensity(e,n,r.pixelDensity);return}catch(e){a=e}}if(!i.shouldFallbackToRunner(a))throw a;Ke(e,`simctl_screenshot`,a)}await i.captureWithRunner(e,n,r.appBundleId,r.fullscreen,r.runnerOptions),await i.normalizeDensity(e,n,r.pixelDensity)}finally{await a().catch(t=>K(e,`restore_failed`,t))}}async function Ue(e,t){let n=_.fromTimeoutMs(oe);await g(async({deadline:n})=>{await V(e,[`io`,e.id,`screenshot`,t],{timeoutMs:Math.max(1e3,n?.remainingMs()??2e4)})},{maxAttempts:5,baseDelayMs:de,maxDelayMs:ce,jitter:.2,shouldRetry:e=>q(e)},{deadline:n,phase:`ios_simulator_screenshot`})}async function W(e,n,r,i,a){if(e.kind===`device`&&!l(e)){await E(e).captureScreenshot(e,n,{appBundleId:r,fullscreen:i,runnerOptions:a,preferRunner:!0,runRunnerCommand:D});return}let o=(await D(e,{command:`screenshot`,appBundleId:r,fullscreen:i,inlineScreenshot:!1},a)).message;if(!o)throw new t(`COMMAND_FAILED`,`Failed to capture iOS screenshot: runner returned no file path`);if(l(e)){await N.copyFile(o,n);return}if(e.kind===`simulator`){await We(e,o,n);return}throw new t(`COMMAND_FAILED`,`Unsupported Apple screenshot target`)}async function We(e,n,r){let i=_.fromTimeoutMs(S),a=`Unable to locate runner container for simulator screenshot`,o=U.get(e.id);if(o){let t=await G(o,n,r);if(t.copied)return;a=t.error,U.delete(e.id)}for(let t of pe){let o=await V(e,[`get_app_container`,e.id,t,`data`],{allowFailure:!0,timeoutMs:Ge(i,S,`runner screenshot container lookup`)});if(o.exitCode!==0){let e=o.stderr.trim();e&&(a=e);continue}let s=o.stdout.trim();if(!s){a=`simctl get_app_container returned empty output`;continue}let c=await G(s,n,r);if(c.copied){U.set(e.id,s);return}a=c.error}throw new t(`COMMAND_FAILED`,`Failed to capture iOS screenshot: ${a}`)}async function G(e,t,n){let r=`Runner screenshot was not found in the simulator container`;for(let i of qe(e,t))try{return await N.copyFile(i,n),{copied:!0}}catch(e){r=e instanceof Error?e.message:String(e)}return{copied:!1,error:r}}function Ge(e,n,r){let i=e.remainingMs();if(i>0)return i;throw new t(`COMMAND_FAILED`,`iOS ${r} timed out after ${n}ms`,{timeoutMs:n,step:r})}function Ke(e,t,n){let r=T(n);m({level:`warn`,phase:`ios_screenshot_fallback`,data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,from:t,to:`runner`,...r}})}function K(e,t,n){m({level:`warn`,phase:`ios_screenshot_status_bar_${t}`,data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,...T(n)}})}function qe(e,t){let n=M.resolve(e),r=t.trim();if(!r)return[];let i=[],a=new Set,o=e=>{let t=M.normalize(e);a.has(t)||(a.add(t),i.push(t))},s=r.replace(/^\/+/,``),c=s.replace(/\\/g,`/`);if(s&&o(M.join(n,s)),M.isAbsolute(r)&&o(M.normalize(r)),c.startsWith(`tmp/`))o(M.join(n,c));else{let e=c.lastIndexOf(`/tmp/`);if(e>=0){let t=c.slice(e+1);o(M.join(n,t))}}let l=M.basename(r);return l&&o(M.join(n,`tmp`,l)),i}function q(e){if(!(e instanceof t)||e.code!==`COMMAND_FAILED`)return!1;let n=C(e);return n.includes(`timeout waiting for screen surfaces`)||n.includes(`nsposixerrordomain`)&&n.includes(`code=60`)&&n.includes(`screenshot`)||n.includes(`timed out`)&&n.includes(`screenshot`)}function Je(e){if(!(e instanceof t)||e.code!==`COMMAND_FAILED`)return!1;let n=C(e);return n.includes(`not booted`)||n.includes(`current state: shutdown`)||n.includes(`current state is shutdown`)||n.includes(`current state=shutdown`)||n.includes(`state: shutdown`)||n.includes(`state=shutdown`)}async function Ye(e,t,n){let r=await Xe(e),i=ge(await he(t),r,n);i&&await f(t,i.width,i.height)}async function Xe(e){let n=H.get(e.id);if(n!==void 0)return n;let r=await V(e,[`getenv`,e.id,`SIMULATOR_MAINSCREEN_SCALE`],{timeoutMs:se}),i=Number(r.stdout.trim());if(!Number.isFinite(i)||i<=0)throw new t(`COMMAND_FAILED`,`Failed to read iOS simulator screenshot scale from SIMULATOR_MAINSCREEN_SCALE`);return H.set(e.id,i),i}function J(e){if(!(e instanceof t)||e.code!==`COMMAND_FAILED`)return!1;let n=e.details??{};if(n.exitCode!==4)return!1;let r=String(n.stderr??``).toLowerCase();return r.includes(`fbsopenapplicationserviceerrordomain`)&&r.includes(`the request to open`)}async function Ze(e,t){let n=await y(ie(e,[`get_app_container`,e.id,t]),{allowFailure:!0});if(n.exitCode!==0)return{installed:!1};let r=n.stdout.trim();if(!r)return{installed:!1};let i=await b(`plutil`,[`-extract`,`CFBundleExecutable`,`raw`,`-o`,`-`,`${r}/Info.plist`],{allowFailure:!0});if(i.exitCode!==0||!i.stdout.trim())return{installed:!0};let a=await b(`otool`,[`-l`,`${r}/${i.stdout.trim()}`],{allowFailure:!0});if(a.exitCode!==0)return{installed:!0};let o=a.stdout.toLowerCase();return{installed:!0,simulatorCompatible:o.includes(`iossimulator`)||o.includes(`platform 7`)}}function Qe(e){return e.installed?e.simulatorCompatible===!1?`ARCH_MISMATCH`:`PERSISTENT_LAUNCH_FAIL`:`APP_NOT_INSTALLED`}function $e(e){switch(e){case`ARCH_MISMATCH`:return`The app binary was not built for the simulator platform. Rebuild with a simulator destination or use a physical device.`;case`APP_NOT_INSTALLED`:return`The app bundle is not installed on this simulator. Run install before open.`;case`PERSISTENT_LAUNCH_FAIL`:return`The simulator repeatedly refused to launch the app. Inspect crash logs in Console.app or ~/Library/Logs/DiagnosticReports/ and consider reinstalling the app.`;default:return`The simulator failed to launch the app. Retry with --debug and inspect diagnostics log for details.`}}const Y=25e3;async function et(e,n,r){let i=r?.launchConsole?.trim(),a=r?.launchArgs;if(i&&(!u(e)||e.kind!==`simulator`))throw new t(`UNSUPPORTED_OPERATION`,ee);if(l(e)){if(a&&a.length>0)throw new t(`UNSUPPORTED_OPERATION`,`--launch-args is not supported on macOS; launch arguments are currently iOS-only.`);await ve(e,n,r);return}let f=r?.url?.trim();if(f){if(i)throw new t(`INVALID_ARGS`,d);if(!c(f))throw new t(`INVALID_ARGS`,`open <app> <url> requires a valid URL target`);if(e.kind===`simulator`){let t=!!a||o(f);if(r?.terminateRunningApp||t){let i=r?.appBundleId??await A(e,n);t?await rt(e,i,{...a?{launchArgs:a}:{},...r?.terminateRunningApp?{terminateRunningApp:!0}:{}}):await nt(e,i)}await X(e,f,void 0);return}let l=s(r?.appBundleId??await A(e,n),f);if(!l)throw new t(`INVALID_ARGS`,`Deep link open on iOS devices requires an active app bundle ID. Open the app first, then open the URL.`);await Q(e,l,{payloadUrl:f,launchArgs:a,runnerOptions:r?.runnerOptions});return}let p=n.trim();if(c(p)){if(i)throw new t(`INVALID_ARGS`,d);if(e.kind===`simulator`){await X(e,p,a);return}let n=s(r?.appBundleId,p);if(!n)throw new t(`INVALID_ARGS`,`Deep link open on iOS devices requires an active app bundle ID. Open the app first, then open the URL.`);await Q(e,n,{payloadUrl:p,launchArgs:a,runnerOptions:r?.runnerOptions});return}let m=r?.appBundleId??await A(e,n);if(e.kind===`simulator`){await rt(e,m,{...i?{launchConsole:i}:{},...a?{launchArgs:a}:{},...r?.terminateRunningApp?{terminateRunningApp:!0}:{}});return}await Q(e,m,{launchArgs:a,runnerOptions:r?.runnerOptions})}async function X(e,n,r){if(r&&r.length>0)throw new t(`INVALID_ARGS`,`--launch-args is not supported with iOS simulator URL opens (simctl openurl ignores launch args). Launch the app first with --launch-args, then issue the URL open in a separate call.`);await k(e),await x(e,[`openurl`,e.id,n])}async function tt(e){l(e)||e.kind===`simulator`&&await _e(e)!==`Booted`&&await k(e)}async function Z(e,t,n){if(l(e)){await we(e,t);return}let r=await A(e,t);if(e.kind===`simulator`){await nt(e,r);return}await E(e).terminateApp(e,r,{runnerOptions:n,runRunnerCommand:D})}async function nt(e,n){await k(e);let r=w(e,[`terminate`,e.id,n]),i=await y(r,{allowFailure:!0,timeoutMs:fe});if(i.exitCode!==0&&!i.stderr.toLowerCase().includes(`found nothing to terminate`))throw new t(`COMMAND_FAILED`,`xcrun exited with code ${i.exitCode}`,h(i,{cmd:`xcrun`,args:r}))}async function rt(e,n,r){await k(e);let i=0,a=_.fromTimeoutMs(ue);try{await g(async({deadline:i})=>{if(i?.isExpired())throw new t(`COMMAND_FAILED`,`App launch deadline exceeded`,{timeoutMs:ue});let a=w(e,it(e.id,n,r)),o=r?.launchConsole?await at(a,r.launchConsole):await y(a,{allowFailure:!0});if(o.exitCode!==0)throw new t(`COMMAND_FAILED`,`xcrun exited with code ${o.exitCode}`,h(o,{cmd:`xcrun`,args:a}))},{maxAttempts:10,baseDelayMs:1e3,maxDelayMs:5e3,jitter:.2,shouldRetry(e){return J(e)?(i+=1,i<3):!1}},{deadline:a})}catch(t){if(J(t)){let r=t,i=Qe(await Ze(e,n));r.details={...r.details,hint:$e(i)}}throw t}}function it(e,t,n){let r=[`launch`];return n?.launchConsole&&r.push(`--console-pty`),n?.terminateRunningApp&&r.push(`--terminate-running-process`),r.push(e,t),n?.launchArgs&&n.launchArgs.length>0&&r.push(...n.launchArgs),r}async function at(e,n){await N.mkdir(M.dirname(n),{recursive:!0});try{let t=await y(e,{allowFailure:!0,timeoutMs:Y});return await ot(n,t.stdout,t.stderr),t}catch(e){let r=(e instanceof t?e:void 0)?.details;if(r?.timeoutMs===Y){let e=typeof r.stdout==`string`?r.stdout:``,t=typeof r.stderr==`string`?r.stderr:``;return await ot(n,e,t),m({level:`warn`,phase:`ios_simulator_launch_console_capture_timeout`,data:{timeoutMs:Y,logPath:n,stdoutBytes:Buffer.byteLength(e),stderrBytes:Buffer.byteLength(t)}}),{stdout:e,stderr:t,exitCode:0}}throw e}}async function ot(e,t,n){await N.writeFile(e,st(t,n),`utf8`)}function st(e,t){return!e||!t||e.endsWith(`
|
|
3
|
-
`)||e.endsWith(`\r`)?`${e}${t}`:`${e}\n${t}`}async function Q(e,t,n){await
|
|
4
|
-
`).replace(/\n$/,``))}async function pt(e,t){if(
|
|
5
|
-
`)){let e=r.trim();if(!e)continue;if(e===`service`){n=!0;continue}if(!n)continue;if(e.startsWith(`bundle identifier`))break;let i=/^([a-z-]+)\s+-\s+/.exec(e)?.[1];i!==void 0&&t.add(i)}return t}function Dt(e,n){let r
|
|
1
|
+
import{o as e}from"./png-worker-contract.js";import{_ as t}from"./sdk-contracts.js";import{_ as n,b as r,m as i,y as a}from"./version.js";import{c as o,l as s,s as c}from"./sdk-batch-runner.js";import{c as l,l as u}from"./sdk-device.js";import{Gt as d,Kt as ee}from"./prepare-kind.js";import{o as f}from"./runtime.js";import{f as p,h as m,j as h}from"./sdk-android-adb.js";import{i as g,o as _}from"./boot-diagnostics.js";import{n as te,r as ne,t as v}from"./setting-state.js";import{R as re,U as ie,_ as ae,a as oe,b as se,f as y,g as ce,h as le,i as b,n as x,o as S,r as ue,s as C,u as de,v as fe,y as pe,z as w}from"./physical-device-control.js";import{a as T,i as E}from"./tool-provider.js";import{a as me}from"./helper.js";import{Bt as he,Vt as ge,ct as D}from"./internal/daemon.js";import{n as _e,r as O,t as k}from"./simulator.js";import{a as ve,c as ye,d as be,f as xe,i as A,l as Se,o as j,r as Ce,s as we,u as Te}from"./app-resolution.js";import{n as Ee}from"./install-artifact2.js";import M from"node:path";import{promises as N}from"node:fs";import De from"node:os";const Oe=[`--time`,`9:41`,`--dataNetwork`,`wifi`,`--wifiMode`,`active`,`--wifiBars`,`3`,`--batteryState`,`charged`,`--batteryLevel`,`100`],ke={0:`hide`,1:`wifi`,6:`3g`,7:`4g`,8:`lte`,9:`lte-a`,10:`lte+`,11:`5g`,12:`5g+`,13:`5g-uwb`,14:`5g-uc`},Ae={1:`searching`,2:`failed`,3:`active`},je={0:`notSupported`,1:`searching`,2:`failed`,3:`active`};function P(e,t,n){return w(e,t,n)}const F=new Set;async function Me(e){let t=null,n=!1;if(Pe(e))n=!0;else try{t=await Fe(e),n=!0}catch(t){B(e,`snapshot_failed`,t)}try{(!n||t)&&await Ie(e),await z(e,Oe)}catch(t){B(e,`prepare_failed`,t)}return async()=>{await Ne(e,n?t:null)}}async function Ne(e,t){if(await Ie(e),!t){L(e);return}await z(e,Re(t)),I(e)}function I(e){F.delete(R(e))}function L(e){F.add(R(e))}function Pe(e){return F.has(R(e))}function R(e){return`${e.platform}:${e.kind}:${e.id}`}async function Fe(e){return Le(m(await P(e,[`status_bar`,e.id,`list`],{allowFailure:!0}),`Failed to read simulator status bar overrides`).stdout)}async function Ie(e){await P(e,[`status_bar`,e.id,`clear`])}async function z(e,t){t.length!==0&&await P(e,[`status_bar`,e.id,`override`,...t])}function Le(e){let n={},r=e.split(`
|
|
2
|
+
`).map(e=>e.trim()).filter(e=>e.length>0&&e!==`Current Status Bar Overrides:`&&!/^=+$/.test(e));for(let e of r){let r=/^DataNetworkType:\s+(\d+)$/.exec(e);if(r){let e=Number(r[1]),i=ke[e];if(!i)throw new t(`COMMAND_FAILED`,`Unsupported simulator data network type: ${e}`);n.dataNetwork=i;continue}let i=/^WiFi Mode:\s+(\d+),\s+WiFi Bars:\s+(\d+)$/.exec(e);if(i){let e=Ae[Number(i[1])];e&&(n.wifiMode=e),n.wifiBars=i[2];continue}let a=/^Cell Mode:\s+(\d+),\s+Cell Bars:\s+(\d+)$/.exec(e);if(a){let e=Number(a[1]),r=je[e];if(!r)throw new t(`COMMAND_FAILED`,`Unsupported simulator cellular mode: ${e}`);n.cellularMode=r,n.cellularBars=a[2];continue}let o=/^Operator Name:\s*(.*)$/.exec(e);if(o){n.operatorName=o[1]??``;continue}}return Object.keys(n).length===0?null:n}function Re(e){let t=[];return e.dataNetwork&&t.push(`--dataNetwork`,e.dataNetwork),e.wifiMode&&t.push(`--wifiMode`,e.wifiMode),e.wifiBars!==void 0&&(e.dataNetwork===`wifi`||e.wifiMode)&&t.push(`--wifiBars`,e.wifiBars),e.cellularMode&&t.push(`--cellularMode`,e.cellularMode),e.cellularBars!==void 0&&(e.cellularMode||ze(e.dataNetwork)||e.operatorName!==void 0)&&t.push(`--cellularBars`,e.cellularBars),e.operatorName!==void 0&&t.push(`--operatorName`,e.operatorName),t}function ze(e){return!!(e&&e!==`hide`&&e!==`wifi`)}function B(e,t,n){h({level:`warn`,phase:`ios_screenshot_status_bar_${t}`,data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,...b(n)}})}function V(e,t,n){return w(e,t,n)}const Be={ensureBooted:k,prepareStatusBarForScreenshot:Me,captureWithRetry:Ue,normalizeDensity:Ye,captureWithRunner:W,shouldFallbackToRunner:q},H=new Map,U=new Map;async function Ve(e,t,n={}){if(u(e)){await W(e,t,n.appBundleId,n.fullscreen,n.runnerOptions);return}if(e.kind===`simulator`){await He(e,t,n);return}await x(e).captureScreenshot(e,t,{appBundleId:n.appBundleId,fullscreen:n.fullscreen,runnerOptions:n.runnerOptions,runRunnerCommand:D})}async function He(e,n,r={}){if(e.kind!==`simulator`)throw new t(`UNSUPPORTED_OPERATION`,`Simulator screenshot fallback flow supports only iOS simulators`);let i={...Be,...r.deps??{}};r.skipIosSimulatorBootCheck||await i.ensureBooted(e);let a=async()=>{};if(r.normalizeStatusBar===!0)try{a=await i.prepareStatusBarForScreenshot(e)}catch(t){K(e,`prepare_failed`,t)}try{try{await i.captureWithRetry(e,n),await i.normalizeDensity(e,n,r.pixelDensity);return}catch(t){let a=t;if(r.skipIosSimulatorBootCheck&&Je(t)){await i.ensureBooted(e);try{await i.captureWithRetry(e,n),await i.normalizeDensity(e,n,r.pixelDensity);return}catch(e){a=e}}if(!i.shouldFallbackToRunner(a))throw a;Ke(e,`simctl_screenshot`,a)}await i.captureWithRunner(e,n,r.appBundleId,r.fullscreen,r.runnerOptions),await i.normalizeDensity(e,n,r.pixelDensity)}finally{await a().catch(t=>K(e,`restore_failed`,t))}}async function Ue(e,t){let n=g.fromTimeoutMs(fe);await _(async({deadline:n})=>{await V(e,[`io`,e.id,`screenshot`,t],{timeoutMs:Math.max(1e3,n?.remainingMs()??2e4)})},{maxAttempts:5,baseDelayMs:le,maxDelayMs:ce,jitter:.2,shouldRetry:e=>q(e)},{deadline:n,phase:`ios_simulator_screenshot`})}async function W(e,n,r,i,a){if(e.kind===`device`&&!u(e)){await x(e).captureScreenshot(e,n,{appBundleId:r,fullscreen:i,runnerOptions:a,preferRunner:!0,runRunnerCommand:D});return}let o=(await D(e,{command:`screenshot`,appBundleId:r,fullscreen:i,inlineScreenshot:!1},a)).message;if(!o)throw new t(`COMMAND_FAILED`,`Failed to capture iOS screenshot: runner returned no file path`);if(u(e)){await N.copyFile(o,n);return}if(e.kind===`simulator`){await We(e,o,n);return}throw new t(`COMMAND_FAILED`,`Unsupported Apple screenshot target`)}async function We(e,n,r){let i=g.fromTimeoutMs(y),a=`Unable to locate runner container for simulator screenshot`,o=U.get(e.id);if(o){let t=await G(o,n,r);if(t.copied)return;a=t.error,U.delete(e.id)}for(let t of se){let o=await V(e,[`get_app_container`,e.id,t,`data`],{allowFailure:!0,timeoutMs:Ge(i,y,`runner screenshot container lookup`)});if(o.exitCode!==0){let e=o.stderr.trim();e&&(a=e);continue}let s=o.stdout.trim();if(!s){a=`simctl get_app_container returned empty output`;continue}let c=await G(s,n,r);if(c.copied){U.set(e.id,s);return}a=c.error}throw new t(`COMMAND_FAILED`,`Failed to capture iOS screenshot: ${a}`)}async function G(e,t,n){let r=`Runner screenshot was not found in the simulator container`;for(let i of qe(e,t))try{return await N.copyFile(i,n),{copied:!0}}catch(e){r=e instanceof Error?e.message:String(e)}return{copied:!1,error:r}}function Ge(e,n,r){let i=e.remainingMs();if(i>0)return i;throw new t(`COMMAND_FAILED`,`iOS ${r} timed out after ${n}ms`,{timeoutMs:n,step:r})}function Ke(e,t,n){let r=b(n);h({level:`warn`,phase:`ios_screenshot_fallback`,data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,from:t,to:`runner`,...r}})}function K(e,t,n){h({level:`warn`,phase:`ios_screenshot_status_bar_${t}`,data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,...b(n)}})}function qe(e,t){let n=M.resolve(e),r=t.trim();if(!r)return[];let i=[],a=new Set,o=e=>{let t=M.normalize(e);a.has(t)||(a.add(t),i.push(t))},s=r.replace(/^\/+/,``),c=s.replace(/\\/g,`/`);if(s&&o(M.join(n,s)),M.isAbsolute(r)&&o(M.normalize(r)),c.startsWith(`tmp/`))o(M.join(n,c));else{let e=c.lastIndexOf(`/tmp/`);if(e>=0){let t=c.slice(e+1);o(M.join(n,t))}}let l=M.basename(r);return l&&o(M.join(n,`tmp`,l)),i}function q(e){if(!(e instanceof t)||e.code!==`COMMAND_FAILED`)return!1;let n=ue(e);return n.includes(`timeout waiting for screen surfaces`)||n.includes(`nsposixerrordomain`)&&n.includes(`code=60`)&&n.includes(`screenshot`)||n.includes(`timed out`)&&n.includes(`screenshot`)}function Je(e){if(!(e instanceof t)||e.code!==`COMMAND_FAILED`)return!1;let n=ue(e);return n.includes(`not booted`)||n.includes(`current state: shutdown`)||n.includes(`current state is shutdown`)||n.includes(`current state=shutdown`)||n.includes(`state: shutdown`)||n.includes(`state=shutdown`)}async function Ye(e,t,n){let r=await Xe(e),i=he(await ge(t),r,n);i&&await f(t,i.width,i.height)}async function Xe(e){let n=H.get(e.id);if(n!==void 0)return n;let r=await V(e,[`getenv`,e.id,`SIMULATOR_MAINSCREEN_SCALE`],{timeoutMs:ae}),i=Number(r.stdout.trim());if(!Number.isFinite(i)||i<=0)throw new t(`COMMAND_FAILED`,`Failed to read iOS simulator screenshot scale from SIMULATOR_MAINSCREEN_SCALE`);return H.set(e.id,i),i}function J(e){if(!(e instanceof t)||e.code!==`COMMAND_FAILED`)return!1;let n=e.details??{};if(n.exitCode!==4)return!1;let r=String(n.stderr??``).toLowerCase();return r.includes(`fbsopenapplicationserviceerrordomain`)&&r.includes(`the request to open`)}async function Ze(e,t){let n=await T(re(e,[`get_app_container`,e.id,t]),{allowFailure:!0});if(n.exitCode!==0)return{installed:!1};let r=n.stdout.trim();if(!r)return{installed:!1};let i=await E(`plutil`,[`-extract`,`CFBundleExecutable`,`raw`,`-o`,`-`,`${r}/Info.plist`],{allowFailure:!0});if(i.exitCode!==0||!i.stdout.trim())return{installed:!0};let a=await E(`otool`,[`-l`,`${r}/${i.stdout.trim()}`],{allowFailure:!0});if(a.exitCode!==0)return{installed:!0};let o=a.stdout.toLowerCase();return{installed:!0,simulatorCompatible:o.includes(`iossimulator`)||o.includes(`platform 7`)}}function Qe(e){return e.installed?e.simulatorCompatible===!1?`ARCH_MISMATCH`:`PERSISTENT_LAUNCH_FAIL`:`APP_NOT_INSTALLED`}function $e(e){switch(e){case`ARCH_MISMATCH`:return`The app binary was not built for the simulator platform. Rebuild with a simulator destination or use a physical device.`;case`APP_NOT_INSTALLED`:return`The app bundle is not installed on this simulator. Run install before open.`;case`PERSISTENT_LAUNCH_FAIL`:return`The simulator repeatedly refused to launch the app. Inspect crash logs in Console.app or ~/Library/Logs/DiagnosticReports/ and consider reinstalling the app.`;default:return`The simulator failed to launch the app. Retry with --debug and inspect diagnostics log for details.`}}const Y=25e3;async function et(e,n,r){let i=r?.launchConsole?.trim(),a=r?.launchArgs;if(i&&(!l(e)||e.kind!==`simulator`))throw new t(`UNSUPPORTED_OPERATION`,ee);if(u(e)){if(a&&a.length>0)throw new t(`UNSUPPORTED_OPERATION`,`--launch-args is not supported on macOS; launch arguments are currently iOS-only.`);await Se(e,n,r);return}let f=r?.url?.trim();if(f){if(i)throw new t(`INVALID_ARGS`,d);if(!c(f))throw new t(`INVALID_ARGS`,`open <app> <url> requires a valid URL target`);if(e.kind===`simulator`){let t=!!a||o(f);if(r?.terminateRunningApp||t){let i=r?.appBundleId??await j(e,n);t?await rt(e,i,{...a?{launchArgs:a}:{},...r?.terminateRunningApp?{terminateRunningApp:!0}:{}}):await nt(e,i)}await X(e,f,void 0);return}let l=s(r?.appBundleId??await j(e,n),f);if(!l)throw new t(`INVALID_ARGS`,`Deep link open on iOS devices requires an active app bundle ID. Open the app first, then open the URL.`);await Q(e,l,{payloadUrl:f,launchArgs:a,runnerOptions:r?.runnerOptions});return}let p=n.trim();if(c(p)){if(i)throw new t(`INVALID_ARGS`,d);if(e.kind===`simulator`){await X(e,p,a);return}let n=s(r?.appBundleId,p);if(!n)throw new t(`INVALID_ARGS`,`Deep link open on iOS devices requires an active app bundle ID. Open the app first, then open the URL.`);await Q(e,n,{payloadUrl:p,launchArgs:a,runnerOptions:r?.runnerOptions});return}let m=r?.appBundleId??await j(e,n);if(e.kind===`simulator`){await rt(e,m,{...i?{launchConsole:i}:{},...a?{launchArgs:a}:{},...r?.terminateRunningApp?{terminateRunningApp:!0}:{}});return}await Q(e,m,{launchArgs:a,runnerOptions:r?.runnerOptions})}async function X(e,n,r){if(r&&r.length>0)throw new t(`INVALID_ARGS`,`--launch-args is not supported with iOS simulator URL opens (simctl openurl ignores launch args). Launch the app first with --launch-args, then issue the URL open in a separate call.`);await k(e),await S(e,[`openurl`,e.id,n])}async function tt(e){u(e)||e.kind===`simulator`&&await _e(e)!==`Booted`&&await k(e)}async function Z(e,t,n){if(u(e)){await ye(e,t);return}let r=await j(e,t);if(e.kind===`simulator`){await nt(e,r);return}await x(e).terminateApp(e,r,{runnerOptions:n,runRunnerCommand:D})}async function nt(e,n){await k(e);let r=C(e,[`terminate`,e.id,n]),i=await T(r,{allowFailure:!0,timeoutMs:pe});if(i.exitCode!==0&&!i.stderr.toLowerCase().includes(`found nothing to terminate`))throw new t(`COMMAND_FAILED`,`xcrun exited with code ${i.exitCode}`,p(i,{cmd:`xcrun`,args:r}))}async function rt(e,n,r){await k(e);let i=0,a=g.fromTimeoutMs(de);try{await _(async({deadline:i})=>{if(i?.isExpired())throw new t(`COMMAND_FAILED`,`App launch deadline exceeded`,{timeoutMs:de});let a=C(e,it(e.id,n,r)),o=r?.launchConsole?await at(a,r.launchConsole):await T(a,{allowFailure:!0});if(o.exitCode!==0)throw new t(`COMMAND_FAILED`,`xcrun exited with code ${o.exitCode}`,p(o,{cmd:`xcrun`,args:a}))},{maxAttempts:10,baseDelayMs:1e3,maxDelayMs:5e3,jitter:.2,shouldRetry(e){return J(e)?(i+=1,i<3):!1}},{deadline:a})}catch(t){if(J(t)){let r=t,i=Qe(await Ze(e,n));r.details={...r.details,hint:$e(i)}}throw t}}function it(e,t,n){let r=[`launch`];return n?.launchConsole&&r.push(`--console-pty`),n?.terminateRunningApp&&r.push(`--terminate-running-process`),r.push(e,t),n?.launchArgs&&n.launchArgs.length>0&&r.push(...n.launchArgs),r}async function at(e,n){await N.mkdir(M.dirname(n),{recursive:!0});try{let t=await T(e,{allowFailure:!0,timeoutMs:Y});return await ot(n,t.stdout,t.stderr),t}catch(e){let r=(e instanceof t?e:void 0)?.details;if(r?.timeoutMs===Y){let e=typeof r.stdout==`string`?r.stdout:``,t=typeof r.stderr==`string`?r.stderr:``;return await ot(n,e,t),h({level:`warn`,phase:`ios_simulator_launch_console_capture_timeout`,data:{timeoutMs:Y,logPath:n,stdoutBytes:Buffer.byteLength(e),stderrBytes:Buffer.byteLength(t)}}),{stdout:e,stderr:t,exitCode:0}}throw e}}async function ot(e,t,n){await N.writeFile(e,st(t,n),`utf8`)}function st(e,t){return!e||!t||e.endsWith(`
|
|
3
|
+
`)||e.endsWith(`\r`)?`${e}${t}`:`${e}\n${t}`}async function Q(e,t,n){await x(e).launchApp(e,t,{...n,runRunnerCommand:D})}async function ct(e,n){return await A(e,async()=>{let r=await j(e,n);if(e.kind!==`simulator`)return await x(e).uninstallApp(e,r),{bundleId:r};await k(e);let i=await S(e,[`uninstall`,e.id,r],{allowFailure:!0});if(i.exitCode!==0&&!oe(`${i.stdout}\n${i.stderr}`.toLowerCase()))throw new t(`COMMAND_FAILED`,`simctl uninstall failed for ${r}`,p(i));return{bundleId:r}})}async function lt(e,t,n){e.kind!==`simulator`&&x(e).assertAppInstallationSupported(e);let r=await Ee({kind:`path`,path:t},n);try{return await dt(e,r.installablePath),{archivePath:r.archivePath,installablePath:r.installablePath,bundleId:r.bundleId,appName:r.appName,launchTarget:r.bundleId}}finally{await r.cleanup()}}async function ut(e,t,n){return e.kind!==`simulator`&&x(e).assertAppInstallationSupported(e),await A(e,async()=>{let{bundleId:r}=await ct(e,t);return await lt(e,n,{appIdentifierHint:t}),{bundleId:r}})}async function dt(e,t){await A(e,async()=>{if(e.kind!==`simulator`){await x(e).installApp(e,t);return}await k(e),await S(e,[`install`,e.id,t])})}async function ft(e){return u(e)?await Te():(O(e,`clipboard`),await k(e),m(await S(e,[`pbpaste`,e.id],{allowFailure:!0}),`Failed to read iOS simulator clipboard`).stdout.replace(/\r\n/g,`
|
|
4
|
+
`).replace(/\n$/,``))}async function pt(e,t){if(u(e)){await xe(t);return}O(e,`clipboard`),await k(e),m(await S(e,[`pbcopy`,e.id],{allowFailure:!0,stdin:t}),`Failed to write iOS simulator clipboard`)}async function mt(e,t,n){O(e,`push`),await k(e);let r=await N.mkdtemp(M.join(De.tmpdir(),`agent-device-ios-push-`)),i=M.join(r,`payload.apns`);try{await N.writeFile(i,`${JSON.stringify(n)}\n`,`utf8`),await S(e,[`push`,e.id,t,i])}finally{await N.rm(r,{recursive:!0,force:!0})}}let $=null,ht;async function gt(e,r,o,s,c){if(u(e)){let e=r.toLowerCase();if(e===`appearance`){await be(o);return}if(e===`permission`){let e=a(o);if(e===`deny`)throw new t(`INVALID_ARGS`,n(`permission`));return await me(e,vt(c?.permissionTarget))}throw new t(`INVALID_ARGS`,n(r))}O(e,`settings`),await k(e);let l=r.toLowerCase();switch(l){case`clear-app-state`:{if(o.toLowerCase()!==`clear`)throw new t(`INVALID_ARGS`,`settings clear-app-state only supports clear.`);if(!s)throw new t(`INVALID_ARGS`,`settings clear-app-state requires an app id or an active app session.`);let n=await _t(e,s);return{bundleId:n.bundleId,containerPath:n.containerPath,cleared:!0}}case`wifi`:{let t=v(o)?`active`:`failed`;await S(e,[`status_bar`,e.id,`override`,`--wifiMode`,t]),I(e);return}case`airplane`:v(o)?(await S(e,[`status_bar`,e.id,`override`,`--dataNetwork`,`hide`,`--wifiMode`,`failed`,`--wifiBars`,`0`,`--cellularMode`,`failed`,`--cellularBars`,`0`,`--operatorName`,``]),I(e)):(await S(e,[`status_bar`,e.id,`clear`]),L(e));return;case`location`:{if(o.toLowerCase()===`set`){let{latitude:t,longitude:n}=i(c);return await S(e,[`location`,e.id,`set`,`${t},${n}`]),{latitude:t,longitude:n}}let n=v(o);if(!s)throw new t(`INVALID_ARGS`,`location setting requires an active app in session`);let r=n?`grant`:`revoke`;await S(e,[`privacy`,e.id,r,`location`,s]);return}case`faceid`:case`touchid`:{let t=l,n=xt[t];await kt(e,Ot(o,t),{settingName:t,label:n.label,modalityAliases:n.modalityAliases});return}case`appearance`:{let t=await yt(e,o);await S(e,[`ui`,e.id,`appearance`,t]);return}case`permission`:if(!s)throw new t(`INVALID_ARGS`,`permission setting requires an active app in session`);await Ct(e,St(a(o)),Dt(c?.permissionTarget,c?.permissionMode),s);return;default:throw new t(`INVALID_ARGS`,`Unsupported setting: ${r}`)}}async function _t(e,n){if(!l(e)||e.kind!==`simulator`)throw new t(`UNSUPPORTED_OPERATION`,`Clearing app state is currently supported only on iOS simulators.`);let r=await j(e,n);await k(e),await Z(e,r);let i=m(await S(e,[`get_app_container`,e.id,r,`data`],{allowFailure:!0}),`simctl get_app_container failed for ${r}`).stdout.trim();if(!i)throw new t(`COMMAND_FAILED`,`simctl get_app_container returned an empty data container path for ${r}`);let a=await N.readdir(i);return await Promise.all(a.map(e=>N.rm(M.join(i,e),{recursive:!0,force:!0}))),{bundleId:r,containerPath:i}}function vt(e){let n=e?.trim().toLowerCase();if(n===`accessibility`||n===`screen-recording`||n===`input-monitoring`)return n;throw new t(`INVALID_ARGS`,`Unsupported macOS permission target. Use accessibility|screen-recording|input-monitoring.`)}async function yt(e,n){let r=te(n);if(r!==`toggle`)return r;let i=m(await S(e,[`ui`,e.id,`appearance`],{allowFailure:!0}),`Failed to read current iOS appearance`),a=bt(i.stdout,i.stderr);if(!a)throw new t(`COMMAND_FAILED`,`Unable to determine current iOS appearance for toggle`,{stdout:i.stdout,stderr:i.stderr});return a===`dark`?`light`:`dark`}function bt(e,t){let n=/\b(light|dark|unsupported|unknown)\b/i.exec(`${e}\n${t}`);if(!n)return null;let r=n[1]?.toLowerCase();return r===`dark`?`dark`:r===`light`?`light`:null}const xt={faceid:{label:`Face ID`,modalityAliases:[`face`]},touchid:{label:`Touch ID`,modalityAliases:[`finger`,`touch`]}};function St(e){return e===`deny`?`revoke`:e}async function Ct(e,n,r,i){let a=await Tt(e);if(!a.has(r))throw new t(`UNSUPPORTED_OPERATION`,`iOS simctl privacy does not support service "${r}" on this runtime.`,{deviceId:e.id,appBundleId:i,hint:`Supported services: ${Array.from(a).sort().join(`, `)}`});let o=[`privacy`,e.id,n,r,i],s=r===`notifications`;if(!(n===`reset`&&s))try{await S(e,o);return}catch(n){throw s&&wt(n)?new t(`UNSUPPORTED_OPERATION`,`iOS simulator does not support setting notifications permission via simctl privacy on this runtime.`,{deviceId:e.id,appBundleId:i,hint:`Use reset notifications for reprompt behavior, or toggle notifications manually in Settings.`}):n}try{await S(e,o);return}catch(e){if(!wt(e))throw e}try{await S(e,[`privacy`,e.id,`reset`,`all`,i])}catch(n){throw new t(`COMMAND_FAILED`,`iOS simulator blocked direct notifications reset. Fallback reset-all also failed.`,{deviceId:e.id,appBundleId:i,hint:`Use reinstall to force a fresh notifications prompt, or reset simulator content and settings.`},n instanceof Error?n:void 0)}}function wt(e){if(!(e instanceof t)||e.code!==`COMMAND_FAILED`)return!1;let n=String(e.details?.stderr??``).toLowerCase();return(n.includes(`failed to grant access`)||n.includes(`failed to revoke access`)||n.includes(`failed to reset access`))&&n.includes(`operation not permitted`)}async function Tt(e){let n=ie(e.simulatorSetPath),r=`${process.env.PATH??``}::${n??``}`;if($&&ht===r)return $;let i=await S(e,[`privacy`,`help`],{allowFailure:!0}),a=Et(`${i.stdout}\n${i.stderr}`);if(a.size===0)throw new t(`COMMAND_FAILED`,`Unable to determine supported simctl privacy services`,{stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode,hint:"Run `xcrun simctl privacy help` manually to verify available services for this runtime."});return $=a,ht=r,a}function Et(e){let t=new Set,n=!1;for(let r of e.split(`
|
|
5
|
+
`)){let e=r.trim();if(!e)continue;if(e===`service`){n=!0;continue}if(!n)continue;if(e.startsWith(`bundle identifier`))break;let i=/^([a-z-]+)\s+-\s+/.exec(e)?.[1];i!==void 0&&t.add(i)}return t}function Dt(e,n){let i=r(e);if(i!==`photos`&&n?.trim())throw new t(`INVALID_ARGS`,`Permission mode is only supported for photos. Received: ${n}.`);if(i===`camera`)return`camera`;if(i===`microphone`)return`microphone`;if(i===`contacts`)return`contacts`;if(i===`contacts-limited`)return`contacts-limited`;if(i===`notifications`)return`notifications`;if(i===`calendar`)return`calendar`;if(i===`location`)return`location`;if(i===`location-always`)return`location-always`;if(i===`media-library`)return`media-library`;if(i===`motion`)return`motion`;if(i===`reminders`)return`reminders`;if(i===`siri`)return`siri`;if(i===`photos`){let e=n?.trim().toLowerCase();if(!e||e===`full`)return`photos`;if(e===`limited`)return`photos-add`;throw new t(`INVALID_ARGS`,`Invalid photos mode: ${n}. Use full|limited.`)}throw new t(`INVALID_ARGS`,`Unsupported permission target: ${e}. Use camera|microphone|photos|contacts|contacts-limited|notifications|calendar|location|location-always|media-library|motion|reminders|siri.`)}function Ot(e,n){let r=e.trim().toLowerCase();if(r===`match`)return`match`;if(r===`nonmatch`)return`nonmatch`;if(r===`enroll`)return`enroll`;if(r===`unenroll`)return`unenroll`;throw new t(`INVALID_ARGS`,`Invalid ${n} state: ${e}. Use match|nonmatch|enroll|unenroll.`)}async function kt(e,n,r){let i=At(e.id,n,r.modalityAliases),a=[];for(let t of i){let n=C(e,t),r=await T(n,{allowFailure:!0});if(r.exitCode===0)return;a.push({args:n,stderr:r.stderr,stdout:r.stdout,exitCode:r.exitCode})}let o=ne(a);throw a.length>0&&a.every(e=>jt(e.stdout,e.stderr))?new t(`UNSUPPORTED_OPERATION`,`${r.label} simulation is not supported on this simulator runtime.`,{deviceId:e.id,action:n,setting:r.settingName,attempts:o}):new t(`COMMAND_FAILED`,`Failed to simulate ${r.settingName}.`,{deviceId:e.id,action:n,setting:r.settingName,attempts:o})}function At(e,t,n){let r=n.length>0?n:[`face`];switch(t){case`match`:return r.flatMap(t=>[[`biometric`,e,`match`,t],[`biometric`,`match`,e,t]]);case`nonmatch`:return r.flatMap(t=>[[`biometric`,e,`nonmatch`,t],[`biometric`,e,`nomatch`,t],[`biometric`,`nonmatch`,e,t],[`biometric`,`nomatch`,e,t]]);case`enroll`:return[[`biometric`,e,`enroll`,`yes`],[`biometric`,e,`enroll`,`1`],[`biometric`,`enroll`,e,`yes`],[`biometric`,`enroll`,e,`1`]];case`unenroll`:return[[`biometric`,e,`enroll`,`no`],[`biometric`,e,`enroll`,`0`],[`biometric`,`enroll`,e,`no`],[`biometric`,`enroll`,e,`0`]]}}function jt(e,t){let n=`${e}\n${t}`.toLowerCase();return n.includes(`unrecognized subcommand`)||n.includes(`unknown subcommand`)||n.includes(`not supported`)||n.includes(`unavailable`)||n.includes(`biometric`)&&n.includes(`invalid`)}var Mt=e({findIosSimulatorInstalledApp:()=>Ce,installIosApp:()=>lt,installIosInstallablePath:()=>dt,listIosApps:()=>ve,pushIosNotification:()=>mt,reinstallIosApp:()=>ut,resolveIosApp:()=>j,resolveIosSimulatorDeepLinkBundleId:()=>we});export{Z as a,W as c,pt as i,Ve as l,gt as n,et as o,ft as r,tt as s,Mt as t};
|
package/dist/src/audio-probe.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{c as e}from"./sdk-device.js";import{c as t}from"./helper.js";const n={platform:`host-system-audio`,source:`system-audio`,backend:`macos-screencapturekit`,sourceCount:1,start:t,notes:r};function r(t){return[`Audio probe samples host system audio through ScreenCaptureKit for this ${e(t)?`iOS simulator`:t.platform===`android`?`Android emulator`:`macOS session`}; it is not app-instrumented audio.`,`Screen Recording permission is required for host system audio capture.`,`Other audible host apps can contribute to the measured buckets.`]}export{n as macOsScreenCaptureKitAudioProbeBackend};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as e}from"./sdk-contracts.js";import{v as t}from"./sdk-android-adb.js";import n from"node:path";import r from"node:fs";async function i(t,n){let r=await t.text(),i={};if(r.trim().length>0)try{i=JSON.parse(r)}catch(r){throw new e(`COMMAND_FAILED`,n.invalidJsonMessage,{status:t.status},r instanceof Error?r:void 0)}if(!t.ok)throw new e(`UNAUTHORIZED`,n.rejectedMessage,{status:t.status,response:i});return i}const a=1e3;async function o(e){return await s({command:e.command,flags:e.flags,stateDir:e.stateDir,allowInteractiveLogin:e.command===`connect`&&!e.flags.noLogin,env:e.env})}async function s(t){let n=t.env??t.io?.env??process.env;if(!t.flags.daemonBaseUrl)return{flags:t.flags,source:`none`};if(A(t.flags.daemonAuthToken))return{flags:t.flags,source:`flag`};if(A(n.AGENT_DEVICE_DAEMON_AUTH_TOKEN))return{flags:t.flags,source:`env`};if(!T(t.flags.daemonBaseUrl,n))return{flags:t.flags,source:`none`};let r=await h({stateDir:t.stateDir,flags:t.flags,env:n,io:t.io});if(r)return{flags:{...t.flags,daemonAuthToken:r.accessToken},source:`cli-session`};if(!t.allowInteractiveLogin)throw t.flags.noLogin?new e(`UNAUTHORIZED`,`Remote daemon authentication is required.`,{hint:`Run agent-device auth login, unset --no-login, or set AGENT_DEVICE_DAEMON_AUTH_TOKEN.`}):C(t.command,n);let i=await l({stateDir:t.stateDir,flags:t.flags,env:n,io:t.io});return{flags:{...t.flags,daemonAuthToken:i.accessToken},source:`login`}}async function c(t){let n=t.env??t.io?.env??process.env;if(A(t.flags.daemonAuthToken))return{accessToken:t.flags.daemonAuthToken,cloudBaseUrl:w(n)};if(A(n.AGENT_DEVICE_DAEMON_AUTH_TOKEN))return{accessToken:n.AGENT_DEVICE_DAEMON_AUTH_TOKEN,cloudBaseUrl:w(n)};let r=await h({stateDir:t.stateDir,flags:t.flags,env:n,io:t.io});if(r)return{accessToken:r.accessToken,cloudBaseUrl:r.cloudBaseUrl};if(t.flags.noLogin)throw new e(`UNAUTHORIZED`,`Cloud connection profile authentication is required.`,{hint:`Run agent-device auth login, unset --no-login, or set AGENT_DEVICE_DAEMON_AUTH_TOKEN.`});let i=await l({stateDir:t.stateDir,flags:t.flags,env:n,io:t.io,commandLabel:`agent-device connect`});return{accessToken:i.accessToken,cloudBaseUrl:i.session.cloudBaseUrl}}async function l(t){let n=t.env??t.io?.env??process.env,r=b(n,t.io);if(r===`non-interactive`)throw C(t.commandLabel??`agent-device connect`,n);let i=w(n),a=await v({baseUrl:i,pathName:`/api/control-plane/device-auth/start`,body:{client:`agent-device`,tenant:t.flags.tenant,runId:t.flags.runId,daemonBaseUrl:t.flags.daemonBaseUrl,session:t.flags.session},fetchImpl:t.io?.fetch});y(a);let o=a.verificationUriComplete??a.verificationUri,s=r===`local-browser`?a.verificationUri:E(a.verificationUri,a.userCode);r===`local-browser`?(O(t.io,`Opening ${a.verificationUri}...\n`),await D(o,t.io)):O(t.io,`Open this URL on your machine:\n${s}\n\nWaiting for approval for 10 minutes...\n`);let c=await _({cloudBaseUrl:i,deviceCode:a.deviceCode,expiresIn:a.expiresIn,interval:a.interval,fetchImpl:t.io?.fetch,now:t.io?.now}),l=c.cliSession?.refreshCredential??c.cliSession?.refreshToken;if(!A(c.accessToken)||!A(l))throw new e(`UNAUTHORIZED`,`Device authorization did not return CLI credentials.`);let u=new Date(t.io?.now?.()??Date.now()).toISOString(),f={version:1,id:c.cliSession?.id??`cli-${Date.now().toString(36)}`,cloudBaseUrl:i,workspaceId:c.cliSession?.workspaceId,accountId:c.cliSession?.accountId,name:c.cliSession?.name,refreshCredential:l,createdAt:u,expiresAt:c.cliSession?.expiresAt};return d({stateDir:t.stateDir,session:f}),{accessToken:c.accessToken,expiresAt:c.expiresAt,session:f}}function u(e){let t=p(e.stateDir);if(!r.existsSync(t))return null;try{let e=JSON.parse(r.readFileSync(t,`utf8`));return e.version!==1||!A(e.id)||!A(e.cloudBaseUrl)||!A(e.refreshCredential)||!A(e.createdAt)?null:e}catch{return null}}function d(e){let t=p(e.stateDir);r.mkdirSync(n.dirname(t),{recursive:!0,mode:448}),r.writeFileSync(t,`${JSON.stringify(e.session,null,2)}\n`,{mode:384});try{r.chmodSync(t,384)}catch{}}function f(e){let t=p(e.stateDir);return r.existsSync(t)?(r.rmSync(t,{force:!0}),!0):!1}function p(e){return n.join(e,`auth`,`cli-session.json`)}function m(e){let t=u({stateDir:e.stateDir});return t?{authenticated:!0,source:`cli-session`,sessionId:t.id,cloudBaseUrl:t.cloudBaseUrl,workspaceId:t.workspaceId,accountId:t.accountId,name:t.name,createdAt:t.createdAt,expiresAt:t.expiresAt,expired:k(t.expiresAt,e.now)}:{authenticated:!1,source:`none`}}async function h(e){let t=u({stateDir:e.stateDir});return!t||k(t.expiresAt,e.io?.now)?null:{accessToken:(await g({session:t,flags:e.flags,env:e.env,io:e.io})).accessToken,cloudBaseUrl:w(e.env,t.cloudBaseUrl)}}async function g(t){let n=await v({baseUrl:w(t.env,t.session.cloudBaseUrl),pathName:`/api/control-plane/cli-session/refresh`,body:{refreshCredential:t.session.refreshCredential,tenant:t.flags.tenant,runId:t.flags.runId,daemonBaseUrl:t.flags.daemonBaseUrl,session:t.flags.session},fetchImpl:t.io?.fetch});if(A(n.accessToken))return{accessToken:n.accessToken,expiresAt:n.expiresAt};throw n.status===`revoked`||n.error===`revoked`?new e(`UNAUTHORIZED`,`Stored cloud CLI session was revoked.`,{hint:`Run agent-device auth login again, or set AGENT_DEVICE_DAEMON_AUTH_TOKEN.`,status:n.status,error:n.error}):new e(`UNAUTHORIZED`,`Failed to refresh CLI session.`,{hint:`Run agent-device auth login again, or set AGENT_DEVICE_DAEMON_AUTH_TOKEN.`,status:n.status,error:n.error})}async function _(t){let n=t.now??Date.now,r=Math.min((t.expiresIn??600)*1e3,6e5),i=n()+r,o=Math.max(a,(t.interval??5e3/1e3)*1e3);for(;n()<i;){let n=await v({baseUrl:t.cloudBaseUrl,pathName:`/api/control-plane/device-auth/poll`,body:{deviceCode:t.deviceCode},fetchImpl:t.fetchImpl});if(n.status===`approved`||A(n.accessToken))return n;if(n.status===`slow_down`||n.error===`slow_down`)o+=a;else if(n.status!==`authorization_pending`&&n.error!==`authorization_pending`)throw new e(`UNAUTHORIZED`,`Device authorization was not approved.`,{status:n.status,error:n.error});await j(o)}throw new e(`TIMEOUT`,`Device authorization expired before approval.`)}async function v(e){let t=await(e.fetchImpl??fetch)(new URL(e.pathName,e.baseUrl),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(e.body),signal:AbortSignal.timeout(15e3)});return await i(t,{invalidJsonMessage:`Cloud auth endpoint returned invalid JSON (${t.status}).`,rejectedMessage:`Cloud auth endpoint rejected the request.`})}function y(t){if(!A(t.deviceCode)||!A(t.userCode)||!A(t.verificationUri))throw new e(`COMMAND_FAILED`,`Cloud auth start returned an unusable response.`)}function b(e,t){let n=t?.stdinIsTTY??process.stdin.isTTY,r=t?.stdoutIsTTY??process.stdout.isTTY;return x(e)||!n||!r?`non-interactive`:S(e)?`device-code`:`local-browser`}function x(e){return e.CI===`true`||e.GITHUB_ACTIONS===`true`||e.BUILDKITE===`true`}function S(e){return!!(e.SSH_TTY||e.SSH_CONNECTION||e.CODESPACES===`true`||e.GITPOD_WORKSPACE_ID||e.REMOTE_CONTAINERS===`true`)}function C(t,n){let r=w(n);return new e(`UNAUTHORIZED`,`${t} cannot perform interactive login in CI or a non-interactive shell.`,{hint:`Create a service/API token: ${new URL(`/api-keys`,r).toString()} Then set AGENT_DEVICE_DAEMON_AUTH_TOKEN=adc_live_...`})}function w(t,n){let r=t.AGENT_DEVICE_CLOUD_BASE_URL??n??`https://cloud.agent-device.dev`;try{return new URL(r).toString().replace(/\/+$/,``)}catch(t){throw new e(`INVALID_ARGS`,`Invalid AGENT_DEVICE_CLOUD_BASE_URL.`,{cloudBaseUrl:r},t instanceof Error?t:void 0)}}function T(e,t){if(t.AGENT_DEVICE_CLOUD_AUTH===`1`||t.AGENT_DEVICE_CLOUD_AUTH===`true`||A(t.AGENT_DEVICE_CLOUD_BASE_URL))return!0;try{let t=new URL(e).hostname.toLowerCase();return t===`agent-device.dev`||t.endsWith(`.agent-device.dev`)}catch{return!1}}function E(e,t){let n=new URL(e);return n.searchParams.set(`user_code`,t),n.toString()}async function D(e,n){if(n?.openBrowser){await n.openBrowser(e);return}let r=process.platform;try{r===`darwin`?await t(`open`,[e],{allowFailure:!0,timeoutMs:5e3}):r===`win32`?await t(`cmd`,[`/c`,`start`,``,e],{allowFailure:!0,timeoutMs:5e3}):await t(`xdg-open`,[e],{allowFailure:!0,timeoutMs:5e3})}catch{O(n,`Open this URL on your machine:\n${e}\n`)}}function O(e,t){(e?.stderr??process.stderr).write(t)}function k(e,t){if(!e)return!1;let n=Date.parse(e);return Number.isFinite(n)?n<=(t?.()??Date.now()):!0}function A(e){return typeof e==`string`&&e.trim().length>0}async function j(e){await new Promise(t=>setTimeout(t,e))}export{m as a,o as i,f as n,i as o,c as r,l as t};
|
package/dist/src/auth.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{_ as e}from"./sdk-contracts.js";import{_ as t}from"./screenshot-result.js";import{a as n,n as r,t as i}from"./auth-session.js";import{t as a}from"./shared.js";const o=async({positionals:o,flags:c})=>{let l=o[0]??`status`,u=t(c.stateDir).baseDir;if(l===`status`){let e=n({stateDir:u});return a(c,e,()=>s(e)),!0}if(l===`login`){let e=await i({stateDir:u,flags:c,commandLabel:`agent-device auth login`});return a(c,{authenticated:!0,source:`cli-session`,sessionId:e.session.id,cloudBaseUrl:e.session.cloudBaseUrl,workspaceId:e.session.workspaceId,accountId:e.session.accountId,expiresAt:e.session.expiresAt,agentTokenExpiresAt:e.expiresAt},()=>`Authenticated with cloud CLI session.`),!0}if(l===`logout`){let e=r({stateDir:u});return a(c,{authenticated:!1,removed:e},()=>e?`Removed stored cloud CLI session.`:`No stored cloud CLI session.`),!0}throw new e(`INVALID_ARGS`,`auth accepts only: status, login, logout`)};function s(e){return e.authenticated?[`Authenticated with cloud CLI session.`,`cloud=${e.cloudBaseUrl}`,`session=${e.sessionId}`,e.workspaceId?`workspace=${e.workspaceId}`:null,e.accountId?`account=${e.accountId}`:null,e.expiresAt?`expiresAt=${e.expiresAt}`:null,e.expired?`status=expired`:null].filter(e=>!!e).join(`
|
|
2
|
+
`):`Not authenticated.`}export{o as authCommand};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{_ as e,v as t}from"./sdk-contracts.js";import{j as n}from"./sdk-android-adb.js";function r(e){return[`1`,`true`,`yes`,`on`].includes((e??``).trim().toLowerCase())}const i={maxAttempts:3,baseDelayMs:200,maxDelayMs:2e3,jitter:.2};var a=class e{startedAtMs;expiresAtMs;constructor(e,t){this.startedAtMs=e,this.expiresAtMs=e+Math.max(0,t)}static fromTimeoutMs(t,n=Date.now()){return new e(n,t)}remainingMs(e=Date.now()){return Math.max(0,this.expiresAtMs-e)}elapsedMs(e=Date.now()){return Math.max(0,e-this.startedAtMs)}isExpired(e=Date.now()){return this.remainingMs(e)<=0}};async function o(t,n={},r={}){let a={maxAttempts:n.maxAttempts??i.maxAttempts,baseDelayMs:n.baseDelayMs??i.baseDelayMs,maxDelayMs:n.maxDelayMs??i.maxDelayMs,jitter:n.jitter??i.jitter,shouldRetry:n.shouldRetry},o;for(let n=1;n<=a.maxAttempts;n+=1){if(r.signal?.aborted)throw new e(`COMMAND_FAILED`,`request canceled`,{reason:`request_canceled`});if(r.deadline?.isExpired()&&n>1)break;try{let e=await t({attempt:n,maxAttempts:a.maxAttempts,deadline:r.deadline});return r.onEvent?.({phase:r.phase,event:`succeeded`,attempt:n,maxAttempts:a.maxAttempts,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs()}),l({phase:r.phase,event:`succeeded`,attempt:n,maxAttempts:a.maxAttempts,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs()}),e}catch(e){o=e;let t=r.classifyReason?.(e),i={phase:r.phase,event:`attempt_failed`,attempt:n,maxAttempts:a.maxAttempts,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs(),reason:t};if(r.onEvent?.(i),l(i),n>=a.maxAttempts||a.shouldRetry&&!a.shouldRetry(e,n))break;let u=s(a.baseDelayMs,a.maxDelayMs,a.jitter,n),d=r.deadline?Math.min(u,r.deadline.remainingMs()):u;if(d<=0)break;let f={phase:r.phase,event:`retry_scheduled`,attempt:n,maxAttempts:a.maxAttempts,delayMs:d,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs(),reason:t};r.onEvent?.(f),l(f),await c(d,r.signal)}}let u={phase:r.phase,event:`exhausted`,attempt:a.maxAttempts,maxAttempts:a.maxAttempts,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs(),reason:r.classifyReason?.(o)};throw r.onEvent?.(u),l(u),o||new e(`COMMAND_FAILED`,`retry failed`)}function s(e,t,n,r){let i=Math.min(t,e*2**(r-1)),a=i*n;return Math.max(0,i+(Math.random()*2-1)*a)}function c(e,t){return new Promise(n=>{if(t?.aborted){n();return}let r=!1,i=()=>{r||(r=!0,t&&t.removeEventListener(`abort`,o),n())},a=setTimeout(i,e);function o(){clearTimeout(a),i()}t&&t.addEventListener(`abort`,o,{once:!0})})}function l(e){n({level:e.event===`attempt_failed`||e.event===`exhausted`?`warn`:`debug`,phase:`retry`,data:{...e}})}
|
|
2
|
-
`).toLowerCase();return r===`ios`&&d.includes(`0xe8008012`)?`IOS_RUNNER_DEVICE_NOT_PROVISIONED`:r===`ios`&&(d.includes(`provisioning profile`)||d.includes(`embedded profile`))?`BOOT_COMMAND_FAILED`:r===`ios`&&(d.includes(`runner did not accept connection`)||i===`connect`&&(d.includes(`timed out`)||d.includes(`timeout`)||d.includes(`econnrefused`)||d.includes(`connection refused`)||d.includes(`fetch failed`)||d.includes(`socket hang up`)))?`IOS_RUNNER_CONNECT_TIMEOUT`:r===`ios`&&i===`boot`&&(d.includes(`timed out`)||d.includes(`timeout`))?`IOS_BOOT_TIMEOUT`:r===`android`&&i===`boot`&&(d.includes(`timed out`)||d.includes(`timeout`))?`ANDROID_BOOT_TIMEOUT`:d.includes(`resource temporarily unavailable`)||d.includes(`killed: 9`)||d.includes(`cannot allocate memory`)||d.includes(`system is low on memory`)?`CI_RESOURCE_STARVATION_SUSPECTED`:r===`android`&&(d.includes(`device not found`)||d.includes(`no devices`)||d.includes(`device offline`)||d.includes(`offline`)||d.includes(`unauthorized`)||d.includes(`not authorized`)||d.includes(`unable to locate device`)||d.includes(`invalid device`))?`ADB_TRANSPORT_UNAVAILABLE`:n?.code===`COMMAND_FAILED`||d.length>0?`BOOT_COMMAND_FAILED`:`UNKNOWN`}function
|
|
1
|
+
import{_ as e,v as t}from"./sdk-contracts.js";import{j as n}from"./sdk-android-adb.js";function r(e){return[`1`,`true`,`yes`,`on`].includes((e??``).trim().toLowerCase())}const i={maxAttempts:3,baseDelayMs:200,maxDelayMs:2e3,jitter:.2};var a=class e{startedAtMs;expiresAtMs;constructor(e,t){this.startedAtMs=e,this.expiresAtMs=e+Math.max(0,t)}static fromTimeoutMs(t,n=Date.now()){return new e(n,t)}remainingMs(e=Date.now()){return Math.max(0,this.expiresAtMs-e)}elapsedMs(e=Date.now()){return Math.max(0,e-this.startedAtMs)}isExpired(e=Date.now()){return this.remainingMs(e)<=0}};async function o(t,n={},r={}){let a={maxAttempts:n.maxAttempts??i.maxAttempts,baseDelayMs:n.baseDelayMs??i.baseDelayMs,maxDelayMs:n.maxDelayMs??i.maxDelayMs,jitter:n.jitter??i.jitter,shouldRetry:n.shouldRetry},o;for(let n=1;n<=a.maxAttempts;n+=1){if(r.signal?.aborted)throw new e(`COMMAND_FAILED`,`request canceled`,{reason:`request_canceled`});if(r.deadline?.isExpired()&&n>1)break;try{let e=await t({attempt:n,maxAttempts:a.maxAttempts,deadline:r.deadline});return r.onEvent?.({phase:r.phase,event:`succeeded`,attempt:n,maxAttempts:a.maxAttempts,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs()}),l({phase:r.phase,event:`succeeded`,attempt:n,maxAttempts:a.maxAttempts,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs()}),e}catch(e){o=e;let t=r.classifyReason?.(e),i={phase:r.phase,event:`attempt_failed`,attempt:n,maxAttempts:a.maxAttempts,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs(),reason:t};if(r.onEvent?.(i),l(i),n>=a.maxAttempts||a.shouldRetry&&!a.shouldRetry(e,n))break;let u=s(a.baseDelayMs,a.maxDelayMs,a.jitter,n),d=r.deadline?Math.min(u,r.deadline.remainingMs()):u;if(d<=0)break;let f={phase:r.phase,event:`retry_scheduled`,attempt:n,maxAttempts:a.maxAttempts,delayMs:d,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs(),reason:t};r.onEvent?.(f),l(f),await c(d,r.signal)}}let u={phase:r.phase,event:`exhausted`,attempt:a.maxAttempts,maxAttempts:a.maxAttempts,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs(),reason:r.classifyReason?.(o)};throw r.onEvent?.(u),l(u),o||new e(`COMMAND_FAILED`,`retry failed`)}function s(e,t,n,r){let i=Math.min(t,e*2**(r-1)),a=i*n;return Math.max(0,i+(Math.random()*2-1)*a)}function c(e,t){return new Promise(n=>{if(t?.aborted){n();return}let r=!1,i=()=>{r||(r=!0,t&&t.removeEventListener(`abort`,o),n())},a=setTimeout(i,e);function o(){clearTimeout(a),i()}t&&t.addEventListener(`abort`,o,{once:!0})})}function l(e){n({level:e.event===`attempt_failed`||e.event===`exhausted`?`warn`:`debug`,phase:`retry`,data:{...e}})}const u=new Set([`IOS_BOOT_TIMEOUT`,`IOS_RUNNER_CONNECT_TIMEOUT`,`IOS_TOOL_MISSING`,`ANDROID_BOOT_TIMEOUT`,`ADB_TRANSPORT_UNAVAILABLE`,`CI_RESOURCE_STARVATION_SUSPECTED`]);function d(e){return u.has(e.toUpperCase())}function f(e){let n=e.error?t(e.error):null,r=e.context?.platform,i=e.context?.phase;if(n?.code===`TOOL_MISSING`)return r===`android`?`ADB_TRANSPORT_UNAVAILABLE`:`IOS_TOOL_MISSING`;let a=n?.details??{},o=typeof a.message==`string`?a.message:void 0,s=typeof a.stdout==`string`?a.stdout:void 0,c=typeof a.stderr==`string`?a.stderr:void 0,l=a.boot&&typeof a.boot==`object`?a.boot:null,u=a.bootstatus&&typeof a.bootstatus==`object`?a.bootstatus:null,d=[e.message,n?.message,e.stdout,e.stderr,o,s,c,typeof l?.stdout==`string`?l.stdout:void 0,typeof l?.stderr==`string`?l.stderr:void 0,typeof u?.stdout==`string`?u.stdout:void 0,typeof u?.stderr==`string`?u.stderr:void 0].filter(Boolean).join(`
|
|
2
|
+
`).toLowerCase();return r===`ios`&&d.includes(`0xe8008012`)?`IOS_RUNNER_DEVICE_NOT_PROVISIONED`:r===`ios`&&(d.includes(`provisioning profile`)||d.includes(`embedded profile`))?`BOOT_COMMAND_FAILED`:r===`ios`&&(d.includes(`runner did not accept connection`)||i===`connect`&&(d.includes(`timed out`)||d.includes(`timeout`)||d.includes(`econnrefused`)||d.includes(`connection refused`)||d.includes(`fetch failed`)||d.includes(`socket hang up`)))?`IOS_RUNNER_CONNECT_TIMEOUT`:r===`ios`&&i===`boot`&&(d.includes(`timed out`)||d.includes(`timeout`))?`IOS_BOOT_TIMEOUT`:r===`android`&&i===`boot`&&(d.includes(`timed out`)||d.includes(`timeout`))?`ANDROID_BOOT_TIMEOUT`:d.includes(`resource temporarily unavailable`)||d.includes(`killed: 9`)||d.includes(`cannot allocate memory`)||d.includes(`system is low on memory`)?`CI_RESOURCE_STARVATION_SUSPECTED`:r===`android`&&(d.includes(`device not found`)||d.includes(`no devices`)||d.includes(`device offline`)||d.includes(`offline`)||d.includes(`unauthorized`)||d.includes(`not authorized`)||d.includes(`unable to locate device`)||d.includes(`invalid device`))?`ADB_TRANSPORT_UNAVAILABLE`:n?.code===`COMMAND_FAILED`||d.length>0?`BOOT_COMMAND_FAILED`:`UNKNOWN`}function p(e){switch(e){case`IOS_BOOT_TIMEOUT`:return`Retry simulator boot and inspect simctl bootstatus logs; in CI reduce parallel jobs or use a larger runner.`;case`IOS_RUNNER_CONNECT_TIMEOUT`:return`Retry runner startup, inspect xcodebuild logs, and verify simulator responsiveness before command execution.`;case`IOS_RUNNER_DEVICE_NOT_PROVISIONED`:return`The XCTest runner cannot be installed on this device: its provisioning profile does not cover it. Register the device with the signing team (Xcode > Settings > Accounts, or add its UDID to the provisioning profile) and retry. Retrying without that will keep failing.`;case`ANDROID_BOOT_TIMEOUT`:return`Retry emulator startup and verify sys.boot_completed reaches 1; consider increasing startup budget in CI.`;case`ADB_TRANSPORT_UNAVAILABLE`:return`Check adb server/device transport (adb devices -l), restart adb, and ensure the target device is online and authorized.`;case`CI_RESOURCE_STARVATION_SUSPECTED`:return`CI machine may be resource constrained; reduce parallel jobs or use a larger runner.`;case`IOS_TOOL_MISSING`:return`Xcode command-line tools are missing or not in PATH; run xcode-select --install and verify xcrun works.`;case`BOOT_COMMAND_FAILED`:return`Inspect command stderr/stdout for the failing boot phase and retry after environment validation.`;default:return`Retry once and inspect verbose logs for the failing phase.`}}export{r as a,a as i,f as n,o,d as r,p as t};
|
package/dist/src/cli-config.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{_ as e}from"./sdk-contracts.js";import{
|
|
1
|
+
import{_ as e}from"./sdk-contracts.js";import{Tt as t}from"./version.js";import{Qt as n}from"./prepare-kind.js";import{S as r,d as i,l as a}from"./registry.js";import{E as o,O as s}from"./sdk-android-adb.js";import{n as c,t as l}from"./path-resolution.js";import{r as u}from"./command-schema.js";import d from"node:path";import f from"node:fs";function p(e,t){for(let[n,r]of Object.entries(t))r!==void 0&&(e[n]=r);return e}const m=new Set([`config`,`remoteConfig`,`help`,`version`,`batchSteps`,`githubActionsArtifact`]),h=new Set([`appsFilter`,`iosSimulatorDeviceSet`]),g=S(),_=new Map(g.map(e=>[e.key,e]));function v(e){return _.get(e)}function y(e){return g.filter(t=>t.configurable&&t.supportsCommand(e))}function b(e,t){return v(e)?.supportsCommand(t)??!1}function x(e,t,n,r){return s(T(e),t,n,r)}function S(){let e=new Map;for(let t of r()){let n=e.get(t.key);n?n.push(t):e.set(t.key,[t])}let t=new Map;for(let e of i)t.set(e,new Set([`*`]));for(let e of n()){let n=u(e);for(let r of[...n.allowedFlags??[],...n.supportedFlags??[]]){let n=t.get(r);n&&n.has(`*`)||(n?n.add(e):t.set(r,new Set([e])))}}return[...e.entries()].map(([e,n])=>({key:e,flagDefinitions:n,configurable:!m.has(e),env:{names:h.has(e)?[]:[o(e)]},supportsCommand(n){let r=t.get(e);return r?r.has(`*`)?!0:n?r.has(n):!1:!1}})).sort((e,t)=>C(e.key,t.key))}function C(e,t){let n=e.toLowerCase(),r=t.toLowerCase();return n===r?e<t?-1:+(e>t):n<r?-1:1}function w(e){let t=e.flagDefinitions[0];if(!t)throw Error(`Missing flag definition for option ${e.key}`);return t}function T(e){let t=e.flagDefinitions.find(e=>e.setValue===void 0);if(t)return t;let n=w(e);if(n.type===`enum`){let t=n.enumValues??e.flagDefinitions.map(e=>e.setValue).filter(e=>e!==void 0);return{...n,setValue:void 0,enumValues:t}}return n}function E(e){let t=e.env??process.env;return p(p({},j(O(e.cwd,e.cliFlags.config,t))),F(t,e.command))}const D=new Set(`json.platform.target.device.udid.serial.session.sessionLock.activity.launchArgs.launchUrl.remote.deviceHub.testIme.appsFilter.clean.force.stale.relaunch.shutdown.surface.headless.restart.noRecord.record.recordAs.snapshotInteractiveOnly.snapshotDiff.snapshotDepth.snapshotScope.snapshotRaw.snapshotCustomActions.snapshotForceFull.screenshotPixelDensity.screenshotFullscreen.screenshotScale.screenshotNoStabilize.screenshotNormalizeStatusBar.overlayRefs.networkInclude.baseline.threshold.count.pointerCount.fps.quality.hideTouches.recordingScope.intervalMs.delayMs.durationMs.holdMs.jitterPx.pixels.doubleTap.verify.settle.settleQuietMs.clickButton.backMode.pauseMs.pattern.kind.perfTemplate.responseLevel.verbose.cost.timeoutMs.retries.failFast.recordVideo.replayUpdate.replayMaestro.replayFrom.replayPlanDigest.replayKeepSession.findFirst.findLast.batchOnError.batchMaxSteps.retainPaths.retentionMs.shardAll.shardSplit.noLogin`.split(`.`));function O(e,t,n){let r=t??n.AGENT_DEVICE_CONFIG;return r?[{path:A(r,e,n),required:!0,source:`explicit`}]:[{path:k(n),required:!1,source:`user`},{path:d.resolve(e,`agent-device.json`),required:!1,source:`project`}]}function k(e){return d.join(l(`~`,{env:e}),`.agent-device`,`config.json`)}function A(e,t,n){return c(e,{cwd:t,env:n})}function j(e){let t={};for(let n of e)p(t,M(n));return t}function M(t){let{path:n,required:r}=t;if(!f.existsSync(n)){if(r)throw new e(`INVALID_ARGS`,`Config file not found: ${n}`);return{}}let i;try{i=f.readFileSync(n,`utf8`)}catch(t){throw new e(`INVALID_ARGS`,`Failed to read config file: ${n}`,{cause:t instanceof Error?t.message:String(t)})}let a;try{a=JSON.parse(i)}catch(t){throw new e(`INVALID_ARGS`,`Invalid JSON in config file: ${n}`,{cause:t instanceof Error?t.message:String(t)})}if(!a||typeof a!=`object`||Array.isArray(a))throw new e(`INVALID_ARGS`,`Config file must contain a JSON object: ${n}`);return N(a,{source:t.source,label:`${t.source===`project`?`project `:``}config file ${n}`})}function N(n,r){let i={};for(let[o,s]of Object.entries(n)){let n=o,c=v(n);if(!c)throw o===t.flagKey?new e(`INVALID_ARGS`,`Config key "${o}" in ${r.label} was removed; use "screenshotScale" (0.01-1) to downscale screenshots. Recordings capture at native resolution.`):new e(`INVALID_ARGS`,`Unknown config key "${o}" in ${r.label}.`);if(!c.configurable)throw new e(`INVALID_ARGS`,`Config key "${o}" is not allowed in ${r.label}. This key is not supported in config files.`);if(r.source===`project`&&!D.has(n))throw new e(`INVALID_ARGS`,`Config key "${o}" is not allowed in ${r.label}. Move it to ~/.agent-device/config.json, pass it with --config or AGENT_DEVICE_CONFIG, or provide it through CLI flags/environment variables.`);if(n===`installSource`){i.installSource=a(s,r.label);continue}i[n]=x(c,s,r.label,o)}return i}const P=new Set([`screenshot`,`record`]);function F(n,r){let i=n[t.envVar];if(r!==null&&P.has(r)&&typeof i==`string`&&i.trim().length>0)throw new e(`INVALID_ARGS`,`${t.envVar} was removed. ${t.migration[r===`record`?`record`:`screenshot`]}`);let a={};for(let e of y(r)){if(e.key===`installSource`)continue;let t=e.env.names.map(e=>({name:e,value:n[e]})).find(e=>typeof e.value==`string`&&e.value.trim().length>0);t&&(a[e.key]=x(e,t.value,`environment variable ${t.name}`,t.name))}return a}export{b as n,p as r,E as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{n as e}from"./registry.js";const t=e();function n(e,n,r){let i=t[e];if(!i)throw Error(`Missing CLI reader for command: ${e}`);return i(n,r)}export{n as t};
|