agent-device 0.21.11 → 0.21.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.11.apk → agent-device-android-ime-helper-0.21.13.apk} +0 -0
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.13.apk.sha256 +1 -0
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.11.manifest.json → agent-device-android-ime-helper-0.21.13.manifest.json} +4 -4
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.11.apk → agent-device-android-snapshot-helper-0.21.13.apk} +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.13.apk.sha256 +1 -0
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.11.manifest.json → agent-device-android-snapshot-helper-0.21.13.manifest.json} +6 -6
- package/apple/fold-helper/Fold.m +97 -0
- package/apple/macos-helper/Package.swift +3 -6
- package/apple/macos-helper/Sources/AgentDeviceMacOSHelper/main.swift +3 -8
- package/apple/macos-helper/Tests/AgentDeviceMacOSHelperTests/ScreenshotResponseTests.swift +15 -0
- package/apple/snapshot-bridge/SnapshotBridgeRuntime.m +47 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunner/AgentDeviceRunnerApp.m +99 -42
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunner/Info.plist +23 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/project.pbxproj +17 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAppScreenCapture.swift +21 -13
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerScrollViewportPolicy.swift +1 -162
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.h +0 -9
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.m +0 -56
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSystemSurfaceHostPolicy.swift +0 -48
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTapPointPolicy.swift +0 -50
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +22 -568
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift +21 -9
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+BlockingSystemModalResolution.swift +0 -36
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandDispatch.swift +630 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +18 -2236
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +1 -338
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Environment.swift +0 -12
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+GestureExecution.swift +165 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +0 -24
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Keyboard.swift +0 -142
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +90 -39
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+MainThreadWork.swift +78 -106
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +23 -2
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Navigation.swift +147 -95
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+PrivateAXPresentation.swift +0 -209
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScreenRecorder.swift +86 -10
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollDragExecution.swift +287 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollGesture.swift +1 -200
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SequenceExecution.swift +0 -185
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +75 -285
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotAcquisition.swift +23 -10
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotBackendCapabilities.swift +0 -78
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +83 -578
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCaptureTarget.swift +106 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotExecution.swift +142 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotTiming.swift +49 -78
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedCommitDeadline.swift +0 -44
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedGesturePolicy.swift +27 -97
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedInteraction.swift +1 -11
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedTextEntry.swift +11 -87
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SystemModal.swift +2 -10
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +1 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntryFocus.swift +0 -35
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextInputCandidatePolicy.swift +0 -31
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextTyping.swift +2 -18
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Transport.swift +34 -52
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TvRemote.swift +0 -22
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TypeExecution.swift +142 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +22 -6
- package/dist/apple/runner/AgentDeviceRunner/RecordingScripts/recording-overlay.swift +140 -20
- package/dist/src/absence-observation-errors.js +1 -1
- package/dist/src/adapter.js +1 -1
- package/dist/src/agent-device-client.js +1 -1
- package/dist/src/alert-runtime.js +1 -1
- package/dist/src/android-adb.d.ts +1 -1
- package/dist/src/app-launch.js +2 -2
- package/dist/src/app-log-runtime2.js +3 -3
- package/dist/src/app-resolution.js +2 -2
- package/dist/src/back-mode.js +1 -1
- package/dist/src/capture-disclosure.js +1 -1
- package/dist/src/capture.js +1 -1
- package/dist/src/cli-config.js +1 -1
- package/dist/src/cli-help.js +10 -7
- package/dist/src/cli-runner.js +1 -1
- package/dist/src/cli.js +1 -1
- package/dist/src/client-types.d.ts +5 -8
- package/dist/src/code-signature.js +1 -1
- package/dist/src/command-schema.js +3 -3
- package/dist/src/command-tools.js +3 -3
- package/dist/src/connection.js +1 -1
- package/dist/src/daemon-client-lifecycle.js +1 -1
- package/dist/src/daemon-resolution.js +1 -1
- package/dist/src/device-claim-rule.js +2 -2
- package/dist/src/device-input-state.d.ts +1 -1
- package/dist/src/device-rotation.js +1 -1
- package/dist/src/device-session.js +1 -1
- package/dist/src/devicectl.js +1 -1
- package/dist/src/display-inventory.js +1 -1
- package/dist/src/doctor-facade.js +1 -1
- package/dist/src/find.js +1 -1
- package/dist/src/gesture-plan-types.d.ts +38 -0
- package/dist/src/harmonyos.js +1 -1
- package/dist/src/helper.js +2 -2
- package/dist/src/host.js +1 -1
- package/dist/src/install-source-network-transport.js +1 -1
- package/dist/src/install-source2.js +1 -1
- package/dist/src/interaction-ref-policy.js +1 -1
- package/dist/src/interaction2.js +1 -1
- package/dist/src/interactor-operation-catalog.js +1 -1
- package/dist/src/interactor.js +4 -4
- package/dist/src/interactor2.js +1 -1
- package/dist/src/internal/bin.js +1 -1
- package/dist/src/internal/daemon.js +2 -2
- package/dist/src/inventory2.js +1 -1
- package/dist/src/ios-snapshot-acquisition.js +1 -1
- package/dist/src/ios-snapshot-runtime.js +1 -1
- package/dist/src/limrun-runtime-dependencies.js +1 -1
- package/dist/src/limrun.d.ts +435 -4
- package/dist/src/linux.js +1 -1
- package/dist/src/local-interactor-operation-set.js +1 -1
- package/dist/src/macos-facade.js +1 -1
- package/dist/src/managed-device-scope.js +1 -1
- package/dist/src/mechanics.js +4 -4
- package/dist/src/mobile-snapshot-semantics.js +1 -1
- package/dist/src/perf-facade.js +1 -2
- package/dist/src/perf-runtime-plan.js +1 -1
- package/dist/src/perf-target.js +2 -0
- package/dist/src/physical-device-apps.js +1 -0
- package/dist/src/physical-device-control.js +1 -1
- package/dist/src/platform-request-scope.js +1 -1
- package/dist/src/platform-runtime-operation-host.js +1 -1
- package/dist/src/platform-runtime-screen-recording-finalizer-host.js +1 -1
- package/dist/src/platform-runtime-unavailable.js +1 -1
- package/dist/src/platform-runtime.js +1 -1
- package/dist/src/platform-runtime2.js +1 -1
- package/dist/src/provider-webdriver.js +1 -1
- package/dist/src/proxy.js +1 -1
- package/dist/src/quality-warnings.js +1 -1
- package/dist/src/react-native.js +1 -1
- package/dist/src/record-runtime.js +1 -1
- package/dist/src/registry.js +35 -35
- package/dist/src/request-admission.js +1 -1
- package/dist/src/request-runtime-binding.js +1 -1
- package/dist/src/runner-client.js +1 -1
- package/dist/src/runner-dev-tools-security.js +1 -1
- package/dist/src/runner-device-readiness.js +1 -1
- package/dist/src/runner-disposal.js +1 -1
- package/dist/src/runner-error-classification.js +3 -0
- package/dist/src/runner-operations-facade.js +1 -1
- package/dist/src/runner-presentation.js +1 -1
- package/dist/src/runner.js +1 -1
- package/dist/src/runtime.js +3 -3
- package/dist/src/runtime10.js +1 -1
- package/dist/src/runtime2.js +2 -2
- package/dist/src/runtime4.js +5 -5
- 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 -1
- package/dist/src/runtime9.js +1 -1
- package/dist/src/screen-recording-admission-ledger.js +1 -1
- package/dist/src/screen-recording-resource-recovery.js +1 -1
- package/dist/src/screen-recording-transport.js +1 -1
- package/dist/src/screenshot-runtime.js +1 -1
- package/dist/src/screenshot3.js +1 -1
- package/dist/src/script.js +1 -1
- package/dist/src/scroll-command.d.ts +377 -0
- package/dist/src/scroll-command.js +1 -1
- package/dist/src/sdk-batch.js +2 -2
- package/dist/src/sdk-contracts.d.ts +9 -0
- package/dist/src/sdk-device.js +1 -1
- package/dist/src/sdk-selectors.d.ts +23 -715
- package/dist/src/selection.js +0 -0
- package/dist/src/selector-runtime.js +1 -1
- package/dist/src/semantic-index.js +1 -1
- package/dist/src/server.js +1 -1
- package/dist/src/session-observation.js +1 -1
- package/dist/src/session-snapshot.js +1 -1
- package/dist/src/session2.js +2 -2
- package/dist/src/simctl-facade.js +1 -1
- package/dist/src/simctl.js +1 -1
- package/dist/src/simulator-facade.js +1 -1
- package/dist/src/simulator-state.js +1 -1
- package/dist/src/simulator.js +1 -1
- package/dist/src/snapshot-runtime-binding.js +1 -1
- package/dist/src/snapshot-runtime.js +1 -1
- package/dist/src/snapshot-state.js +1 -1
- package/dist/src/snapshot4.js +1 -1
- package/dist/src/src7.js +1 -1
- package/dist/src/text-entry-focus.js +1 -1
- package/dist/src/tool-provider.js +1 -1
- package/dist/src/touch-runtime.js +1 -1
- package/dist/src/tree.js +1 -1
- package/dist/src/update-check.js +1 -1
- package/dist/src/version.js +1 -1
- package/dist/src/web2.js +1 -1
- package/package.json +4 -2
- package/server.json +2 -2
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.11.apk.sha256 +0 -1
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.11.apk.sha256 +0 -1
- package/apple/macos-helper/Sources/AgentDeviceMacOSDeviceHub/DeviceHubPose.swift +0 -47
- package/apple/macos-helper/Sources/AgentDeviceMacOSDeviceHub/DeviceHubWindowInventory.swift +0 -65
- package/apple/macos-helper/Sources/AgentDeviceMacOSHelper/DeviceHubPose.swift +0 -225
- package/apple/macos-helper/Sources/AgentDeviceMacOSHelper/DeviceHubSidebar.swift +0 -57
- package/apple/macos-helper/Sources/AgentDeviceMacOSHelper/DeviceHubWindowDiscovery.swift +0 -108
- package/apple/macos-helper/Tests/AgentDeviceMacOSDeviceHubTests/DeviceHubPoseTests.swift +0 -30
- package/apple/macos-helper/Tests/AgentDeviceMacOSDeviceHubTests/DeviceHubWindowInventoryTests.swift +0 -65
- package/dist/src/app-inventory.d.ts +0 -4
- package/dist/src/apps-simctl.js +0 -1
- package/dist/src/cloud-artifacts.d.ts +0 -61
- package/dist/src/runner-contract.js +0 -3
package/dist/src/runtime6.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{D as e}from"./sdk-contracts.js";import{E as t}from"./sdk-device.js";import{Yt as n,tn as r}from"./sdk-batch.js";import{n as i}from"./device-shell.js";import{n as a,t as o}from"./application-lifecycle-runtime.js";import{A as s,D as c,G as l,H as u,I as d,L as f,N as p,O as ee,P as te,R as ne,T as re,U as ie,a as ae,b as oe,g as se,j as ce,o as le,p as ue,t as de,u as fe,v as m,w as h,x as g,z as pe}from"./alert-runtime.js";import{n as me}from"./audio-probe-runtime.js";import{n as he}from"./perf-runtime.js";import{i as ge,t as _e}from"./touch-runtime.js";import{a as _,n as v}from"./durable-resource.js";import{n as ve}from"./async-lifecycle.js";import{i as ye,r as be}from"./src7.js";import{n as xe,t as y}from"./screen-recording-completion.js";import{t as b}from"./screen-recording-options.js";import{n as x}from"./screen-recording-runtime.js";import{i as S}from"./gesture-admission.js";import{t as C}from"./interactor-operation-catalog.js";import{i as w,n as T}from"./perf-runtime-operation-builder.js";import{t as E}from"./app-log-runtime.js";import{n as D,t as O}from"./application-lifecycle-interaction.js";import{randomUUID as k}from"node:crypto";import{setTimeout as A}from"node:timers/promises";const j=Object.freeze({resourceKind:E,version:1,encode:e=>({...e}),decode:e=>e.transport!==`harmony-hilog`||!N(e.outputPath)||!N(e.pidPath)?{status:`invalid`,message:`Invalid HarmonyOS app-log descriptor`}:{status:`decoded`,descriptor:Object.freeze({transport:`harmony-hilog`,outputPath:e.outputPath,pidPath:e.pidPath})}});function M(e){return v({resourceKind:E,sessionId:e.sessionId,device:{id:e.device.id,family:`harmonyos`,kind:e.device.kind,...e.device.target===void 0?{}:{target:e.device.target}},owner:e.owner,fence:e.fence,lifecycle:`open`,descriptor:_(j,e.descriptor)})}function N(e){return typeof e==`string`&&e.trim().length>0}function Se(e){return be(e,{family:`harmonyos`,backend:`harmonyos`,label:`HarmonyOS`,codec:j,startUnavailableHint:`The selected HarmonyOS transport cannot start a background hilog stream.`,cleanupFailureMessage:`HarmonyOS app-log cleanup did not settle every owned resource`,doctor:async(e,t)=>({backend:`harmonyos`,checks:{},notes:t?[]:[`No app bundle is tracked in this session. Run open <app> first for app-scoped logs.`]}),process:async({host:e,device:t,input:n,signal:r})=>{let a=await Ce(e,r);return{resolvePid:async r=>await ye(e,{executable:a,args:i(`hdc`,`shell`,[`pidof`,n.appBundleId],[`-t`,t.id]),allowFailure:!0,timeoutMs:5e3},r),command:e=>({kind:`host`,request:{executable:a,args:i(`hdc`,`shell`,[`hilog`,`-P`,e],[`-t`,t.id]),allowFailure:!0}})}},descriptor:({artifacts:e})=>({transport:`harmony-hilog`,...e}),envelope:({input:e,device:t,owner:n,descriptor:r})=>M({sessionId:e.sessionId,device:t,owner:n,fence:e.fence,descriptor:r})})}async function Ce(t,n){n.throwIfAborted(),await P(async()=>await t.toolchains.prepare(`harmonyos`),n),n.throwIfAborted();let r=await P(async()=>await t.commands.which(`hdc`),n);if(n.throwIfAborted(),!r)throw new e(`TOOL_MISSING`,`hdc not found in PATH`,{hint:`Install HarmonyOS Command Line Tools, then add its sdk/default/openharmony/toolchains directory to PATH.`});return r}async function P(e,t){try{return await e()}catch(e){throw t.throwIfAborted(),e}}function we(e){let{resolveHost:t,device:n}=e,r={available:!1,reason:`Dropped-frame sampling is currently available only on Android app sessions and connected iOS device app sessions.`};return Object.freeze({perfFrames:async()=>({metric:r,sampling:r}),perfMemorySample:async({appId:e})=>({metric:e?await w(t().sampleMemory(n,e)):T(`HarmonyOS`,`bundle`),sampling:{method:`hdc-shell-proc-status`,description:`Resident memory snapshot from HarmonyOS /proc/<pid>/status. Values are reported in kilobytes.`,unit:`kB`,topConsumerLimit:1}}),perfMemorySnapshot:async({kind:e})=>({artifact:{available:!1,kind:e??`memgraph`,reason:`Memory snapshot artifacts are not supported on harmonyos.`,hint:`Use perf memory sample where supported, or run the snapshot against Android, iOS simulator, or macOS.`,support:{platform:`harmonyos`,defaultKind:`memgraph`,androidHprof:!1,memgraph:!1,heapprofd:!1}},sampling:{method:`unsupported`,description:`HarmonyOS memory snapshot capture is not available through HDC.`,artifactOnly:!0}})})}const F=Object.freeze({resourceKind:x,version:1,encode:e=>({...e}),decode:e=>e.backend===`harmony-screen-recorder`&&typeof e.fileName==`string`&&De(e.fileName)&&e.remotePath===`/data/local/tmp/${e.fileName}`?{status:`decoded`,descriptor:Object.freeze({backend:`harmony-screen-recorder`,fileName:e.fileName,remotePath:e.remotePath})}:{status:`invalid`,message:`Invalid HarmonyOS screen-recording descriptor`}});function Te(e){let{device:n,owner:r,input:i,descriptor:a}=e;return v({resourceKind:x,sessionId:i.sessionId,device:t(n),owner:r,fence:i.fence,lifecycle:`open`,descriptor:_(F,a)})}function Ee(e){return F.decode(e).status===`decoded`?{status:`cleanup-pending`,reason:`manual-recovery-required`,message:`HarmonyOS recorder ownership cannot be proven after daemon restart; no recorder was stopped.`}:{status:`cleanup-pending`,reason:`manual-recovery-required`}}function De(e){return/^agent-device-recording-[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}\.mp4$/i.test(e)}function Oe(e){return e.kind===`device`?Object.freeze({available:!0}):Object.freeze({available:!1,reason:`unsupported-device-kind`,hint:`HarmonyOS recording is supported on physical devices only.`})}function ke(e){let{host:t,device:n,owner:r,signal:i}=e;return Object.freeze({screenRecordingStart:async e=>await Ae({host:t,device:n,owner:r,input:e,signal:i}),screenRecordingReattach:async()=>({status:`unreattachable`,reason:`transport-not-reattachable`,message:`HarmonyOS recordings cannot be reattached after daemon restart.`}),screenRecordingCleanup:async e=>Ee(e.envelope.descriptor.body)})}async function Ae(t){let{host:n,device:r,owner:i,input:a,signal:o}=t;if(a.scope===`app`)throw new e(`INVALID_ARGS`,`HarmonyOS recording captures the whole physical-device screen; use --scope device or --scope system`);b(a,{scopes:[`device`,`system`],fps:!1,exportQuality:!1,hideTouches:!1},e=>`HarmonyOS recordings do not support ${e.join(`, `)}`),o.throwIfAborted(),await n.screenRecording.outputs.prepare(a.outputPath);let s=`agent-device-recording-${k()}.mp4`,c={backend:`harmony-screen-recorder`,fileName:s,remotePath:`/data/local/tmp/${s}`},l;try{l=await n.screenRecording.harmony.start(r,s,o),o.throwIfAborted()}catch(e){throw o.aborted?(await R(n,r,c).catch(()=>{}),o.reason):e}B(l,`start`);try{o.throwIfAborted()}catch(e){throw await R(n,r,c).catch(()=>{}),e}let u=je(a),d=!1,f=async()=>{d||=(B(await n.screenRecording.harmony.stop(r),`stop`),!0)},p=xe(u,{finish:async e=>await Me(n,r,e,c,f),forceCleanup:async()=>await R(n,r,c,f)});return Object.freeze({pendingHandle:new ve(p),envelope:Te({device:r,owner:i,input:a,descriptor:c})})}function je(e){return Object.freeze({backend:`HarmonyOS ScreenRecorder`,outPath:e.outputPath,...e.clientOutputPath===void 0?{}:{clientOutPath:e.clientOutputPath},startedAt:Date.now(),scope:e.scope,showTouches:!1,recordOnlySession:e.recordOnlySession,...e.activeSessionApp===void 0?{}:{activeSessionApp:e.activeSessionApp},gestureEvents:[]})}async function Me(e,t,n,r,i){await i();let a=await e.screenRecording.harmony.findMedia(t,r.fileName);if(!a)throw Error(`failed to find finalized HarmonyOS recording '${r.fileName}'`);if(!await Pe(e,t,r,a))throw Error(`failed to finalize HarmonyOS recording: ${r.fileName} did not produce a non-empty media file`);try{if((await e.screenRecording.harmony.pull(t,{remotePath:r.remotePath,outputPath:n.outPath})).exitCode!==0)throw Error(`failed to retrieve HarmonyOS recording`);let i=await e.screenRecording.finalize.complete({outputPath:n.outPath,showTouches:!1,gestureEvents:n.gestureEvents,targetLabel:`HarmonyOS recording`}),o=await Ne(e,t,r,a);return y(n,{...i,...L(i.warning,o)},{stopObservation:{recorder:`confirmed`},nativePathDisposition:o===void 0?`retired`:`retirable`,showTouches:!1})}catch(n){throw await e.screenRecording.harmony.remove(t,r.remotePath).catch(()=>{}),n}}async function Ne(e,t,n,r){let i=[];return await I(()=>e.screenRecording.harmony.remove(t,n.remotePath))||i.push(`staging artifact`),await I(()=>e.screenRecording.harmony.removeMedia(t,r))||i.push(`media-library artifact`),i.length===0?void 0:`HarmonyOS recording completed, but cleanup was not confirmed for the ${i.join(` and `)}.`}async function I(e){try{return await e()}catch{return!1}}function L(e,t){let n=[e,t].filter(e=>e!==void 0).join(` `);return n.length===0?{}:{warning:n}}async function Pe(e,t,n,r){let i;for(let a=0;a<40;a+=1){if(await e.screenRecording.harmony.remove(t,n.remotePath).catch(()=>{}),await e.screenRecording.harmony.stageMedia(t,{mediaUri:r,remotePath:n.remotePath})){let r=await e.screenRecording.harmony.stagedFileSize(t,n.remotePath);if(r!==void 0&&r>0&&r===i)return!0;i=r!==void 0&&r>0?r:void 0}else i=void 0;a<39&&await e.clock.sleep(250)}return!1}async function R(e,t,n,r=async()=>{B(await e.screenRecording.harmony.stop(t),`stop`)}){let i=[await z(r),await z(async()=>{if(!await e.screenRecording.harmony.remove(t,n.remotePath))throw Error(`HarmonyOS recording staging artifact removal was not confirmed`)}),await z(async()=>await Fe(e,t,n.fileName))].find(e=>e!==void 0);return i===void 0?{status:`cleaned`}:{status:`cleanup-pending`,reason:`transport-failed`,message:i instanceof Error?i.message:`HarmonyOS recording cleanup failed`}}async function Fe(e,t,n){let r=await e.screenRecording.harmony.findMedia(t,n);if(r&&!await e.screenRecording.harmony.removeMedia(t,r))throw Error(`HarmonyOS recording media removal was not confirmed`)}async function z(e){try{await e();return}catch(e){return e}}function B(e,t){if(e.exitCode===0&&e.stdout.includes(`start ability successfully`))return;let n=e.stdout.trim()||e.stderr.trim()||`hdc exit ${e.exitCode}`;throw Error(`failed to ${t} HarmonyOS screen recording: ${n}`)}async function Ie(t,n){n.throwIfAborted();let{runHarmonyShell:r}=await import(`./hdc.js`),i=await r(t,[`aa`,`dump`,`-l`],{timeoutMs:15e3,signal:n});n.throwIfAborted();let a=Le(i.stdout);if(!a)throw new e(`COMMAND_FAILED`,`Could not determine the foreground HarmonyOS app`,{hint:`Open an app on the target, then retry appstate.`});return a}function Le(e){let t=e.split(/(?=^\s*Mission ID #)/m);for(let e of t){if(!/\bstate #FOREGROUND\b/.test(e))continue;let t=e.match(/mission name #\[#([^:]+):[^:]*:([^\]]+)]/);if(!t)continue;let[,n,r]=t;if(!(!n||!r))return{package:n,activity:r}}}function Re(e){return O({owner:`HarmonyOS`,openTargetIdentity:`bundle-id`,binding:D({device:e.device,signal:e.signal,resolveInteractor:e.host.resolve})})}const ze=Object.freeze({available:!0}),Be=Object.freeze({available:!1,reason:`unsupported-device-kind`}),V=Object.freeze({available:!1,reason:`unsupported-platform-leaf`});function H(e){let t=e.kind===`emulator`||e.kind===`device`?ze:Be;return Object.freeze({deployApp:t,materializeAppSource:V,deployMaterializedApp:V,sendPushNotification:V})}function Ve(e){return H(e.device).deployApp.available?Object.freeze({deployApp:async t=>await He(e.commands,e.device,t,e.signal)}):Object.freeze({})}async function He(t,n,r,i){let a=await Ue(t,r.appPath,i)??r.app.trim();if(!a)throw new e(`INVALID_ARGS`,`Could not determine the bundle name from the HAP archive`,{hint:`Pass the HarmonyOS bundle name before the HAP path, or provide a valid HAP containing module.json.`});return await Ke(t,n,[`install`,`-r`,r.appPath],i,18e4),r.replaceExisting&&(await A(1e3,void 0,{signal:i}),await We(t,n,a,i)),{packageName:a,launchTarget:a}}async function Ue(e,t,n){let r=await e.run({executable:`unzip`,args:[`-p`,t,`module.json`],allowFailure:!0,timeoutMs:15e3},n);if(r.exitCode===0&&r.stdout.trim().length!==0)try{return JSON.parse(r.stdout).app?.bundleName?.trim()||void 0}catch{return}}async function We(t,n,r,i){let a=Ge((await U(t,n,[`bm`,`dump`,`-n`,r],i)).stdout);if(!a)throw new e(`COMMAND_FAILED`,`Could not determine a launchable ability for ${r}`,{hint:`Check that the HarmonyOS bundle exposes a main ability.`});await U(t,n,[`aa`,`start`,`-b`,r,...a.module?[`-m`,a.module]:[],`-a`,a.ability],i)}function Ge(e){let t=e.indexOf(`{`);if(t!==-1)try{let n=JSON.parse(e.slice(t)).hapModuleInfos?.find(e=>e.mainElementName);return n?.mainElementName?{ability:n.mainElementName,...n.moduleName?{module:n.moduleName}:{}}:void 0}catch{return}}async function Ke(e,t,n,r,i=15e3){return await e.run({executable:`hdc`,args:[`-t`,t.id,...n],timeoutMs:i},r)}async function U(e,t,n,r,a=15e3){return await e.run({executable:`hdc`,args:i(`hdc`,`shell`,n,[`-t`,t.id]),timeoutMs:a},r)}const W=n(`harmonyos`),qe=Object.freeze({available:!1,reason:`unsupported-platform-leaf`,hint:`HarmonyOS reads element text from the captured tree only.`}),Je=Object.freeze({available:!1,reason:`unsupported-device-kind`,hint:`focus is supported on HarmonyOS emulators and physical devices.`}),G=Object.freeze({available:!0}),K=Object.freeze({available:!1,reason:`unsupported-platform-leaf`}),Ye=Object.freeze({available:!1,reason:`unsupported-device-kind`,hint:`HarmonyOS appstate is supported only for HarmonyOS emulators and devices.`}),Xe=Object.freeze({available:!1,reason:`unsupported-platform-leaf`,hint:`Apple runner preparation is supported only for Apple targets.`}),q=Object.freeze({available:!0}),Ze=Object.freeze({available:!1,reason:`unsupported-device-kind`,hint:`open is supported only for HarmonyOS emulators and devices.`}),Qe=Object.freeze({available:!1,reason:`unsupported-device-kind`,hint:`close is supported only for HarmonyOS emulators and devices.`}),$e=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Port reverse is supported only by an owning provider runtime.`}),J=Object.freeze({available:!1,reason:`unsupported-device-kind`,hint:`snapshot is supported only for HarmonyOS emulators and devices.`}),et=Object.freeze({available:!1,reason:`unsupported-device-kind`,hint:`screenshot is supported only for HarmonyOS emulators and devices.`}),tt=Object.freeze({available:!1,reason:`unsupported-platform-leaf`,hint:`Re-run without --actions, or target an iOS simulator.`}),nt=Object.freeze({available:!1,reason:`unsupported-platform-leaf`,hint:`viewport resizes web targets only (--platform web).`});function rt(e){let t=it(e),n=at(e);return o({resolveOpenTarget:t,prepareApplicationOpen:t,openApplication:t,applyRuntimeHints:K,clearRuntimeHints:K,closeApplication:n,finalizeApplicationClose:n,prepareAppleRunner:Xe,configureProviderPortReverse:$e})}function it(e){return e.kind===`emulator`||e.kind===`device`?q:Ze}function at(e){return e.kind===`emulator`||e.kind===`device`?q:Qe}const Y=Object.freeze({available:!1,reason:`unsupported-device-kind`,hint:`Gestures are supported on HarmonyOS emulators and physical devices.`}),ot=Object.freeze({available:!1,reason:`unsupported-platform-leaf`}),st=Object.freeze({available:!1,reason:`unsupported-platform-leaf`,hint:S});function X(e){return e.kind===`emulator`||e.kind===`device`?G:Y}function Z(e){return e.kind===`emulator`||e.kind===`device`?G:Je}const Q=Object.freeze({available:!1,reason:`unsupported-platform-leaf`}),ct=Object.freeze({available:!1,reason:`unsupported-platform-leaf`,hint:`keyboard status/get is not available through the public HarmonyOS HDC API; use keyboard dismiss or enter`}),$=Object.freeze({available:!1,reason:`unsupported-platform-leaf`,hint:`audio is supported for web browser sessions, macOS sessions, iOS simulators, and Android emulators on macOS hosts`});function lt(e){let t=Se(e),n=async e=>{let n=await t.inspectFacts(e),r=H(e),i=Oe(e);return Object.freeze({device:n.device,operations:{...n.operations,...r,appState:e.kind===`simulator`?Ye:G,networkDump:K,screenRecordingStart:i,screenRecordingReattach:i,screenRecordingCleanup:i,...u({capture:e.kind===`emulator`||e.kind===`device`?G:J,customActions:tt,withoutActiveApp:e.kind===`emulator`||e.kind===`device`?G:J}),...l({capture:e.kind===`emulator`||e.kind===`device`?G:et}),...ne({findText:J}),...f({setViewport:nt}),...d({focus:Z(e)}),...p({unsupported:Y,plan:X(e),directionalFling:X(e),multiTouch:ot,targetAuthoredDrag:st,viewport:X(e)}),...s({scroll:X(e)}),...c({type:Z(e)}),...ge({unsupported:K,tap:Z(e),longPress:Z(e),fill:Z(e)}),...h({readTextAtPoint:qe}),...g({back:Z(e)}),...fe({unsupported:Q,home:Z(e),appSwitcher:Z(e)}),setFoldPose:Q,...le({triggerAppEvent:Q}),...ae({setSetting:Z(e),readSetting:Q}),...de({read:Q,wait:Q,accept:Q,dismiss:Q}),...oe({orientation:Q}),...m({tvRemote:Q}),...se({unsupported:Q,status:ct,dismiss:Z(e),enter:Z(e)}),...ue({unsupported:Q}),...me({capture:$,query:$}),...he({frames:Z(e),memorySample:Z(e),memorySnapshot:Z(e),nativeCapture:Q,profileReport:Q}),ensureReady:G,bootTarget:K,bootTargetHeadless:K,listApps:G,...rt(e),shutdownTarget:K}})};return Object.freeze({owner:W,ownsDevice:e=>e.platform===`harmonyos`,inspectFacts:n,bind:async i=>{let o=await t.bind(i),s=await n(i.device),c=s.operations.screenRecordingStart;return Object.freeze({device:o.device,owner:W,facts:s,operations:Object.freeze({...o.operations,...Ve({commands:e.commands,device:i.device,signal:i.scope.signal}),...s.operations.appState.available?{appState:async()=>await Ie(i.device,i.scope.signal)}:{},ensureReady:async()=>({...i.device,booted:!0}),...c.available?ke({host:e,device:i.device,owner:W,signal:i.scope.signal}):{},...s.operations.captureSnapshot.available?pe({device:i.device,signal:i.scope.signal,resolveInteractor:e.localInteractors.resolve}):{},...s.operations.captureScreenshot.available?ie({device:i.device,signal:i.scope.signal,resolveInteractor:e.localInteractors.resolve}):{},...s.operations.focusPoint.available?te({device:i.device,signal:i.scope.signal,resolveInteractor:e.localInteractors.resolve}):{},...s.operations.typeText.available?re({device:i.device,signal:i.scope.signal,resolveInteractor:e.localInteractors.resolve}):{},...ce({device:i.device,signal:i.scope.signal,facts:s.operations,resolveInteractor:e.localInteractors.resolve}),...s.operations.scrollDirection.available?ee({device:i.device,signal:i.scope.signal,resolveInteractor:e.localInteractors.resolve}):{},...C({device:i.device,signal:i.scope.signal,resolveInteractor:e.localInteractors.resolve,facts:s.operations}),...r(s.operations.perfFrames,()=>we({resolveHost:()=>e.perf.harmony,device:i.device})),...r(s.operations.tapPoint,()=>_e({device:i.device,signal:i.scope.signal,resolveInteractor:e.localInteractors.resolve,facts:s.operations,pause:async t=>await e.clock.sleep(t,i.scope.signal)})),listApps:async e=>{i.scope.signal.throwIfAborted();let{listHarmonyApps:t}=await import(`./app-lifecycle2.js`);return(await t(e.device,e.filter,{signal:i.scope.signal})).map(e=>({id:e.package,name:e.name}))},...a(Re({host:e.localInteractors,device:i.device,signal:i.scope.signal}),s.operations)}),[Symbol.asyncDispose]:async()=>await o[Symbol.asyncDispose]()})},shutdown:async()=>await t.shutdown()})}export{lt as createHarmonyPlatformRuntime};
|
|
1
|
+
import{D as e}from"./sdk-contracts.js";import{D as t}from"./sdk-device.js";import{Yt as n,tn as r}from"./sdk-batch.js";import{n as i}from"./device-shell.js";import{n as a,t as o}from"./application-lifecycle-runtime.js";import{A as s,B as c,C as l,D as u,G as d,H as f,I as p,J as ee,K as te,L as ne,N as re,O as ie,P as ae,V as oe,d as se,h as ce,j as le,n as ue,o as de,s as fe,v as m,w as h,x as g,z as pe}from"./alert-runtime.js";import{n as me}from"./audio-probe-runtime.js";import{n as he}from"./perf-runtime.js";import{i as ge,t as _e}from"./touch-runtime.js";import{a as _,n as v}from"./durable-resource.js";import{n as ve}from"./async-lifecycle.js";import{i as ye,r as be}from"./src7.js";import{n as xe,t as y}from"./screen-recording-completion.js";import{t as b}from"./screen-recording-options.js";import{n as x}from"./screen-recording-runtime.js";import{i as S}from"./gesture-admission.js";import{t as C}from"./interactor-operation-catalog.js";import{i as w,n as T}from"./perf-runtime-operation-builder.js";import{t as E}from"./app-log-runtime.js";import{n as D,t as O}from"./application-lifecycle-interaction.js";import{randomUUID as k}from"node:crypto";import{setTimeout as A}from"node:timers/promises";const j=Object.freeze({resourceKind:E,version:1,encode:e=>({...e}),decode:e=>e.transport!==`harmony-hilog`||!N(e.outputPath)||!N(e.pidPath)?{status:`invalid`,message:`Invalid HarmonyOS app-log descriptor`}:{status:`decoded`,descriptor:Object.freeze({transport:`harmony-hilog`,outputPath:e.outputPath,pidPath:e.pidPath})}});function M(e){return v({resourceKind:E,sessionId:e.sessionId,device:{id:e.device.id,family:`harmonyos`,kind:e.device.kind,...e.device.target===void 0?{}:{target:e.device.target}},owner:e.owner,fence:e.fence,lifecycle:`open`,descriptor:_(j,e.descriptor)})}function N(e){return typeof e==`string`&&e.trim().length>0}function Se(e){return be(e,{family:`harmonyos`,backend:`harmonyos`,label:`HarmonyOS`,codec:j,startUnavailableHint:`The selected HarmonyOS transport cannot start a background hilog stream.`,cleanupFailureMessage:`HarmonyOS app-log cleanup did not settle every owned resource`,doctor:async(e,t)=>({backend:`harmonyos`,checks:{},notes:t?[]:[`No app bundle is tracked in this session. Run open <app> first for app-scoped logs.`]}),process:async({host:e,device:t,input:n,signal:r})=>{let a=await Ce(e,r);return{resolvePid:async r=>await ye(e,{executable:a,args:i(`hdc`,`shell`,[`pidof`,n.appBundleId],[`-t`,t.id]),allowFailure:!0,timeoutMs:5e3},r),command:e=>({kind:`host`,request:{executable:a,args:i(`hdc`,`shell`,[`hilog`,`-P`,e],[`-t`,t.id]),allowFailure:!0}})}},descriptor:({artifacts:e})=>({transport:`harmony-hilog`,...e}),envelope:({input:e,device:t,owner:n,descriptor:r})=>M({sessionId:e.sessionId,device:t,owner:n,fence:e.fence,descriptor:r})})}async function Ce(t,n){n.throwIfAborted(),await P(async()=>await t.toolchains.prepare(`harmonyos`),n),n.throwIfAborted();let r=await P(async()=>await t.commands.which(`hdc`),n);if(n.throwIfAborted(),!r)throw new e(`TOOL_MISSING`,`hdc not found in PATH`,{hint:`Install HarmonyOS Command Line Tools, then add its sdk/default/openharmony/toolchains directory to PATH.`});return r}async function P(e,t){try{return await e()}catch(e){throw t.throwIfAborted(),e}}function we(e){let{resolveHost:t,device:n}=e,r={available:!1,reason:`Dropped-frame sampling is currently available only on Android app sessions and connected iOS device app sessions.`};return Object.freeze({perfFrames:async()=>({metric:r,sampling:r}),perfMemorySample:async({appId:e})=>({metric:e?await w(t().sampleMemory(n,e)):T(`HarmonyOS`,`bundle`),sampling:{method:`hdc-shell-proc-status`,description:`Resident memory snapshot from HarmonyOS /proc/<pid>/status. Values are reported in kilobytes.`,unit:`kB`,topConsumerLimit:1}}),perfMemorySnapshot:async({kind:e})=>({artifact:{available:!1,kind:e??`memgraph`,reason:`Memory snapshot artifacts are not supported on harmonyos.`,hint:`Use perf memory sample where supported, or run the snapshot against Android, iOS simulator, or macOS.`,support:{platform:`harmonyos`,defaultKind:`memgraph`,androidHprof:!1,memgraph:!1,heapprofd:!1}},sampling:{method:`unsupported`,description:`HarmonyOS memory snapshot capture is not available through HDC.`,artifactOnly:!0}})})}const F=Object.freeze({resourceKind:x,version:1,encode:e=>({...e}),decode:e=>e.backend===`harmony-screen-recorder`&&typeof e.fileName==`string`&&De(e.fileName)&&e.remotePath===`/data/local/tmp/${e.fileName}`?{status:`decoded`,descriptor:Object.freeze({backend:`harmony-screen-recorder`,fileName:e.fileName,remotePath:e.remotePath})}:{status:`invalid`,message:`Invalid HarmonyOS screen-recording descriptor`}});function Te(e){let{device:n,owner:r,input:i,descriptor:a}=e;return v({resourceKind:x,sessionId:i.sessionId,device:t(n),owner:r,fence:i.fence,lifecycle:`open`,descriptor:_(F,a)})}function Ee(e){return F.decode(e).status===`decoded`?{status:`cleanup-pending`,reason:`manual-recovery-required`,message:`HarmonyOS recorder ownership cannot be proven after daemon restart; no recorder was stopped.`}:{status:`cleanup-pending`,reason:`manual-recovery-required`}}function De(e){return/^agent-device-recording-[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}\.mp4$/i.test(e)}function Oe(e){return e.kind===`device`?Object.freeze({available:!0}):Object.freeze({available:!1,reason:`unsupported-device-kind`,hint:`HarmonyOS recording is supported on physical devices only.`})}function ke(e){let{host:t,device:n,owner:r,signal:i}=e;return Object.freeze({screenRecordingStart:async e=>await Ae({host:t,device:n,owner:r,input:e,signal:i}),screenRecordingReattach:async()=>({status:`unreattachable`,reason:`transport-not-reattachable`,message:`HarmonyOS recordings cannot be reattached after daemon restart.`}),screenRecordingCleanup:async e=>Ee(e.envelope.descriptor.body)})}async function Ae(t){let{host:n,device:r,owner:i,input:a,signal:o}=t;if(a.scope===`app`)throw new e(`INVALID_ARGS`,`HarmonyOS recording captures the whole physical-device screen; use --scope device or --scope system`);b(a,{scopes:[`device`,`system`],fps:!1,exportQuality:!1,hideTouches:!1},e=>`HarmonyOS recordings do not support ${e.join(`, `)}`),o.throwIfAborted(),await n.screenRecording.outputs.prepare(a.outputPath);let s=`agent-device-recording-${k()}.mp4`,c={backend:`harmony-screen-recorder`,fileName:s,remotePath:`/data/local/tmp/${s}`},l;try{l=await n.screenRecording.harmony.start(r,s,o),o.throwIfAborted()}catch(e){throw o.aborted?(await R(n,r,c).catch(()=>{}),o.reason):e}B(l,`start`);try{o.throwIfAborted()}catch(e){throw await R(n,r,c).catch(()=>{}),e}let u=je(a),d=!1,f=async()=>{d||=(B(await n.screenRecording.harmony.stop(r),`stop`),!0)},p=xe(u,{finish:async e=>await Me(n,r,e,c,f),forceCleanup:async()=>await R(n,r,c,f)});return Object.freeze({pendingHandle:new ve(p),envelope:Te({device:r,owner:i,input:a,descriptor:c})})}function je(e){return Object.freeze({backend:`HarmonyOS ScreenRecorder`,outPath:e.outputPath,...e.clientOutputPath===void 0?{}:{clientOutPath:e.clientOutputPath},startedAt:Date.now(),scope:e.scope,showTouches:!1,recordOnlySession:e.recordOnlySession,...e.activeSessionApp===void 0?{}:{activeSessionApp:e.activeSessionApp},gestureEvents:[]})}async function Me(e,t,n,r,i){await i();let a=await e.screenRecording.harmony.findMedia(t,r.fileName);if(!a)throw Error(`failed to find finalized HarmonyOS recording '${r.fileName}'`);if(!await Pe(e,t,r,a))throw Error(`failed to finalize HarmonyOS recording: ${r.fileName} did not produce a non-empty media file`);try{if((await e.screenRecording.harmony.pull(t,{remotePath:r.remotePath,outputPath:n.outPath})).exitCode!==0)throw Error(`failed to retrieve HarmonyOS recording`);let i=await e.screenRecording.finalize.complete({outputPath:n.outPath,showTouches:!1,gestureEvents:n.gestureEvents,targetLabel:`HarmonyOS recording`}),o=await Ne(e,t,r,a);return y(n,{...i,...L(i.warning,o)},{stopObservation:{recorder:`confirmed`},nativePathDisposition:o===void 0?`retired`:`retirable`,showTouches:!1})}catch(n){throw await e.screenRecording.harmony.remove(t,r.remotePath).catch(()=>{}),n}}async function Ne(e,t,n,r){let i=[];return await I(()=>e.screenRecording.harmony.remove(t,n.remotePath))||i.push(`staging artifact`),await I(()=>e.screenRecording.harmony.removeMedia(t,r))||i.push(`media-library artifact`),i.length===0?void 0:`HarmonyOS recording completed, but cleanup was not confirmed for the ${i.join(` and `)}.`}async function I(e){try{return await e()}catch{return!1}}function L(e,t){let n=[e,t].filter(e=>e!==void 0).join(` `);return n.length===0?{}:{warning:n}}async function Pe(e,t,n,r){let i;for(let a=0;a<40;a+=1){if(await e.screenRecording.harmony.remove(t,n.remotePath).catch(()=>{}),await e.screenRecording.harmony.stageMedia(t,{mediaUri:r,remotePath:n.remotePath})){let r=await e.screenRecording.harmony.stagedFileSize(t,n.remotePath);if(r!==void 0&&r>0&&r===i)return!0;i=r!==void 0&&r>0?r:void 0}else i=void 0;a<39&&await e.clock.sleep(250)}return!1}async function R(e,t,n,r=async()=>{B(await e.screenRecording.harmony.stop(t),`stop`)}){let i=[await z(r),await z(async()=>{if(!await e.screenRecording.harmony.remove(t,n.remotePath))throw Error(`HarmonyOS recording staging artifact removal was not confirmed`)}),await z(async()=>await Fe(e,t,n.fileName))].find(e=>e!==void 0);return i===void 0?{status:`cleaned`}:{status:`cleanup-pending`,reason:`transport-failed`,message:i instanceof Error?i.message:`HarmonyOS recording cleanup failed`}}async function Fe(e,t,n){let r=await e.screenRecording.harmony.findMedia(t,n);if(r&&!await e.screenRecording.harmony.removeMedia(t,r))throw Error(`HarmonyOS recording media removal was not confirmed`)}async function z(e){try{await e();return}catch(e){return e}}function B(e,t){if(e.exitCode===0&&e.stdout.includes(`start ability successfully`))return;let n=e.stdout.trim()||e.stderr.trim()||`hdc exit ${e.exitCode}`;throw Error(`failed to ${t} HarmonyOS screen recording: ${n}`)}async function Ie(t,n){n.throwIfAborted();let{runHarmonyShell:r}=await import(`./hdc.js`),i=await r(t,[`aa`,`dump`,`-l`],{timeoutMs:15e3,signal:n});n.throwIfAborted();let a=Le(i.stdout);if(!a)throw new e(`COMMAND_FAILED`,`Could not determine the foreground HarmonyOS app`,{hint:`Open an app on the target, then retry appstate.`});return a}function Le(e){let t=e.split(/(?=^\s*Mission ID #)/m);for(let e of t){if(!/\bstate #FOREGROUND\b/.test(e))continue;let t=e.match(/mission name #\[#([^:]+):[^:]*:([^\]]+)]/);if(!t)continue;let[,n,r]=t;if(!(!n||!r))return{package:n,activity:r}}}function Re(e){return O({owner:`HarmonyOS`,openTargetIdentity:`bundle-id`,binding:D({device:e.device,signal:e.signal,resolveInteractor:e.host.resolve})})}const ze=Object.freeze({available:!0}),Be=Object.freeze({available:!1,reason:`unsupported-device-kind`}),V=Object.freeze({available:!1,reason:`unsupported-platform-leaf`});function H(e){let t=e.kind===`emulator`||e.kind===`device`?ze:Be;return Object.freeze({deployApp:t,materializeAppSource:V,deployMaterializedApp:V,sendPushNotification:V})}function Ve(e){return H(e.device).deployApp.available?Object.freeze({deployApp:async t=>await He(e.commands,e.device,t,e.signal)}):Object.freeze({})}async function He(t,n,r,i){let a=await Ue(t,r.appPath,i)??r.app.trim();if(!a)throw new e(`INVALID_ARGS`,`Could not determine the bundle name from the HAP archive`,{hint:`Pass the HarmonyOS bundle name before the HAP path, or provide a valid HAP containing module.json.`});return await Ke(t,n,[`install`,`-r`,r.appPath],i,18e4),r.replaceExisting&&(await A(1e3,void 0,{signal:i}),await We(t,n,a,i)),{packageName:a,launchTarget:a}}async function Ue(e,t,n){let r=await e.run({executable:`unzip`,args:[`-p`,t,`module.json`],allowFailure:!0,timeoutMs:15e3},n);if(r.exitCode===0&&r.stdout.trim().length!==0)try{return JSON.parse(r.stdout).app?.bundleName?.trim()||void 0}catch{return}}async function We(t,n,r,i){let a=Ge((await U(t,n,[`bm`,`dump`,`-n`,r],i)).stdout);if(!a)throw new e(`COMMAND_FAILED`,`Could not determine a launchable ability for ${r}`,{hint:`Check that the HarmonyOS bundle exposes a main ability.`});await U(t,n,[`aa`,`start`,`-b`,r,...a.module?[`-m`,a.module]:[],`-a`,a.ability],i)}function Ge(e){let t=e.indexOf(`{`);if(t!==-1)try{let n=JSON.parse(e.slice(t)).hapModuleInfos?.find(e=>e.mainElementName);return n?.mainElementName?{ability:n.mainElementName,...n.moduleName?{module:n.moduleName}:{}}:void 0}catch{return}}async function Ke(e,t,n,r,i=15e3){return await e.run({executable:`hdc`,args:[`-t`,t.id,...n],timeoutMs:i},r)}async function U(e,t,n,r,a=15e3){return await e.run({executable:`hdc`,args:i(`hdc`,`shell`,n,[`-t`,t.id]),timeoutMs:a},r)}const W=n(`harmonyos`),qe=Object.freeze({available:!1,reason:`unsupported-platform-leaf`,hint:`HarmonyOS reads element text from the captured tree only.`}),Je=Object.freeze({available:!1,reason:`unsupported-device-kind`,hint:`focus is supported on HarmonyOS emulators and physical devices.`}),G=Object.freeze({available:!0}),K=Object.freeze({available:!1,reason:`unsupported-platform-leaf`}),Ye=Object.freeze({available:!1,reason:`unsupported-device-kind`,hint:`HarmonyOS appstate is supported only for HarmonyOS emulators and devices.`}),Xe=Object.freeze({available:!1,reason:`unsupported-platform-leaf`,hint:`Apple runner preparation is supported only for Apple targets.`}),q=Object.freeze({available:!0}),Ze=Object.freeze({available:!1,reason:`unsupported-device-kind`,hint:`open is supported only for HarmonyOS emulators and devices.`}),Qe=Object.freeze({available:!1,reason:`unsupported-device-kind`,hint:`close is supported only for HarmonyOS emulators and devices.`}),$e=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Port reverse is supported only by an owning provider runtime.`}),J=Object.freeze({available:!1,reason:`unsupported-device-kind`,hint:`snapshot is supported only for HarmonyOS emulators and devices.`}),et=Object.freeze({available:!1,reason:`unsupported-device-kind`,hint:`screenshot is supported only for HarmonyOS emulators and devices.`}),tt=Object.freeze({available:!1,reason:`unsupported-platform-leaf`,hint:`Re-run without --actions, or target an iOS simulator.`}),nt=Object.freeze({available:!1,reason:`unsupported-platform-leaf`,hint:`viewport resizes web targets only (--platform web).`});function rt(e){let t=it(e),n=at(e);return o({resolveOpenTarget:t,prepareApplicationOpen:t,openApplication:t,applyRuntimeHints:K,clearRuntimeHints:K,closeApplication:n,finalizeApplicationClose:n,prepareAppleRunner:Xe,configureProviderPortReverse:$e})}function it(e){return e.kind===`emulator`||e.kind===`device`?q:Ze}function at(e){return e.kind===`emulator`||e.kind===`device`?q:Qe}const Y=Object.freeze({available:!1,reason:`unsupported-device-kind`,hint:`Gestures are supported on HarmonyOS emulators and physical devices.`}),ot=Object.freeze({available:!1,reason:`unsupported-platform-leaf`}),st=Object.freeze({available:!1,reason:`unsupported-platform-leaf`,hint:S});function X(e){return e.kind===`emulator`||e.kind===`device`?G:Y}function Z(e){return e.kind===`emulator`||e.kind===`device`?G:Je}const Q=Object.freeze({available:!1,reason:`unsupported-platform-leaf`}),ct=Object.freeze({available:!1,reason:`unsupported-platform-leaf`,hint:`keyboard status/get is not available through the public HarmonyOS HDC API; use keyboard dismiss or enter`}),$=Object.freeze({available:!1,reason:`unsupported-platform-leaf`,hint:`audio is supported for web browser sessions, macOS sessions, iOS simulators, and Android emulators on macOS hosts`});function lt(e){let t=Se(e),n=async e=>{let n=await t.inspectFacts(e),r=H(e),i=Oe(e);return Object.freeze({device:n.device,operations:{...n.operations,...r,appState:e.kind===`simulator`?Ye:G,networkDump:K,screenRecordingStart:i,screenRecordingReattach:i,screenRecordingCleanup:i,...d({capture:e.kind===`emulator`||e.kind===`device`?G:J,customActions:tt,withoutActiveApp:e.kind===`emulator`||e.kind===`device`?G:J}),...ee({capture:e.kind===`emulator`||e.kind===`device`?G:et}),...oe({findText:J}),...c({setViewport:nt}),...pe({focus:Z(e)}),...p({unsupported:Y,plan:X(e),directionalFling:X(e),multiTouch:ot,targetAuthoredDrag:st,viewport:X(e)}),...re({scroll:X(e)}),...s({type:Z(e)}),...ge({unsupported:K,tap:Z(e),longPress:Z(e),fill:Z(e)}),...u({readTextAtPoint:qe}),...h({back:Z(e)}),...se({unsupported:Q,home:Z(e),appSwitcher:Z(e)}),setFoldPose:Q,...fe({triggerAppEvent:Q}),...de({setSetting:Z(e),readSetting:Q}),...ue({read:Q,wait:Q,accept:Q,dismiss:Q}),...l({orientation:Q}),...g({tvRemote:Q}),...m({unsupported:Q,status:ct,dismiss:Z(e),enter:Z(e)}),...ce({unsupported:Q}),...me({capture:$,query:$}),...he({frames:Z(e),memorySample:Z(e),memorySnapshot:Z(e),nativeCapture:Q,profileReport:Q}),ensureReady:G,bootTarget:K,bootTargetHeadless:K,listApps:G,...rt(e),shutdownTarget:K}})};return Object.freeze({owner:W,ownsDevice:e=>e.platform===`harmonyos`,inspectFacts:n,bind:async i=>{let o=await t.bind(i),s=await n(i.device),c=s.operations.screenRecordingStart;return Object.freeze({device:o.device,owner:W,facts:s,operations:Object.freeze({...o.operations,...Ve({commands:e.commands,device:i.device,signal:i.scope.signal}),...s.operations.appState.available?{appState:async()=>await Ie(i.device,i.scope.signal)}:{},ensureReady:async()=>({...i.device,booted:!0}),...c.available?ke({host:e,device:i.device,owner:W,signal:i.scope.signal}):{},...s.operations.captureSnapshot.available?f({device:i.device,signal:i.scope.signal,resolveInteractor:e.localInteractors.resolve}):{},...s.operations.captureScreenshot.available?te({device:i.device,signal:i.scope.signal,resolveInteractor:e.localInteractors.resolve}):{},...s.operations.focusPoint.available?ne({device:i.device,signal:i.scope.signal,resolveInteractor:e.localInteractors.resolve}):{},...s.operations.typeText.available?ie({device:i.device,signal:i.scope.signal,resolveInteractor:e.localInteractors.resolve}):{},...ae({device:i.device,signal:i.scope.signal,facts:s.operations,resolveInteractor:e.localInteractors.resolve}),...s.operations.scrollDirection.available?le({device:i.device,signal:i.scope.signal,resolveInteractor:e.localInteractors.resolve}):{},...C({device:i.device,signal:i.scope.signal,resolveInteractor:e.localInteractors.resolve,facts:s.operations}),...r(s.operations.perfFrames,()=>we({resolveHost:()=>e.perf.harmony,device:i.device})),...r(s.operations.tapPoint,()=>_e({device:i.device,signal:i.scope.signal,resolveInteractor:e.localInteractors.resolve,facts:s.operations,pause:async t=>await e.clock.sleep(t,i.scope.signal)})),listApps:async e=>{i.scope.signal.throwIfAborted();let{listHarmonyApps:t}=await import(`./app-lifecycle2.js`);return(await t(e.device,e.filter,{signal:i.scope.signal})).map(e=>({id:e.package,name:e.name}))},...a(Re({host:e.localInteractors,device:i.device,signal:i.scope.signal}),s.operations)}),[Symbol.asyncDispose]:async()=>await o[Symbol.asyncDispose]()})},shutdown:async()=>await t.shutdown()})}export{lt as createHarmonyPlatformRuntime};
|
package/dist/src/runtime7.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{D as e}from"./sdk-contracts.js";import{Yt as t,en as n}from"./sdk-batch.js";import{n as r,t as i}from"./application-lifecycle-runtime.js";import{A as a,D as o,G as s,
|
|
1
|
+
import{D as e}from"./sdk-contracts.js";import{Yt as t,en as n}from"./sdk-batch.js";import{n as r,t as i}from"./application-lifecycle-runtime.js";import{A as a,D as o,G as s,I as c,J as ee,N as l,W as u,d,h as f,w as p,z as m}from"./alert-runtime.js";import{i as h}from"./touch-runtime.js";import{r as g}from"./platform-runtime-unavailable.js";import{i as _}from"./gesture-admission.js";import{t as v}from"./local-interactor-operation-set.js";import{n as y,t as b}from"./application-lifecycle-interaction.js";function x(e){return b({owner:`Linux`,openTargetIdentity:`app-name`,binding:y({device:e.device,signal:e.signal,resolveInteractor:e.host.resolve})})}const S=Object.freeze({available:!0}),C=t(`linux`),w=$(`unsupported-platform-leaf`),T=$(`unsupported-device-kind`),E=$(`unsupported-device-kind`,`focus is supported only for the Linux desktop device.`),D=$(`unsupported-device-kind`,`type is supported only for the Linux desktop device.`),O=$(`unsupported-device-kind`,`Gestures are supported only for the Linux desktop device.`),k=$(`unsupported-device-kind`,`scroll is supported only for the Linux desktop device.`),A=$(`unsupported-platform-leaf`),j=$(`unsupported-platform-leaf`),M=$(`unsupported-platform-leaf`,_),N=$(`unsupported-platform-leaf`),P=$(`unsupported-platform-leaf`,`Runtime hints are supported only for local iOS-family simulators and Android devices.`),F=$(`unsupported-platform-leaf`,`Apple runner preparation is supported only for Apple targets.`),I=$(`unsupported-provider-mode`,`Port reverse is supported only by an owning provider runtime.`),L=$(`unsupported-device-kind`,`open is supported only for the Linux desktop device.`),R=$(`unsupported-device-kind`,`close is supported only for the Linux desktop device.`),z=$(`unsupported-device-kind`,`snapshot is supported only for the Linux desktop device.`),B=$(`unsupported-device-kind`,`screenshot is supported only for the Linux desktop device.`),V=$(`unsupported-platform-leaf`,`Re-run without --actions, or target an iOS simulator.`),H=$(`unsupported-device-kind`,`back is supported only for the Linux desktop device.`),U=$(`unsupported-device-kind`,`home is supported only for the Linux desktop device.`),W=$(`unsupported-device-kind`,`clipboard is supported only for the Linux desktop device.`),G=w,K=$(`unsupported-platform-leaf`,`audio is supported for web browser sessions, macOS sessions, iOS simulators, and Android emulators on macOS hosts`);function q(t){return Object.freeze({owner:C,ownsDevice:e=>e.platform===`linux`,inspectFacts:async e=>Y(e),bind:async i=>{if(i.intent.kind===`exact-owner`&&!n(i.intent.owner,C))throw new e(`UNSUPPORTED_OPERATION`,`Linux runtime owner identity does not match`);if(i.device.platform!==`linux`)throw new e(`UNSUPPORTED_PLATFORM`,`Linux runtime cannot bind this device`);let a=Y(i.device),o=x({host:t.localInteractors,device:i.device,signal:i.scope.signal});return Object.freeze({device:i.device,owner:C,facts:a,operations:Object.freeze({...r(o,a.operations),...a.operations.captureSnapshot.available?Q(t,i):{},...J(t,i,a)}),[Symbol.asyncDispose]:async()=>void 0})},shutdown:async()=>void 0})}function J(e,t,n){let r={device:t.device,signal:t.scope.signal,resolveInteractor:e.localInteractors.resolve};return v({...r,facts:n.operations,pause:async n=>await e.clock.sleep(n,t.scope.signal)})}function Y(e){let t=e.kind===`device`?S:L,n=e.kind===`device`?S:R,r=g(e,C,{appLog:w,network:w,screenshot:B,snapshot:z,viewport:w,focus:E,gesture:O,scroll:k,typeText:D,touch:E,elementText:T,back:H,orientation:G,tvRemote:G,clipboard:W,systemButton:G,fold:G,triggerAppEvent:G,settings:G,readAlert:G,awaitAlert:G,acceptAlert:G,dismissAlert:G,keyboard:G,audioProbeCapture:K,audioProbeQuery:K,perf:G,readiness:w,lifecycle:i({resolveOpenTarget:t,prepareApplicationOpen:t,openApplication:t,applyRuntimeHints:P,clearRuntimeHints:P,closeApplication:n,finalizeApplicationClose:n,prepareAppleRunner:F,configureProviderPortReverse:I})});return Object.freeze({device:r.device,operations:{...r.operations,...s({capture:X(e,z),customActions:V,withoutActiveApp:X(e,z)}),...ee({capture:X(e,B)}),...m({focus:X(e,E)}),...c({unsupported:O,plan:X(e,O),directionalFling:A,multiTouch:j,targetAuthoredDrag:M,viewport:N}),...l({scroll:X(e,k)}),...a({type:X(e,D)}),...Z(e),...o({readTextAtPoint:X(e,T)}),...p({back:X(e,H)}),...d({unsupported:G,home:X(e,U)}),...f({unsupported:W,read:X(e,W),write:X(e,W)})}})}function X(e,t){return e.kind===`device`?S:t}function Z(e){let t=e.kind===`device`?S:E;return h({unsupported:w,tap:t,longPress:t,fill:t})}function Q(e,t){let n=async n=>await e.snapshot.captureSurface(t.device,n.options,u(t.scope.signal,n));return Object.freeze({captureSnapshot:n,captureSnapshotWithCustomActions:n,captureSnapshotWithoutActiveApp:n})}function $(e,t){return Object.freeze(t===void 0?{available:!1,reason:e}:{available:!1,reason:e,hint:t})}export{q as createLinuxPlatformRuntime};
|
package/dist/src/runtime8.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{D as e}from"./sdk-contracts.js";import{Yt as t,en as n}from"./sdk-batch.js";import{n as r,t as i}from"./application-lifecycle-runtime.js";import{
|
|
1
|
+
import{D as e}from"./sdk-contracts.js";import{Yt as t,en as n}from"./sdk-batch.js";import{n as r,t as i}from"./application-lifecycle-runtime.js";import{I as a,d as o,w as s,x as c}from"./alert-runtime.js";import{r as l}from"./platform-runtime-unavailable.js";import{i as u}from"./gesture-admission.js";import{t as d}from"./interactor-operation-catalog.js";import{n as f,t as p}from"./application-lifecycle-interaction.js";function m(e){return p({owner:`Vega`,openTargetIdentity:`app-name`,binding:f({device:e.device,signal:e.signal,resolveInteractor:e.host.resolve})})}const h=t(`vega`),g=Object.freeze({available:!0}),_=W(`unsupported-platform-leaf`),v=W(`unsupported-platform-leaf`,`Runtime hints are supported only for local iOS-family simulators and Android devices.`),y=W(`unsupported-platform-leaf`,`Apple runner preparation is supported only for Apple targets.`),b=W(`unsupported-provider-mode`,`Port reverse is supported only by an owning provider runtime.`),x=W(`unsupported-device-kind`,`open currently supports only Vega Virtual Devices.`),S=W(`unsupported-device-kind`,`close currently supports only Vega Virtual Devices.`);function C(t){return Object.freeze({owner:h,ownsDevice:e=>e.platform===`vega`,inspectFacts:async e=>U(e),bind:async i=>{if(i.intent.kind===`exact-owner`&&!n(i.intent.owner,h))throw new e(`UNSUPPORTED_OPERATION`,`Vega runtime owner identity does not match`);if(i.device.platform!==`vega`)throw new e(`UNSUPPORTED_PLATFORM`,`Vega runtime cannot bind this device`);let a=U(i.device),o=m({host:t.localInteractors,device:i.device,signal:i.scope.signal});return Object.freeze({device:i.device,owner:h,facts:a,operations:Object.freeze({...r(o,a.operations),...d({device:i.device,signal:i.scope.signal,resolveInteractor:t.localInteractors.resolve,facts:a.operations})}),[Symbol.asyncDispose]:async()=>void 0})},shutdown:async()=>void 0})}const w=W(`unsupported-platform-leaf`,`screenshot is not supported on Vega OS: the Vega runtime exposes remote navigation only.`),T=W(`unsupported-platform-leaf`,`focus is not supported on Vega OS: the Vega runtime exposes remote navigation only.`),E=W(`unsupported-platform-leaf`,`type is not supported on Vega OS: the Vega runtime exposes remote navigation only.`),D=W(`unsupported-platform-leaf`,`Gestures are not supported on Vega OS: the Vega runtime exposes remote navigation only.`),O=W(`unsupported-platform-leaf`,`scroll is not supported on Vega OS: the Vega runtime exposes remote navigation only.`),k=W(`unsupported-platform-leaf`),A=W(`unsupported-platform-leaf`,u),j=W(`unsupported-platform-leaf`,`orientation is not supported on Vega OS.`),M=W(`unsupported-platform-leaf`,`keyboard is not supported on Vega OS.`),N=W(`unsupported-platform-leaf`,`alert is not supported on Vega OS.`),P=W(`unsupported-platform-leaf`,`settings is not supported on Vega OS.`),F=W(`unsupported-platform-leaf`,`trigger-app-event is not supported on Vega OS.`),I=W(`unsupported-platform-leaf`,`System buttons other than home are not supported on Vega OS.`),L=W(`unsupported-platform-leaf`,`fold is not supported on Vega OS.`),R=W(`unsupported-platform-leaf`,`clipboard is not supported on Vega OS.`),z=W(`unsupported-device-kind`,`back currently supports only Vega Virtual Devices.`),B=W(`unsupported-device-kind`,`home currently supports only Vega Virtual Devices.`),V=W(`unsupported-device-kind`,`tv-remote currently supports only Vega Virtual Devices.`),H=W(`unsupported-platform-leaf`,`audio is supported for web browser sessions, macOS sessions, iOS simulators, and Android emulators on macOS hosts`);function U(e){let t=e.kind===`emulator`&&e.target===`tv`,n=t?g:x,r=t?g:S,u=l(e,h,{appLog:_,network:_,screenshot:w,snapshot:_,viewport:_,focus:T,gesture:D,scroll:O,typeText:E,touch:_,elementText:_,back:z,orientation:j,tvRemote:V,clipboard:R,systemButton:I,fold:L,triggerAppEvent:F,settings:P,readAlert:N,awaitAlert:N,acceptAlert:N,dismissAlert:N,keyboard:M,audioProbeCapture:H,audioProbeQuery:H,perf:_,readiness:_,lifecycle:i({resolveOpenTarget:n,prepareApplicationOpen:n,openApplication:n,applyRuntimeHints:v,clearRuntimeHints:v,closeApplication:r,finalizeApplicationClose:r,prepareAppleRunner:y,configureProviderPortReverse:b})});return Object.freeze({device:u.device,operations:{...u.operations,...s({back:t?g:z}),...o({unsupported:I,home:t?g:B}),...c({tvRemote:t?g:V}),...a({unsupported:D,multiTouch:k,targetAuthoredDrag:A})}})}function W(e,t){let n={available:!1,reason:e,...t===void 0?{}:{hint:t}};return Object.freeze(n)}export{C as createVegaPlatformRuntime};
|
package/dist/src/runtime9.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{D as e}from"./sdk-contracts.js";import{Yt as t,en as n,tn as r}from"./sdk-batch.js";import{n as i,t as a}from"./application-lifecycle-runtime.js";import{A as o,
|
|
1
|
+
import{D as e}from"./sdk-contracts.js";import{Yt as t,en as n,tn as r}from"./sdk-batch.js";import{n as i,t as a}from"./application-lifecycle-runtime.js";import{A as o,B as s,C as c,D as l,G as u,H as d,I as ee,J as f,K as te,L as ne,N as p,O as m,V as h,d as re,h as g,j as _,n as v,o as ie,s as y,v as b,w as x,x as S,z as C}from"./alert-runtime.js";import{n as w}from"./audio-probe-runtime.js";import{n as T}from"./perf-runtime.js";import{i as E,t as D}from"./touch-runtime.js";import{i as O}from"./gesture-admission.js";import{n as k,t as A}from"./application-lifecycle-interaction.js";import{n as j,r as M,t as N}from"./screen-recording-transport.js";async function P(e){let{host:t,device:n,owner:r,signal:i}=e,a=await t.screenRecording.web.resolve(n);return a?{available:!0,operations:{screenRecordingStart:async e=>(F(e),await N({host:t,device:n,owner:r,input:e,signal:i,transport:{backend:`agent-browser`,targetLabel:`web recording`,start:async t=>await a.start(e.outputPath,t),stop:async()=>await a.stop()},support:{scopes:[`app`],fps:!1,exportQuality:!1,hideTouches:!1},unsupported:e=>`web recordings do not support ${e.join(`, `)}; agent-browser records WebM directly`})),screenRecordingReattach:async()=>M(`Web recordings cannot be reattached after daemon restart.`),screenRecordingCleanup:async()=>j(`Web recordings cannot be cleaned after daemon restart.`)}}:{available:!1,operations:{}}}function F(t){if(t.recordOnlySession)throw new e(`INVALID_ARGS`,`record on web requires an active browser session; run open <url> --platform web first`);if(!t.outputPath.toLowerCase().endsWith(`.webm`))throw new e(`INVALID_ARGS`,`web recordings require a .webm output path; agent-browser records WebM directly`)}function I(e){return A({owner:`web`,openTargetIdentity:`app-name`,binding:k({device:e.device,signal:e.signal,resolveInteractor:e.host.resolve})})}const L=t(`web`),R=Object.freeze({available:!0}),z=Object.freeze({available:!1,reason:`unsupported-platform-leaf`,hint:`Web targets read element text from the captured tree only.`}),B=Object.freeze({available:!1,reason:`unsupported-platform-leaf`}),V=Object.freeze({available:!1,reason:`owner-capability-missing`,hint:`record is not supported by this web provider`}),H=Object.freeze({available:!1,reason:`unsupported-platform-leaf`,hint:`Re-run without --actions, or target an iOS simulator.`}),U=Object.freeze({available:!1,reason:`unsupported-platform-leaf`}),W=Object.freeze({available:!1,reason:`unsupported-platform-leaf`,hint:`apps is not supported on web targets.`}),G=Object.freeze({available:!1,reason:`unsupported-platform-leaf`}),K=Object.freeze({available:!1,reason:`unsupported-platform-leaf`}),q=Object.freeze({available:!1,reason:`unsupported-platform-leaf`,hint:`Apple runner preparation is supported only for Apple targets.`}),J=Object.freeze({available:!1,reason:`owner-capability-missing`}),Y=Object.freeze({available:!1,reason:`unsupported-platform-leaf`,hint:`A web click is one immediate pointer press; the browser backend has no timed hold.`}),ae=Object.freeze({available:!1,reason:`unsupported-platform-leaf`,hint:`audio on web sessions is the stateless page probe; host capture is a macOS-host operation.`});function X(e,t){return typeof e==`function`?t:J}function Z(e,t){return e?R:t}const oe=Object.freeze({available:!1,reason:`unsupported-platform-leaf`}),se=Object.freeze({available:!1,reason:`unsupported-platform-leaf`,hint:O}),Q=Object.freeze({available:!1,reason:`unsupported-device-kind`,hint:`open is supported only for web browser devices.`}),ce=Object.freeze({available:!1,reason:`unsupported-device-kind`,hint:`close is supported only for web browser devices.`}),le=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Port reverse is supported only by an owning provider runtime.`});function ue(e){let t=de(e),n=fe(e);return a({resolveOpenTarget:t,prepareApplicationOpen:t,openApplication:t,applyRuntimeHints:U,clearRuntimeHints:U,closeApplication:n,finalizeApplicationClose:n,prepareAppleRunner:q,configureProviderPortReverse:le})}function de(e){return e.kind===`device`?R:Q}function fe(e){return e.kind===`device`?R:ce}function pe(t){return Object.freeze({owner:L,ownsDevice:e=>e.platform===`web`,inspectFacts:async e=>{let n=await t.networkTransports.resolve(e),r=await P({host:t,device:e,owner:L,signal:new AbortController().signal}),i=e.kind===`device`?await t.localInteractors.resolve(e,{}):void 0;return $(e,n,r.available,i)},bind:async r=>{if(r.intent.kind===`exact-owner`&&!n(r.intent.owner,L))throw new e(`UNSUPPORTED_OPERATION`,`Web runtime owner identity does not match`);if(r.device.platform!==`web`)throw new e(`UNSUPPORTED_PLATFORM`,`Web runtime owner cannot bind ${r.device.platform}`);let i=await t.networkTransports.resolve(r.device),a=await P({host:t,device:r.device,owner:L,signal:r.scope.signal}),o=r.device.kind===`device`?await t.localInteractors.resolve(r.device,{signal:r.scope.signal}):void 0;return me(t,r.device,r.scope.signal,i,a,$(r.device,i,a.available,o))},shutdown:async()=>void 0})}function me(t,n,a,o,s,c){let l=o.dump,u={...l?{networkDump:async e=>{let t=await l({maxEntries:e.maxEntries,include:e.include},a);return Object.freeze({source:`provider`,...t})}}:{},...s.operations,...c.operations.captureSnapshot.available?d({device:n,signal:a,resolveInteractor:t.localInteractors.resolve}):{},...c.operations.captureScreenshot.available?te({device:n,signal:a,resolveInteractor:t.localInteractors.resolve}):{},...c.operations.focusPoint.available?ne({device:n,signal:a,resolveInteractor:t.localInteractors.resolve}):{},...c.operations.typeText.available?m({device:n,signal:a,resolveInteractor:t.localInteractors.resolve}):{},...r(c.operations.tapPoint,()=>D({device:n,signal:a,resolveInteractor:t.localInteractors.resolve,facts:c.operations,pause:async e=>await t.clock.sleep(e,a)})),...c.operations.scrollDirection.available?_({device:n,signal:a,resolveInteractor:t.localInteractors.resolve}):{},...c.operations.setViewport.available?{setViewport:async r=>{a.throwIfAborted();let i=await t.localInteractors.resolve(n,{signal:a});if(!i.setViewport)throw new e(`UNSUPPORTED_OPERATION`,`viewport is not supported by the bound web interactor`);await i.setViewport(r.width,r.height),a.throwIfAborted()}}:{},...r(c.operations.audioProbeQuery,()=>({audioProbeQuery:async r=>{let i=await t.audioProbe.web.resolve(n);if(i===void 0)throw new e(`UNSUPPORTED_OPERATION`,`audio is not supported by this web provider`);return await i.probe(r)}})),...i(I({host:t.localInteractors,device:n,signal:a}),c.operations)};return Object.freeze({device:n,owner:L,facts:c,operations:Object.freeze(u),[Symbol.asyncDispose]:async()=>void 0})}function $(e,t,n,r){let i=Object.freeze({available:!1,reason:`owner-capability-missing`,hint:`network is not supported by this web provider`}),a=Z(e.kind===`device`,Q);return Object.freeze({device:{family:`web`,kind:e.kind,...e.target===void 0?{}:{target:e.target},providerMode:t.mode},operations:{appLogInspect:B,appLogDoctor:B,appLogStart:B,appLogReattach:B,appLogCleanup:B,appState:G,networkDump:Z(!!t.dump,i),screenRecordingStart:Z(n,V),screenRecordingReattach:Z(n,V),screenRecordingCleanup:Z(n,V),...u({capture:a,customActions:H,withoutActiveApp:a}),...h({findText:Q}),...f({capture:a}),...C({focus:a}),...o({type:a}),...E({unsupported:U,tap:a,tapRef:X(r?.tapRef,a),longPress:Y,hover:X(r?.hover,a),hoverRef:X(r?.hoverRef,a),fill:a,fillRef:X(r?.fillRef,a)}),...p({scroll:a}),...ee({unsupported:oe,targetAuthoredDrag:se}),...s({setViewport:a}),...l({readTextAtPoint:z}),...x({back:K}),...c({orientation:K}),...S({tvRemote:K}),...b({unsupported:K}),...g({unsupported:K}),...w({capture:ae,query:R}),...T({frames:K,memorySample:K,memorySnapshot:K,nativeCapture:K,profileReport:K}),...re({unsupported:K}),setFoldPose:K,...y({triggerAppEvent:K}),...ie({setSetting:K,readSetting:K}),...v({read:K,wait:K,accept:K,dismiss:K}),ensureReady:U,bootTarget:U,bootTargetHeadless:U,listApps:W,deployApp:U,materializeAppSource:U,deployMaterializedApp:U,sendPushNotification:U,shutdownTarget:U,...ue(e)}})}export{pe as createWebPlatformRuntime};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{D as e}from"./sdk-contracts.js";import{D as t,
|
|
1
|
+
import{D as e}from"./sdk-contracts.js";import{D as t,O as n}from"./sdk-device.js";function r(r){let i=r.now??Date.now,a=r.undurableCleanupTtlMs??3e5,o=new Map;return Object.freeze({blockUndurableCleanup(e,r){let s=t(e);o.set(n(s),{device:s,reason:r,expiresAt:i()+a})},clearUndurableCleanup(e){o.delete(n(t(e)))},assertStartAllowed(a){let s=n(t(a)),c=o.get(s);if(c){if(i()>c.expiresAt){o.delete(s),r.onUndurableCleanupExpired?.({device:c.device,reason:c.reason});return}throw new e(`COMMAND_FAILED`,`The existing ${r.displayName.toLowerCase()} resource has process-local unconfirmed ownership`,{reason:`cleanup-unconfirmed`,hint:`Do not start a replacement in this daemon process: ${c.reason}`})}}})}function i(){return r({displayName:`screen recording`})}export{r as n,i as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{D as e}from"./sdk-contracts.js";import{D as t,E as n,k as r}from"./sdk-device.js";import{$t as i,O as a,Zt as o}from"./sdk-batch.js";import{r as s}from"./diagnostics.js";import{E as c}from"./owner-identity.js";import{i as l}from"./verified-file.js";import"./file.js";import"./diagnostics2.js";import{r as u}from"./session-paths.js";import{i as d,n as f,t as p}from"./durable-resource.js";import{n as m}from"./screen-recording-runtime.js";import h from"node:path";import g from"node:fs";import ee from"node:crypto";function _(e){return e.length===0?e:e[0].toUpperCase()+e.slice(1)}function v(e){return e.replaceAll(`-`,`_`)}async function te(e,t,n){let r={kind:`pending`};try{let i=ce(ie(e,t),`active`);e.store.write(n,i),r={kind:`persisted`},t.throwIfCanceled();let a=t.pendingHandle.transfer();r={kind:`transferred`,handle:a},t.sessionStore.set(t.sessionName,e.sessionSlot.replace(t.session,{handle:a,envelope:i}))}catch(i){throw await ne(e,t,n,r,i),i}}async function ne(e,t,n,r,i){let a=r.kind!==`pending`||b(e,t,n),o=re(e,t,n,await y(t,r));t.reportUndurableCleanup(t.device,!a&&o.cleanupError===void 0||o.confirmed?{confirmed:!0}:{confirmed:!1,reason:o.cleanupError instanceof Error?o.cleanupError.message:`The durable cleanup transition could not be confirmed`}),o.cleanupError!==void 0&&se(e,t,i,o.cleanupError)}function re(e,t,n,r){try{return{confirmed:oe(e,n,t.fence,r),cleanupError:r}}catch(n){return s({level:`error`,phase:`${v(e.resourceKind)}_pending_adoption_transition_failed`,data:{session:t.sessionName,transitionError:n instanceof Error?n.message:String(n)}}),{confirmed:!1,cleanupError:r??n}}}async function y(e,t){try{t.kind===`transferred`?await t.handle[Symbol.asyncDispose]():await e.pendingHandle[Symbol.asyncDispose]();return}catch(e){return e}}function b(e,t,n){try{return e.store.write(n,x(e,t,t.envelope.descriptor)),!0}catch(r){try{return e.store.write(n,x(e,t,{version:0,body:{reason:`runtime-contract-invalid`}})),!0}catch(n){return s({level:`error`,phase:`${v(e.resourceKind)}_runtime_contract_tombstone_failed`,data:{session:t.sessionName,descriptorError:r instanceof Error?r.message:String(r),persistenceError:n instanceof Error?n.message:String(n)}}),!1}}}function x(e,t,r){return f({resourceKind:e.resourceKind,sessionId:t.sessionName,device:n(t.device),owner:t.owner,fence:t.fence,lifecycle:`open`,descriptor:r,metadata:{phase:`runtime-contract-invalid`,runtimeContractInvalid:!0}})}function ie(t,n){let r=d(n.envelope);if(r.status===`decoded`&&ae(r.envelope,n,t.resourceKind))return r.envelope;throw new e(`COMMAND_FAILED`,`${_(t.displayName)} runtime returned an incoherent durable envelope`,{reason:`runtime-contract-invalid`,hint:`Retain the runtime diagnostics and report the selected device and owner.`})}function ae(e,t,a){return e.resourceKind===a&&e.sessionId===t.sessionName&&r(e.device,n(t.device))&&i(e.owner)===i(t.owner)&&e.fence.token===t.fence.token&&e.fence.generation===t.fence.generation&&e.lifecycle===`open`}function oe(e,t,n,r){let i=e.store.read(t);return i.status!==`decoded`||i.envelope.fence.token!==n.token||i.envelope.fence.generation!==n.generation?!1:(e.store.write(t,{...i.envelope,lifecycle:r===void 0?`completed`:`open`,metadata:{...i.envelope.metadata??{},phase:r===void 0?`completed`:`cleanup-pending`,cleanupStatus:r===void 0?`cleaned`:`cleanup-pending`}}),!0)}function se(e,t,n,r){s({level:`error`,phase:`${v(e.resourceKind)}_pending_adoption_cleanup_failed`,data:{session:t.sessionName,primaryError:n instanceof Error?n.message:String(n),cleanupError:r instanceof Error?r.message:String(r)}})}function ce(e,t){return Object.freeze({...e,lifecycle:`open`,metadata:{...e.metadata??{},phase:t}})}async function S(e){e.scope.signal.throwIfAborted();let t=new AbortController,n={...e.scope,signal:AbortSignal.any([e.scope.signal,t.signal])},r=()=>{},i=new Promise((e,t)=>{r=t}),a=()=>{},o=new Promise((t,n)=>{let r=()=>{try{e.scope.signal.throwIfAborted()}catch(e){n(e)}};if(e.scope.signal.aborted){r();return}e.scope.signal.addEventListener(`abort`,r,{once:!0}),a=()=>e.scope.signal.removeEventListener(`abort`,r)}),s=setTimeout(()=>{let n=new w(e.displayName,e.deadlineMs);t.abort(n),r(n)},e.deadlineMs);s.unref?.();let c=ue(e,n),l,u=c.then(e=>(l??={kind:`acquisition`},e),e=>{throw l??={kind:`acquisition-error`},e}),d=i.catch(e=>{throw l??={kind:`deadline`,error:e},e}),f=o.catch(e=>{throw l??={kind:`cancellation`,error:e},e});try{return await Promise.race([u,d,f])}finally{if(clearTimeout(s),a(),l?.kind===`deadline`||l?.kind===`cancellation`){let t=l.error;c.then(n=>le(e,n,t),()=>{}).catch(()=>{})}else c.catch(()=>{})}}async function le(e,t,n){try{t.reattached.status===`active`&&await C(e,t.reattached.handle,`late_handle_cleanup_failed`,n)}finally{await C(e,t.control,`late_control_cleanup_failed`,n)}}async function ue(e,t){let n,r;try{return n=await e.acquireControl(e.envelope,t),t.signal.throwIfAborted(),r=await n.reattach(e.envelope),t.signal.throwIfAborted(),{control:n,reattached:r}}catch(t){try{r?.status===`active`&&await C(e,r.handle,`late_handle_cleanup_failed`,t)}finally{n&&await C(e,n,`late_control_cleanup_failed`,t)}throw t}}async function C(e,t,n,r){try{await t[Symbol.asyncDispose]()}catch(t){e.onLateCleanupFailure(n,t,r)}}var w=class extends Error{deadlineMs;constructor(e,t){super(`${_(e)} recovery exceeded its ${t}ms deadline`),this.name=`DurableCaptureRecoveryDeadlineError`,this.deadlineMs=t}};const T=new Map;async function E(e){return await fe(e.resourcePath,async()=>{let t=e.store.read(e.resourcePath);if(t.status!==`decoded`)throw D(e.store,t.status===`missing`?`${e.store.displayName} resource record is missing`:`${e.store.displayName} resource record is unreattachable: ${t.message}`);if(!de(t.envelope.fence,e.expected))throw D(e.store,`${e.store.displayName} resource ownership fence was lost`);let n=t.envelope;return await e.run({get envelope(){return n},transition(t,r={}){return n=Object.freeze({...n,lifecycle:t,...r.descriptor===void 0?{}:{descriptor:r.descriptor},...r.metadata===void 0?{}:{metadata:r.metadata}}),e.store.write(e.resourcePath,n),n}})})}function de(e,t){return e.token===t.token&&e.generation===t.generation}async function fe(e,t){let n=T.get(e)??Promise.resolve(),r,i=new Promise(e=>{r=e}),a=n.catch(()=>{}).then(()=>i);T.set(e,a),await n.catch(()=>{});try{return await t()}finally{r(),T.get(e)===a&&T.delete(e)}}function D(t,n){return new e(`COMMAND_FAILED`,n,{reason:`ownership-fence-lost`,retriable:!1,hint:`Use the current ${t.displayName.toLowerCase()} resource owner or retain the recovery record for manual recovery.`})}async function pe(t,n,r){let i=t.sessionSlot.read(n.session);if(!i)throw new e(`INVALID_ARGS`,t.messages.noActive);try{let e=await O(t,{handle:i.handle,fence:i.envelope.fence,resourcePath:r,intent:n.intent});return j(t,n),e}catch(e){let i=t.store.read(r);throw i.status===`decoded`&&i.envelope.lifecycle===`completed`&&j(t,n),e}}async function O(e,t){return await E({store:e.store,resourcePath:t.resourcePath,expected:t.fence,run:async n=>{R(n);let r=L(n),i;try{i=await t.handle.finish(r)}catch(r){throw await k(e,n,t,r,t.intent),r}if(i.status===`completed`)return I(e,n,i),i.result;I(e,n,i);let a=F(e,i);throw await k(e,n,t,a,t.intent),a}})}async function k(e,t,n,r,i){if(i===`capture`&&e.failedFinishPolicy===`preserve-retry-material`){he(e,n,r);return}let a;try{a=await n.handle.forceCleanup()}catch(i){A(e,n,r,i,me(t,i));return}try{N(t,a)}catch(t){A(e,n,r,a.status===`cleanup-pending`?a.message??a.reason:`cleanup returned ${a.status}`,t);return}p(a)||A(e,n,r,a.message)}function me(e,t){try{N(e,{status:`cleanup-pending`,reason:`cleanup-unconfirmed`,message:M(t)});return}catch(e){return e}}function he(e,t,n){s({level:`error`,phase:`${v(e.resourceKind)}_finish_evidence_preserved`,data:{resourcePath:t.resourcePath,finishError:M(n),failedFinishPolicy:e.failedFinishPolicy}})}function A(e,t,n,r,i){s({level:`error`,phase:`${v(e.resourceKind)}_finish_cleanup_failed`,data:{resourcePath:t.resourcePath,finishError:M(n),cleanupError:r===void 0?`cleanup could not be confirmed`:M(r),...i===void 0?{}:{transitionError:M(i)}}})}function j(e,t){t.sessionStore.set(t.sessionName,e.sessionSlot.replace(t.session,void 0))}function M(e){return e instanceof Error?e.message:String(e)}async function ge(e,t){let n=e.sessionSlot.read(t.session);n&&(P(e,await E({store:e.store,resourcePath:t.resourcePath,expected:n.envelope.fence,run:async e=>{R(e);let t=await n.handle.forceCleanup();return N(e,t),t}})),t.sessionStore&&t.sessionName&&t.sessionStore.set(t.sessionName,e.sessionSlot.replace(t.session,void 0)))}function N(e,t){e.transition(p(t)?`completed`:`open`,{metadata:{...e.envelope.metadata??{},phase:p(t)?`completed`:`cleanup-pending`,cleanupStatus:t.status,...t.status===`cleanup-pending`?{cleanupPendingReason:t.reason,...t.message?{cleanupPendingMessage:t.message}:{}}:{}}})}function P(e,t){if(!p(t))throw F(e,t)}function F(t,n){return new e(`COMMAND_FAILED`,n.message??`${_(t.displayName)} cleanup could not be confirmed`,{reason:n.reason,retriable:n.reason!==`ownership-fence-lost`,hint:t.messages.cleanupPendingHint})}function I(e,t,n){if(n.status===`completed`){t.transition(`completed`,{metadata:{...t.envelope.metadata??{},...e.completionMetadata(n.result),phase:`completed`}});return}N(t,n)}function L(e){return Object.freeze({learned:e.envelope.metadata,record:t=>{e.transition(`open`,{metadata:{...e.envelope.metadata??{},...t}})}})}function R(e){e.transition(`open`,{metadata:{...e.envelope.metadata??{},phase:`completing`}})}async function _e(e){let t=e.definition.store.list(e.sessionsDir),n=[];for(let r of t)n.push(await z(e,r));return{scanned:t.length,recovered:n.filter(e=>e===`recovered`).length,retained:n.filter(e=>e===`retained`).length}}async function z(e,t){let n=ve(e,t);if(n.status!==`recoverable`)return n.status;try{return await ye(e,t,n.envelope,e.perRecordDeadlineMs??5e3)?`recovered`:`retained`}catch(n){return H(e,n instanceof w?`timed_out`:`failed`,t,{error:n instanceof Error?n.message:String(n),...n instanceof w?{deadlineMs:n.deadlineMs}:{}}),`retained`}}function ve(e,t){let n=e.definition.store.read(t);if(n.status===`unreattachable`)return H(e,`record_unreattachable`,t,{reason:n.reason,message:n.message,version:n.version}),{status:`retained`};if(n.status===`missing`||n.envelope.lifecycle===`completed`)return{status:`ignored`};let r=e.definition.store.resolvePath(e.resolveSessionDir(n.envelope.sessionId));return h.resolve(t)===h.resolve(r)?{status:`recoverable`,envelope:n.envelope}:(H(e,`session_path_mismatch`,t,{envelopeSessionId:n.envelope.sessionId,canonicalPath:r}),{status:`retained`})}async function ye(e,t,n,r){return await be(e,t,n,await S({displayName:e.definition.displayName,envelope:n,scope:e.scope,deadlineMs:r,acquireControl:e.acquireControl,onLateCleanupFailure:(n,r,i)=>H(e,n,t,{error:r instanceof Error?r.message:String(r),primaryError:i instanceof Error?i.message:String(i)})}))}async function be(e,t,n,r){try{switch(r.reattached.status){case`active`:{let i=r.reattached.handle,a=await E({store:e.definition.store,resourcePath:t,expected:n.fence,run:async e=>{xe(e);let t=await i.forceCleanup();return N(e,t),t}});return p(a)}case`completed`:return await B(e,t,n,{...e.definition.completionMetadata(r.reattached.result)}),!0;case`missing`:return await B(e,t,n,{recoveryStatus:`already-missing`}),!0;case`unreattachable`:{if(!V(r.reattached.reason))return H(e,`retained`,t,{reason:r.reattached.reason,message:r.reattached.message}),!1;let i=await r.control.cleanup(n);return await E({store:e.definition.store,resourcePath:t,expected:n.fence,run:async e=>N(e,i)}),p(i)}}}finally{await r.control[Symbol.asyncDispose]()}}async function B(e,t,n,r){await E({store:e.definition.store,resourcePath:t,expected:n.fence,run:async e=>{e.transition(`completed`,{metadata:{...e.envelope.metadata??{},phase:`completed`,...r}})}})}function xe(e){e.transition(`open`,{metadata:{...e.envelope.metadata??{},phase:`completing`}})}function V(e){switch(e){case`descriptor-invalid`:case`descriptor-version-unsupported`:case`ownership-fence-lost`:return!1;case`owner-unavailable`:case`transport-not-reattachable`:return!0}}function H(e,t,n,r){let i={phase:`${v(e.definition.resourceKind)}_recovery_${t}`,resourcePath:n,data:r};e.onDiagnostic?e.onDiagnostic(i):s({level:`warn`,phase:i.phase,data:{resourcePath:n,...r}})}async function Se(t,n){let r=t.store.read(n.resourcePath);if(r.status!==`decoded`||r.envelope.lifecycle!==`open`)throw Ce(t,r.status);let i=r.envelope,a=await S({displayName:t.displayName,envelope:i,scope:n.scope,deadlineMs:n.deadlineMs??5e3,acquireControl:n.acquireControl,onLateCleanupFailure:(e,r,i)=>n.scope.diagnostics.emit({level:`error`,phase:`${v(t.resourceKind)}_recovery_${e}`,data:{resourcePath:n.resourcePath,error:U(r),primaryError:U(i)}})});try{switch(a.reattached.status){case`active`:return await O(t,{handle:a.reattached.handle,fence:i.fence,resourcePath:n.resourcePath,intent:`capture`});case`completed`:{let e=a.reattached.result;return await E({store:t.store,resourcePath:n.resourcePath,expected:i.fence,run:async n=>{I(t,n,{status:`completed`,result:e,alreadyCompleted:!0})}}),e}case`missing`:throw new e(`COMMAND_FAILED`,`${_(t.displayName)} is missing`,{reason:`resource-missing`,hint:t.messages.cleanupPendingHint});case`unreattachable`:if(V(a.reattached.reason)){let e=await a.control.cleanup(i);await E({store:t.store,resourcePath:n.resourcePath,expected:i.fence,run:async t=>N(t,e)}),P(t,e)}throw new e(`COMMAND_FAILED`,a.reattached.message??`${_(t.displayName)} cannot be reattached`,{reason:a.reattached.reason,hint:t.messages.cleanupPendingHint})}}finally{await a.control[Symbol.asyncDispose]()}}function Ce(t,n){return new e(`INVALID_ARGS`,n===`missing`?t.messages.noActive:`${_(t.displayName)} recovery record is not open`)}function U(e){return e instanceof Error?e.message:String(e)}function W(e){Te(e.fileName);let t=t=>h.join(t,e.fileName);return Object.freeze({resourceKind:e.resourceKind,displayName:e.displayName,resolvePath:t,read(t){let n,r;try{if(n=l(t),n===void 0)return{status:`missing`};r=JSON.parse(g.readFileSync(n,`utf8`))}catch(t){return K(t)?{status:`missing`}:G(De(t,e.displayName))}finally{n!==void 0&&g.closeSync(n)}return we(d(r),e.resourceKind)},write(e,t){let n=h.dirname(e);g.mkdirSync(n,{recursive:!0}),c({destination:e,contents:`${JSON.stringify(t)}\n`})},list(e){let n;try{n=g.readdirSync(e,{withFileTypes:!0})}catch{return[]}return n.filter(e=>e.isDirectory()).map(n=>t(h.join(e,n.name))).filter(Ee).sort()}})}function we(e,t){return e.status===`decoded`?e.envelope.resourceKind===t?{status:`decoded`,envelope:e.envelope}:G(`Expected ${t} resource record, received ${e.envelope.resourceKind}`):e}function Te(e){if(e.length===0||h.basename(e)!==e)throw TypeError(`Durable capture resource fileName must be one file name`)}function Ee(e){try{return g.lstatSync(e),!0}catch(e){return!K(e)}}function G(e){return{status:`unreattachable`,reason:`descriptor-invalid`,message:e}}function K(e){return typeof e==`object`&&!!e&&`code`in e&&e.code===`ENOENT`}function De(e,t){return e instanceof Error?e.message:`${t} resource record is invalid`}function Oe(e,t){t.admissionLedger.assertStartAllowed(t.device),ke(e,t.resourcePath,t.device);let n=e.store.read(t.resourcePath);return Object.freeze({token:ee.randomUUID(),generation:n.status===`decoded`?n.envelope.fence.generation+1:1})}function ke(r,i,a){let o=t(n(a));for(let n of r.store.list(h.dirname(h.dirname(i)))){let a=r.store.read(n);if(a.status===`unreattachable`)throw new e(`COMMAND_FAILED`,`${_(q(r.displayName))} ${r.displayName} recovery record is unreattachable: ${a.message}`,{reason:a.reason,retriable:!1,hint:`Retain the corrupt or future-version ${r.displayName} manifest for manual recovery; no replacement capture is safe.`});if(a.status===`decoded`&&a.envelope.lifecycle!==`completed`&&(n===i||t(a.envelope.device)===o))throw new e(`COMMAND_FAILED`,`${_(q(r.displayName))} ${r.displayName} resource for this device has not reached a confirmed terminal state`,{reason:`cleanup-unconfirmed`,hint:`Retry exact-owner cleanup using the existing ${r.displayName} manifest before starting a replacement.`})}}function q(e){return/^[aeiou]/i.test(e)?`an`:`a`}function J(e){let t=(t,n)=>e.store.resolvePath(t.resolveSessionDir(n)),n=t=>({definition:e,resolveSessionDir:e=>h.join(t.sessionsDir,u(e)),...t});return Object.freeze({store:e.store,resourcePath:t,createNextFence(t){return Oe(e,t)},adoptStarted(n){return te(e,{...n,reportUndurableCleanup:(e,t)=>{t.confirmed?n.admissionLedger.clearUndurableCleanup(e):n.admissionLedger.blockUndurableCleanup(e,t.reason)}},t(n.sessionStore,n.sessionName))},finishLive(n){return pe(e,n,t(n.sessionStore,n.sessionName))},finishRecovered(t){return Se(e,t)},forceCleanupLive(t){return ge(e,t)},recoverAll(e){return _e(n(e))},recoverOne(e,t){return z(n(e),t)}})}const Y=J({resourceKind:`screen-recording`,displayName:`screen recording`,store:W({resourceKind:m,fileName:`screen-recording.resource.json`,displayName:`screen recording`}),sessionSlot:{read:e=>e.screenRecording,replace:(e,t)=>({...e,screenRecording:t})},completionMetadata:Me,failedFinishPolicy:`preserve-retry-material`,messages:{noActive:`no active recording`,cleanupPendingHint:`Keep screen-recording.resource.json and retry stop through its exact runtime owner.`}});function Ae(e){return Y.adoptStarted(e)}function je(e){return Y.finishLive(e)}const X=`completion`;function Me(e){return{[X]:{backend:e.backend,outPath:e.outPath,startedAt:e.startedAt,completedAt:e.completedAt,...e.capturedDurationMs===void 0?{}:{capturedDurationMs:e.capturedDurationMs},...e.stopObservation===void 0?{}:{stopObservation:Pe(e.stopObservation)},...e.nativePathDisposition===void 0?{}:{nativePathDisposition:e.nativePathDisposition},scope:e.scope,showTouches:e.showTouches,recordOnlySession:e.recordOnlySession,...e.clientOutPath===void 0?{}:{clientOutPath:e.clientOutPath},...e.telemetryPath===void 0?{}:{telemetryPath:e.telemetryPath},...e.warning===void 0?{}:{warning:e.warning},...e.overlayWarning===void 0?{}:{overlayWarning:e.overlayWarning},...e.activeSessionApp===void 0?{}:{activeSessionApp:Ne(e.activeSessionApp)},...e.chunks===void 0?{}:{chunks:e.chunks.map(Fe)}}}}function Ne(e){return{bundleId:e.bundleId,...e.name===void 0?{}:{name:e.name}}}function Pe(e){return e.recorder===`confirmed`?{recorder:e.recorder}:{recorder:e.recorder,why:e.why}}function Fe(e){return{index:e.index,path:e.path,...e.clientOutPath===void 0?{}:{clientOutPath:e.clientOutPath}}}function Z(e){return Y.finishRecovered(e)}async function Q(e){let t;try{return t=await e.gateway.bind({device:Ie(e.envelope),intent:{kind:`exact-owner`,owner:e.envelope.owner,fence:e.envelope.fence},scope:e.scope}),e.scope.signal.throwIfAborted(),e.create(t)}catch(e){throw t&&await t[Symbol.asyncDispose](),e}}function Ie(e){return{platform:e.device.family,id:e.device.id,name:e.device.id,kind:e.device.kind,...e.device.target===void 0?{}:{target:e.device.target},...e.device.appleOs===void 0?{}:{appleOs:e.device.appleOs},...e.device.iosPhysicalDeviceBackend===void 0?{}:{iosPhysicalDeviceBackend:e.device.iosPhysicalDeviceBackend}}}function Le(e){return Y.recoverOne({sessionsDir:e.sessionsDir,scope:e.scope,perRecordDeadlineMs:e.perRecordDeadlineMs,onDiagnostic:e.onDiagnostic,acquireControl:async(t,n)=>await Re(e.gateway,t,n)},e.resourcePath)}async function Re(e,t,n){return await Q({gateway:e,envelope:t,scope:n,create:e=>$({runtime:o(e,a),dispose:async()=>await e[Symbol.asyncDispose]()})})}function $(e){return Object.freeze({reattach:async t=>await e.runtime.operations.screenRecordingReattach({envelope:t}),cleanup:async t=>await e.runtime.operations.screenRecordingCleanup({envelope:t}),[Symbol.asyncDispose]:e.dispose})}export{Ae as a,Y as c,X as i,J as l,Le as n,je as o,Q as r,Z as s,$ as t,W as u};
|
|
1
|
+
import{D as e}from"./sdk-contracts.js";import{A as t,D as n,O as r}from"./sdk-device.js";import{$t as i,O as a,Zt as o}from"./sdk-batch.js";import{r as s}from"./diagnostics.js";import{E as c}from"./owner-identity.js";import{i as l}from"./verified-file.js";import"./file.js";import"./diagnostics2.js";import{r as u}from"./session-paths.js";import{i as d,n as f,t as p}from"./durable-resource.js";import{n as m}from"./screen-recording-runtime.js";import h from"node:path";import g from"node:fs";import ee from"node:crypto";function _(e){return e.length===0?e:e[0].toUpperCase()+e.slice(1)}function v(e){return e.replaceAll(`-`,`_`)}async function te(e,t,n){let r={kind:`pending`};try{let i=ce(ie(e,t),`active`);e.store.write(n,i),r={kind:`persisted`},t.throwIfCanceled();let a=t.pendingHandle.transfer();r={kind:`transferred`,handle:a},t.sessionStore.set(t.sessionName,e.sessionSlot.replace(t.session,{handle:a,envelope:i}))}catch(i){throw await ne(e,t,n,r,i),i}}async function ne(e,t,n,r,i){let a=r.kind!==`pending`||b(e,t,n),o=re(e,t,n,await y(t,r));t.reportUndurableCleanup(t.device,!a&&o.cleanupError===void 0||o.confirmed?{confirmed:!0}:{confirmed:!1,reason:o.cleanupError instanceof Error?o.cleanupError.message:`The durable cleanup transition could not be confirmed`}),o.cleanupError!==void 0&&se(e,t,i,o.cleanupError)}function re(e,t,n,r){try{return{confirmed:oe(e,n,t.fence,r),cleanupError:r}}catch(n){return s({level:`error`,phase:`${v(e.resourceKind)}_pending_adoption_transition_failed`,data:{session:t.sessionName,transitionError:n instanceof Error?n.message:String(n)}}),{confirmed:!1,cleanupError:r??n}}}async function y(e,t){try{t.kind===`transferred`?await t.handle[Symbol.asyncDispose]():await e.pendingHandle[Symbol.asyncDispose]();return}catch(e){return e}}function b(e,t,n){try{return e.store.write(n,x(e,t,t.envelope.descriptor)),!0}catch(r){try{return e.store.write(n,x(e,t,{version:0,body:{reason:`runtime-contract-invalid`}})),!0}catch(n){return s({level:`error`,phase:`${v(e.resourceKind)}_runtime_contract_tombstone_failed`,data:{session:t.sessionName,descriptorError:r instanceof Error?r.message:String(r),persistenceError:n instanceof Error?n.message:String(n)}}),!1}}}function x(e,t,r){return f({resourceKind:e.resourceKind,sessionId:t.sessionName,device:n(t.device),owner:t.owner,fence:t.fence,lifecycle:`open`,descriptor:r,metadata:{phase:`runtime-contract-invalid`,runtimeContractInvalid:!0}})}function ie(t,n){let r=d(n.envelope);if(r.status===`decoded`&&ae(r.envelope,n,t.resourceKind))return r.envelope;throw new e(`COMMAND_FAILED`,`${_(t.displayName)} runtime returned an incoherent durable envelope`,{reason:`runtime-contract-invalid`,hint:`Retain the runtime diagnostics and report the selected device and owner.`})}function ae(e,r,a){return e.resourceKind===a&&e.sessionId===r.sessionName&&t(e.device,n(r.device))&&i(e.owner)===i(r.owner)&&e.fence.token===r.fence.token&&e.fence.generation===r.fence.generation&&e.lifecycle===`open`}function oe(e,t,n,r){let i=e.store.read(t);return i.status!==`decoded`||i.envelope.fence.token!==n.token||i.envelope.fence.generation!==n.generation?!1:(e.store.write(t,{...i.envelope,lifecycle:r===void 0?`completed`:`open`,metadata:{...i.envelope.metadata??{},phase:r===void 0?`completed`:`cleanup-pending`,cleanupStatus:r===void 0?`cleaned`:`cleanup-pending`}}),!0)}function se(e,t,n,r){s({level:`error`,phase:`${v(e.resourceKind)}_pending_adoption_cleanup_failed`,data:{session:t.sessionName,primaryError:n instanceof Error?n.message:String(n),cleanupError:r instanceof Error?r.message:String(r)}})}function ce(e,t){return Object.freeze({...e,lifecycle:`open`,metadata:{...e.metadata??{},phase:t}})}async function S(e){e.scope.signal.throwIfAborted();let t=new AbortController,n={...e.scope,signal:AbortSignal.any([e.scope.signal,t.signal])},r=()=>{},i=new Promise((e,t)=>{r=t}),a=()=>{},o=new Promise((t,n)=>{let r=()=>{try{e.scope.signal.throwIfAborted()}catch(e){n(e)}};if(e.scope.signal.aborted){r();return}e.scope.signal.addEventListener(`abort`,r,{once:!0}),a=()=>e.scope.signal.removeEventListener(`abort`,r)}),s=setTimeout(()=>{let n=new w(e.displayName,e.deadlineMs);t.abort(n),r(n)},e.deadlineMs);s.unref?.();let c=ue(e,n),l,u=c.then(e=>(l??={kind:`acquisition`},e),e=>{throw l??={kind:`acquisition-error`},e}),d=i.catch(e=>{throw l??={kind:`deadline`,error:e},e}),f=o.catch(e=>{throw l??={kind:`cancellation`,error:e},e});try{return await Promise.race([u,d,f])}finally{if(clearTimeout(s),a(),l?.kind===`deadline`||l?.kind===`cancellation`){let t=l.error;c.then(n=>le(e,n,t),()=>{}).catch(()=>{})}else c.catch(()=>{})}}async function le(e,t,n){try{t.reattached.status===`active`&&await C(e,t.reattached.handle,`late_handle_cleanup_failed`,n)}finally{await C(e,t.control,`late_control_cleanup_failed`,n)}}async function ue(e,t){let n,r;try{return n=await e.acquireControl(e.envelope,t),t.signal.throwIfAborted(),r=await n.reattach(e.envelope),t.signal.throwIfAborted(),{control:n,reattached:r}}catch(t){try{r?.status===`active`&&await C(e,r.handle,`late_handle_cleanup_failed`,t)}finally{n&&await C(e,n,`late_control_cleanup_failed`,t)}throw t}}async function C(e,t,n,r){try{await t[Symbol.asyncDispose]()}catch(t){e.onLateCleanupFailure(n,t,r)}}var w=class extends Error{deadlineMs;constructor(e,t){super(`${_(e)} recovery exceeded its ${t}ms deadline`),this.name=`DurableCaptureRecoveryDeadlineError`,this.deadlineMs=t}};const T=new Map;async function E(e){return await fe(e.resourcePath,async()=>{let t=e.store.read(e.resourcePath);if(t.status!==`decoded`)throw D(e.store,t.status===`missing`?`${e.store.displayName} resource record is missing`:`${e.store.displayName} resource record is unreattachable: ${t.message}`);if(!de(t.envelope.fence,e.expected))throw D(e.store,`${e.store.displayName} resource ownership fence was lost`);let n=t.envelope;return await e.run({get envelope(){return n},transition(t,r={}){return n=Object.freeze({...n,lifecycle:t,...r.descriptor===void 0?{}:{descriptor:r.descriptor},...r.metadata===void 0?{}:{metadata:r.metadata}}),e.store.write(e.resourcePath,n),n}})})}function de(e,t){return e.token===t.token&&e.generation===t.generation}async function fe(e,t){let n=T.get(e)??Promise.resolve(),r,i=new Promise(e=>{r=e}),a=n.catch(()=>{}).then(()=>i);T.set(e,a),await n.catch(()=>{});try{return await t()}finally{r(),T.get(e)===a&&T.delete(e)}}function D(t,n){return new e(`COMMAND_FAILED`,n,{reason:`ownership-fence-lost`,retriable:!1,hint:`Use the current ${t.displayName.toLowerCase()} resource owner or retain the recovery record for manual recovery.`})}async function pe(t,n,r){let i=t.sessionSlot.read(n.session);if(!i)throw new e(`INVALID_ARGS`,t.messages.noActive);try{let e=await O(t,{handle:i.handle,fence:i.envelope.fence,resourcePath:r,intent:n.intent});return j(t,n),e}catch(e){let i=t.store.read(r);throw i.status===`decoded`&&i.envelope.lifecycle===`completed`&&j(t,n),e}}async function O(e,t){return await E({store:e.store,resourcePath:t.resourcePath,expected:t.fence,run:async n=>{R(n);let r=L(n),i;try{i=await t.handle.finish(r)}catch(r){throw await k(e,n,t,r,t.intent),r}if(i.status===`completed`)return I(e,n,i),i.result;I(e,n,i);let a=F(e,i);throw await k(e,n,t,a,t.intent),a}})}async function k(e,t,n,r,i){if(i===`capture`&&e.failedFinishPolicy===`preserve-retry-material`){he(e,n,r);return}let a;try{a=await n.handle.forceCleanup()}catch(i){A(e,n,r,i,me(t,i));return}try{N(t,a)}catch(t){A(e,n,r,a.status===`cleanup-pending`?a.message??a.reason:`cleanup returned ${a.status}`,t);return}p(a)||A(e,n,r,a.message)}function me(e,t){try{N(e,{status:`cleanup-pending`,reason:`cleanup-unconfirmed`,message:M(t)});return}catch(e){return e}}function he(e,t,n){s({level:`error`,phase:`${v(e.resourceKind)}_finish_evidence_preserved`,data:{resourcePath:t.resourcePath,finishError:M(n),failedFinishPolicy:e.failedFinishPolicy}})}function A(e,t,n,r,i){s({level:`error`,phase:`${v(e.resourceKind)}_finish_cleanup_failed`,data:{resourcePath:t.resourcePath,finishError:M(n),cleanupError:r===void 0?`cleanup could not be confirmed`:M(r),...i===void 0?{}:{transitionError:M(i)}}})}function j(e,t){t.sessionStore.set(t.sessionName,e.sessionSlot.replace(t.session,void 0))}function M(e){return e instanceof Error?e.message:String(e)}async function ge(e,t){let n=e.sessionSlot.read(t.session);n&&(P(e,await E({store:e.store,resourcePath:t.resourcePath,expected:n.envelope.fence,run:async e=>{R(e);let t=await n.handle.forceCleanup();return N(e,t),t}})),t.sessionStore&&t.sessionName&&t.sessionStore.set(t.sessionName,e.sessionSlot.replace(t.session,void 0)))}function N(e,t){e.transition(p(t)?`completed`:`open`,{metadata:{...e.envelope.metadata??{},phase:p(t)?`completed`:`cleanup-pending`,cleanupStatus:t.status,...t.status===`cleanup-pending`?{cleanupPendingReason:t.reason,...t.message?{cleanupPendingMessage:t.message}:{}}:{}}})}function P(e,t){if(!p(t))throw F(e,t)}function F(t,n){return new e(`COMMAND_FAILED`,n.message??`${_(t.displayName)} cleanup could not be confirmed`,{reason:n.reason,retriable:n.reason!==`ownership-fence-lost`,hint:t.messages.cleanupPendingHint})}function I(e,t,n){if(n.status===`completed`){t.transition(`completed`,{metadata:{...t.envelope.metadata??{},...e.completionMetadata(n.result),phase:`completed`}});return}N(t,n)}function L(e){return Object.freeze({learned:e.envelope.metadata,record:t=>{e.transition(`open`,{metadata:{...e.envelope.metadata??{},...t}})}})}function R(e){e.transition(`open`,{metadata:{...e.envelope.metadata??{},phase:`completing`}})}async function _e(e){let t=e.definition.store.list(e.sessionsDir),n=[];for(let r of t)n.push(await z(e,r));return{scanned:t.length,recovered:n.filter(e=>e===`recovered`).length,retained:n.filter(e=>e===`retained`).length}}async function z(e,t){let n=ve(e,t);if(n.status!==`recoverable`)return n.status;try{return await ye(e,t,n.envelope,e.perRecordDeadlineMs??5e3)?`recovered`:`retained`}catch(n){return H(e,n instanceof w?`timed_out`:`failed`,t,{error:n instanceof Error?n.message:String(n),...n instanceof w?{deadlineMs:n.deadlineMs}:{}}),`retained`}}function ve(e,t){let n=e.definition.store.read(t);if(n.status===`unreattachable`)return H(e,`record_unreattachable`,t,{reason:n.reason,message:n.message,version:n.version}),{status:`retained`};if(n.status===`missing`||n.envelope.lifecycle===`completed`)return{status:`ignored`};let r=e.definition.store.resolvePath(e.resolveSessionDir(n.envelope.sessionId));return h.resolve(t)===h.resolve(r)?{status:`recoverable`,envelope:n.envelope}:(H(e,`session_path_mismatch`,t,{envelopeSessionId:n.envelope.sessionId,canonicalPath:r}),{status:`retained`})}async function ye(e,t,n,r){return await be(e,t,n,await S({displayName:e.definition.displayName,envelope:n,scope:e.scope,deadlineMs:r,acquireControl:e.acquireControl,onLateCleanupFailure:(n,r,i)=>H(e,n,t,{error:r instanceof Error?r.message:String(r),primaryError:i instanceof Error?i.message:String(i)})}))}async function be(e,t,n,r){try{switch(r.reattached.status){case`active`:{let i=r.reattached.handle,a=await E({store:e.definition.store,resourcePath:t,expected:n.fence,run:async e=>{xe(e);let t=await i.forceCleanup();return N(e,t),t}});return p(a)}case`completed`:return await B(e,t,n,{...e.definition.completionMetadata(r.reattached.result)}),!0;case`missing`:return await B(e,t,n,{recoveryStatus:`already-missing`}),!0;case`unreattachable`:{if(!V(r.reattached.reason))return H(e,`retained`,t,{reason:r.reattached.reason,message:r.reattached.message}),!1;let i=await r.control.cleanup(n);return await E({store:e.definition.store,resourcePath:t,expected:n.fence,run:async e=>N(e,i)}),p(i)}}}finally{await r.control[Symbol.asyncDispose]()}}async function B(e,t,n,r){await E({store:e.definition.store,resourcePath:t,expected:n.fence,run:async e=>{e.transition(`completed`,{metadata:{...e.envelope.metadata??{},phase:`completed`,...r}})}})}function xe(e){e.transition(`open`,{metadata:{...e.envelope.metadata??{},phase:`completing`}})}function V(e){switch(e){case`descriptor-invalid`:case`descriptor-version-unsupported`:case`ownership-fence-lost`:return!1;case`owner-unavailable`:case`transport-not-reattachable`:return!0}}function H(e,t,n,r){let i={phase:`${v(e.definition.resourceKind)}_recovery_${t}`,resourcePath:n,data:r};e.onDiagnostic?e.onDiagnostic(i):s({level:`warn`,phase:i.phase,data:{resourcePath:n,...r}})}async function Se(t,n){let r=t.store.read(n.resourcePath);if(r.status!==`decoded`||r.envelope.lifecycle!==`open`)throw Ce(t,r.status);let i=r.envelope,a=await S({displayName:t.displayName,envelope:i,scope:n.scope,deadlineMs:n.deadlineMs??5e3,acquireControl:n.acquireControl,onLateCleanupFailure:(e,r,i)=>n.scope.diagnostics.emit({level:`error`,phase:`${v(t.resourceKind)}_recovery_${e}`,data:{resourcePath:n.resourcePath,error:U(r),primaryError:U(i)}})});try{switch(a.reattached.status){case`active`:return await O(t,{handle:a.reattached.handle,fence:i.fence,resourcePath:n.resourcePath,intent:`capture`});case`completed`:{let e=a.reattached.result;return await E({store:t.store,resourcePath:n.resourcePath,expected:i.fence,run:async n=>{I(t,n,{status:`completed`,result:e,alreadyCompleted:!0})}}),e}case`missing`:throw new e(`COMMAND_FAILED`,`${_(t.displayName)} is missing`,{reason:`resource-missing`,hint:t.messages.cleanupPendingHint});case`unreattachable`:if(V(a.reattached.reason)){let e=await a.control.cleanup(i);await E({store:t.store,resourcePath:n.resourcePath,expected:i.fence,run:async t=>N(t,e)}),P(t,e)}throw new e(`COMMAND_FAILED`,a.reattached.message??`${_(t.displayName)} cannot be reattached`,{reason:a.reattached.reason,hint:t.messages.cleanupPendingHint})}}finally{await a.control[Symbol.asyncDispose]()}}function Ce(t,n){return new e(`INVALID_ARGS`,n===`missing`?t.messages.noActive:`${_(t.displayName)} recovery record is not open`)}function U(e){return e instanceof Error?e.message:String(e)}function W(e){Te(e.fileName);let t=t=>h.join(t,e.fileName);return Object.freeze({resourceKind:e.resourceKind,displayName:e.displayName,resolvePath:t,read(t){let n,r;try{if(n=l(t),n===void 0)return{status:`missing`};r=JSON.parse(g.readFileSync(n,`utf8`))}catch(t){return K(t)?{status:`missing`}:G(De(t,e.displayName))}finally{n!==void 0&&g.closeSync(n)}return we(d(r),e.resourceKind)},write(e,t){let n=h.dirname(e);g.mkdirSync(n,{recursive:!0}),c({destination:e,contents:`${JSON.stringify(t)}\n`})},list(e){let n;try{n=g.readdirSync(e,{withFileTypes:!0})}catch{return[]}return n.filter(e=>e.isDirectory()).map(n=>t(h.join(e,n.name))).filter(Ee).sort()}})}function we(e,t){return e.status===`decoded`?e.envelope.resourceKind===t?{status:`decoded`,envelope:e.envelope}:G(`Expected ${t} resource record, received ${e.envelope.resourceKind}`):e}function Te(e){if(e.length===0||h.basename(e)!==e)throw TypeError(`Durable capture resource fileName must be one file name`)}function Ee(e){try{return g.lstatSync(e),!0}catch(e){return!K(e)}}function G(e){return{status:`unreattachable`,reason:`descriptor-invalid`,message:e}}function K(e){return typeof e==`object`&&!!e&&`code`in e&&e.code===`ENOENT`}function De(e,t){return e instanceof Error?e.message:`${t} resource record is invalid`}function Oe(e,t){t.admissionLedger.assertStartAllowed(t.device),ke(e,t.resourcePath,t.device);let n=e.store.read(t.resourcePath);return Object.freeze({token:ee.randomUUID(),generation:n.status===`decoded`?n.envelope.fence.generation+1:1})}function ke(t,i,a){let o=r(n(a));for(let n of t.store.list(h.dirname(h.dirname(i)))){let a=t.store.read(n);if(a.status===`unreattachable`)throw new e(`COMMAND_FAILED`,`${_(q(t.displayName))} ${t.displayName} recovery record is unreattachable: ${a.message}`,{reason:a.reason,retriable:!1,hint:`Retain the corrupt or future-version ${t.displayName} manifest for manual recovery; no replacement capture is safe.`});if(a.status===`decoded`&&a.envelope.lifecycle!==`completed`&&(n===i||r(a.envelope.device)===o))throw new e(`COMMAND_FAILED`,`${_(q(t.displayName))} ${t.displayName} resource for this device has not reached a confirmed terminal state`,{reason:`cleanup-unconfirmed`,hint:`Retry exact-owner cleanup using the existing ${t.displayName} manifest before starting a replacement.`})}}function q(e){return/^[aeiou]/i.test(e)?`an`:`a`}function J(e){let t=(t,n)=>e.store.resolvePath(t.resolveSessionDir(n)),n=t=>({definition:e,resolveSessionDir:e=>h.join(t.sessionsDir,u(e)),...t});return Object.freeze({store:e.store,resourcePath:t,createNextFence(t){return Oe(e,t)},adoptStarted(n){return te(e,{...n,reportUndurableCleanup:(e,t)=>{t.confirmed?n.admissionLedger.clearUndurableCleanup(e):n.admissionLedger.blockUndurableCleanup(e,t.reason)}},t(n.sessionStore,n.sessionName))},finishLive(n){return pe(e,n,t(n.sessionStore,n.sessionName))},finishRecovered(t){return Se(e,t)},forceCleanupLive(t){return ge(e,t)},recoverAll(e){return _e(n(e))},recoverOne(e,t){return z(n(e),t)}})}const Y=J({resourceKind:`screen-recording`,displayName:`screen recording`,store:W({resourceKind:m,fileName:`screen-recording.resource.json`,displayName:`screen recording`}),sessionSlot:{read:e=>e.screenRecording,replace:(e,t)=>({...e,screenRecording:t})},completionMetadata:Me,failedFinishPolicy:`preserve-retry-material`,messages:{noActive:`no active recording`,cleanupPendingHint:`Keep screen-recording.resource.json and retry stop through its exact runtime owner.`}});function Ae(e){return Y.adoptStarted(e)}function je(e){return Y.finishLive(e)}const X=`completion`;function Me(e){return{[X]:{backend:e.backend,outPath:e.outPath,startedAt:e.startedAt,completedAt:e.completedAt,...e.capturedDurationMs===void 0?{}:{capturedDurationMs:e.capturedDurationMs},...e.stopObservation===void 0?{}:{stopObservation:Pe(e.stopObservation)},...e.nativePathDisposition===void 0?{}:{nativePathDisposition:e.nativePathDisposition},scope:e.scope,showTouches:e.showTouches,recordOnlySession:e.recordOnlySession,...e.clientOutPath===void 0?{}:{clientOutPath:e.clientOutPath},...e.telemetryPath===void 0?{}:{telemetryPath:e.telemetryPath},...e.warning===void 0?{}:{warning:e.warning},...e.overlayWarning===void 0?{}:{overlayWarning:e.overlayWarning},...e.activeSessionApp===void 0?{}:{activeSessionApp:Ne(e.activeSessionApp)},...e.chunks===void 0?{}:{chunks:e.chunks.map(Fe)}}}}function Ne(e){return{bundleId:e.bundleId,...e.name===void 0?{}:{name:e.name}}}function Pe(e){return e.recorder===`confirmed`?{recorder:e.recorder}:{recorder:e.recorder,why:e.why}}function Fe(e){return{index:e.index,path:e.path,...e.clientOutPath===void 0?{}:{clientOutPath:e.clientOutPath}}}function Z(e){return Y.finishRecovered(e)}async function Q(e){let t;try{return t=await e.gateway.bind({device:Ie(e.envelope),intent:{kind:`exact-owner`,owner:e.envelope.owner,fence:e.envelope.fence},scope:e.scope}),e.scope.signal.throwIfAborted(),e.create(t)}catch(e){throw t&&await t[Symbol.asyncDispose](),e}}function Ie(e){return{platform:e.device.family,id:e.device.id,name:e.device.id,kind:e.device.kind,...e.device.target===void 0?{}:{target:e.device.target},...e.device.appleOs===void 0?{}:{appleOs:e.device.appleOs},...e.device.iosPhysicalDeviceBackend===void 0?{}:{iosPhysicalDeviceBackend:e.device.iosPhysicalDeviceBackend}}}function Le(e){return Y.recoverOne({sessionsDir:e.sessionsDir,scope:e.scope,perRecordDeadlineMs:e.perRecordDeadlineMs,onDiagnostic:e.onDiagnostic,acquireControl:async(t,n)=>await Re(e.gateway,t,n)},e.resourcePath)}async function Re(e,t,n){return await Q({gateway:e,envelope:t,scope:n,create:e=>$({runtime:o(e,a),dispose:async()=>await e[Symbol.asyncDispose]()})})}function $(e){return Object.freeze({reattach:async t=>await e.runtime.operations.screenRecordingReattach({envelope:t}),cleanup:async t=>await e.runtime.operations.screenRecordingCleanup({envelope:t}),[Symbol.asyncDispose]:e.dispose})}export{Ae as a,Y as c,X as i,J as l,Le as n,je as o,Q as r,Z as s,$ as t,W as u};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{D as e}from"./sdk-device.js";import{a as t,n}from"./durable-resource.js";import{n as r}from"./async-lifecycle.js";import{n as i,t as a}from"./screen-recording-completion.js";import{t as o}from"./screen-recording-options.js";import{n as s}from"./screen-recording-runtime.js";function c(e){return Object.freeze({resourceKind:s,version:1,encode:e=>({...e}),decode:t=>t.backend===e&&typeof t.outputPath==`string`?{status:`decoded`,descriptor:Object.freeze({backend:e,outputPath:t.outputPath})}:{status:`invalid`,message:`Invalid ${e} screen-recording descriptor`}})}function l(e){return{status:`unreattachable`,reason:`transport-not-reattachable`,message:e}}function u(e){return{status:`cleanup-pending`,reason:`manual-recovery-required`,message:e}}async function d(l){let{host:u,device:d,owner:m,input:h,signal:g,transport:_}=l;o(h,l.support,l.unsupported),g.throwIfAborted(),await u.screenRecording.outputs.prepare(h.outputPath);let v=f(_),y=!1;try{await _.start(g),y=!0,g.throwIfAborted()}catch(e){throw y&&await v().catch(()=>{}),g.throwIfAborted(),e}let b=i(p(_.backend,h),{finish:async e=>{let t=await v();_.collect&&await _.collect(t,e.outPath);let n=await u.screenRecording.finalize.complete({outputPath:e.outPath,showTouches:!1,gestureEvents:e.gestureEvents,...e.exportQuality===void 0?{}:{exportQuality:e.exportQuality},targetLabel:_.targetLabel});return a(e,n,{stopObservation:{recorder:`confirmed`},showTouches:!1})},forceCleanup:async()=>{try{return await v(),{status:`cleaned`}}catch(e){return{status:`cleanup-pending`,reason:`transport-failed`,message:e instanceof Error?e.message:`${_.backend} recording cleanup failed`}}}});return Object.freeze({pendingHandle:new r(b),envelope:n({resourceKind:s,sessionId:h.sessionId,device:e(d),owner:m,fence:h.fence,lifecycle:`open`,descriptor:t(c(_.backend),{backend:_.backend,outputPath:h.outputPath})})})}function f(e){let t;return()=>t??=e.stop().catch(e=>{throw t=void 0,e})}function p(e,t){return Object.freeze({backend:e,outPath:t.outputPath,...t.clientOutputPath===void 0?{}:{clientOutPath:t.clientOutputPath},startedAt:Date.now(),scope:t.scope,showTouches:!1,recordOnlySession:t.recordOnlySession,...t.activeSessionApp===void 0?{}:{activeSessionApp:t.activeSessionApp},...t.exportQuality===void 0?{}:{exportQuality:t.exportQuality},gestureEvents:[]})}export{u as n,l as r,d as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{D as e,g as t,o as n}from"./sdk-contracts.js";import{c as r,d as i,l as a,r as o}from"./capture.js";import{b as s,d as c,w as l}from"./sdk-device.js";import{Ar as u,Fr as d,Ft as f,Ir as p,Kr as m,Rr as h,Ur as g,d as _,l as v,mn as ee,qr as y,x as te,y as ne}from"./sdk-batch.js";import{t as re}from"./session-store.js";import{c as b,f as x,i as S,m as C,o as w}from"./session-snapshot.js";import{M as ie,h as ae,l as oe,v as se}from"./runtime.js";import{t as T}from"./snapshot-state.js";import{i as ce,o as le,r as ue}from"./png-worker-client.js";import{t as de}from"./png-size.js";import{r as fe,t as pe}from"./screenshot-density.js";import{a as E,c as me,o as D,s as O,t as he}from"./screenshot-overlay-draw.js";import{a as ge,i as _e,n as ve,t as ye}from"./session-runtime-admission.js";import k from"node:path";import{promises as A}from"node:fs";import j from"node:os";const M=v(_),N=Fe(M);function P(e){return I(e)?.route??`generic`}function F(e){return I(e)?.sessionKind}function be(e){return I(e)?.leaseAdmissionExempt===!0}function xe(e){return I(e)?.selectorValidationExempt!==!0}function Se(e){return I(e)?.sessionExecutionLockExempt!==!0}function Ce(e){return I(e)?.replayScopedAction===!0}function we(e){return I(e)?.allowInvalidRecording!==!0}function Te(e){return I(e)?.saveScriptFlagOwner===!0}function Ee(){return M.filter(e=>e.saveScriptFlagOwner===!0).map(e=>e.command).sort()}function De(e){return I(e)?.lockPolicySelectorOverride===!0}function Oe(e){return I(e)?.androidBlockingDialogGuard===!0}function ke(e){if(e.command===`human_control`||e.command===`lease_heartbeat`)return!1;let t=te(e);return t===void 0?F(e.command)!==`observability`&&ne(e.command)!==`observe`:t!==`observes-app`}function Ae(e){return I(e.command)?.preferExplicitDeviceOverExistingSession===!0}function je(e){let t=I(e.command)?.allowSessionlessDefaultDevice;return typeof t==`function`&&t(e)}function Me(e){return I(e.command)?.sessionlessLeaseAdmissionExemption?.(e)}function Ne(e){let t=I(e.command)?.refFrameEffect;return typeof t==`function`?t(e):t}function Pe(e,t){return t.hasExistingSession?Ae(e)&&t.hasExplicitDeviceIdentity?`explicit-device`:`existing-session`:Ie(e)?`skip`:t.hasDeviceSelectionInput?`explicit-device`:je(e)?`sessionless-default-device`:`skip`}function I(e){return N.descriptorsByCommand.get(e)}function Fe(e){let t=new Map;for(let n of e){if(t.has(n.command))throw Error(`Duplicate daemon command descriptor: ${n.command}`);t.set(n.command,n)}return{descriptorsByCommand:t}}function Ie(e){let t=I(e.command);if(t?.route===`lease`)return!0;let n=t?.skipSessionlessProviderDevice;return typeof n==`function`&&n(e)}const L=o.pendingPixelIdentityEvidence,Le=[{target:`ios-simulator`,status:`accepted`},{target:`android-emulator`,status:`accepted`},{target:`android-device`,status:`rejected`,rejectionReason:L},{target:`macos-app-window`,status:`rejected`,rejectionReason:L},{target:`ios-physical`,status:`rejected`,rejectionReason:L},{target:`macos-helper`,status:`rejected`,rejectionReason:L},{target:`web`,status:`rejected`,rejectionReason:L},{target:`linux`,status:`rejected`,rejectionReason:L},{target:`tvos`,status:`rejected`,rejectionReason:L},{target:`harmonyos`,status:`rejected`,rejectionReason:L},{target:`vega`,status:`rejected`,rejectionReason:L}];function Re(e,t){switch(e.platform){case`apple`:return ze(e,t);case`android`:return e.kind===`device`?`android-device`:`android-emulator`;case`harmonyos`:return`harmonyos`;case`vega`:return`vega`;case`linux`:return`linux`;case`web`:return`web`}}function ze(e,t){let n=l(e);switch(n){case`ios`:case`ipados`:return e.kind===`device`?`ios-physical`:`ios-simulator`;case`tvos`:return`tvos`;case`macos`:return Be(t);case`watchos`:case`visionos`:throw R(n)}}function Be(e){return e===`app`||e===`frontmost-app`?`macos-app-window`:`macos-helper`}function R(t,n){return new e(`UNSUPPORTED_OPERATION`,`screenshot --crop-on is not accepted on ${t} targets`,{reason:o.targetNotAccepted,...n?{rejectionReason:n}:{}})}function Ve(t){if(t.overlayRefs||t.fullscreen)throw new e(`INVALID_ARGS`,`--crop-on cannot be combined with --overlay-refs or --fullscreen: both move the captured frame away from the snapshot viewport the crop is measured against`,{reason:o.frameMismatch});try{ee(t.cropOn)}catch{throw new e(`INVALID_ARGS`,`screenshot --crop-on requires a valid selector expression`,{reason:o.selectorInvalid})}let n=Re(t.device,t.surface),r=Le.find(e=>e.target===n);if(!r||r.status===`rejected`)throw R(n,r?.status===`rejected`?r.rejectionReason:void 0)}async function He(t,n){if(!Ue(n))throw new e(`INVALID_ARGS`,`Screenshot crop box must be positive integer pixel offsets`);let r=await ue(await A.readFile(t),n,`screenshot`);r!==null&&await A.writeFile(t,r)}function Ue(e){return Number.isInteger(e.x)&&e.x>=0&&Number.isInteger(e.y)&&e.y>=0&&Number.isInteger(e.width)&&e.width>0&&Number.isInteger(e.height)&&e.height>0}function We(t){switch(t){case`android`:return`device-pixels`;case`xctest`:case`macos-helper`:return`viewport-points`;default:throw new e(`UNSUPPORTED_OPERATION`,`screenshot --crop-on does not accept snapshot backend "${t??`unknown`}"`,{reason:o.targetNotAccepted})}}function z(e,t,n,r,i){if(e===`device-pixels`||t===null)return Je(n);let a=r/t.width,o=i/t.height;return{x:Math.round((n.x-t.x)*a),y:Math.round((n.y-t.y)*o),width:Math.round(n.width*a),height:Math.round(n.height*o)}}function Ge(e,t,n){let r=Math.max(e.x,0),i=Math.max(e.y,0),a=Math.min(e.x+e.width,t),o=Math.min(e.y+e.height,n);return a<=r||o<=i?null:{x:r,y:i,width:a-r,height:o-i}}function B(e){let t=null;for(let n of e)!u(n)||!g(n.rect)||(!t||m(n.rect)>m(t))&&(t=n.rect);return t||Ke(e.filter(e=>g(e.rect)&&!qe(e)))}function Ke(e){let t=1/0,n=1/0,r=-1/0,i=-1/0;for(let a of e)g(a.rect)&&(t=Math.min(t,a.rect.x),n=Math.min(n,a.rect.y),r=Math.max(r,a.rect.x+a.rect.width),i=Math.max(i,a.rect.y+a.rect.height));return!Number.isFinite(t)||!Number.isFinite(n)||r<=t||i<=n?null:{x:t,y:n,width:r-t,height:i-n}}function qe(e){return p(e.type??``)===`image`&&!d(e.label)}function Je(e){return{x:Math.round(e.x),y:Math.round(e.y),width:Math.round(e.width),height:Math.round(e.height)}}const Ye=`${o.partialIntersection}: the selector frame extends past the captured image; the crop was clipped to the image frame`;function Xe(e){return e?.partialIntersection?[Ye]:[]}async function Ze(t){let{device:n,session:r,surface:i,cropOn:a,screenshotPath:s,logPath:c,dispatchContext:l}=t,u={snapshotInteractiveOnly:!1},d=await b({device:n,session:r,flags:u,logPath:c,snapshotScope:void 0,captureData:async()=>await t.captureSnapshot({options:{appBundleId:l.appBundleId,interactiveOnly:!1,includeRects:!0,surface:i},execution:C(l)})}),f=T(d,u);if(f.snapshotQuality?.state===`sparse`)throw new e(`COMMAND_FAILED`,`the snapshot taken for --crop-on was sparse and cannot be read as the screen`,{reason:o.captureUnreadable});let p=await Qe(f.nodes,a,f.truncated,n),m=await de(s),h=z(We(f.backend),B(f.nodes),p.rect,m.width,m.height),g=Ge(h,m.width,m.height);if(g===null)throw new e(`COMMAND_FAILED`,`the frame resolved by --crop-on occupies no pixel of the capture`,{reason:o.emptyIntersection});let _=g.x!==h.x||g.y!==h.y||g.width<h.width||g.height<h.height;return await He(s,g),{partialIntersection:_}}async function Qe(t,n,r,i){let a=await oe(ae.cropTarget,t,n,{platform:s(i)});if(a.kind===`ambiguous`)throw new e(`COMMAND_FAILED`,`--crop-on matched ${a.matchedNodes.length} nodes and must resolve to one`,{reason:o.targetAmbiguous,candidates:a.matchedNodes.map(e=>e.label??e.ref),matches:a.matchedNodes.length});if(a.kind===`none`)throw r?new e(`COMMAND_FAILED`,`the snapshot taken for --crop-on was truncated, so a missing match is not proven`,{reason:o.captureIncomplete}):new e(`COMMAND_FAILED`,`--crop-on matched no node: ${n}`,{reason:o.targetNotFound,hint:`find ${n} list`});return a.node}const $e=[`scroll`,`list`,`recyclerview`,`edittext`,`textfield`];function et(e,t,n){if(e.backend!==`android`||!n.hittable||!D(n.rect)||u(n))return!1;let r=p(n.type??``);return!($e.some(e=>r.includes(e))||t&&O(n.rect)>O(t)*.25)}function tt(e,t,n,r){return!e.rect||e.hittable!==!0||n(e)||r(e)?null:nt(e,t,r)}function nt(e,t,n){let r=e.rect,i=rt(e,t,n);if(!i)return null;let a=i.y-r.y,o=r.y+r.height-(i.y+i.height);if(a<0||o<0||Math.abs(o-a)<16)return null;let s=Math.min(a,o),c=Math.round(i.y-s),l=Math.round(i.height+s*2);return l<=0||l>=r.height?null:{x:r.x,y:c,width:r.width,height:l}}function rt(e,t,n){let r=e.rect,i=new Map(t.map(e=>[e.index,e])),a=t.filter(t=>t.ref!==e.ref&&at(t,e,i)&&it(t,n)&&D(t.rect)&&y(r,t.rect)).map(e=>e.rect);return a.length<2?null:me(a)}function it(e,t){let n=p(e.type??``);return n.includes(`text`)||n.includes(`image`)&&t(e)}function at(e,t,n){let r=e;for(;r.parentIndex!==void 0;){let e=n.get(r.parentIndex);if(!e)return!1;if(e.ref===t.ref)return!0;r=e}return!1}const ot=[`button`,`link`,`menu`,`tab`,`textfield`,`searchfield`,`securetextfield`,`checkbox`,`radio`,`switch`,`cell`];async function V(e){let t=await A.readFile(e.screenshotPath),n=await ce(t,`screenshot`),r=st(e.snapshot,n.width,n.height,{maxRefs:e.maxRefs});for(let e of r)he(n,e);return await A.writeFile(e.screenshotPath,await le(n)),r}function st(e,n,r,i={}){let a=B(e.nodes),o=new Map;for(let t of e.nodes){if(!ut(e,a,t))continue;let i=dt(e.nodes,t);if(!i?.rect||!D(i.rect))continue;let s=ft(t,i,e.nodes),c=pt(t,i,s),l=H(e,a,lt(e,i,e.nodes),n,r);if(!D(l))continue;let u=o.get(i.ref);(!u||c>u.score)&&o.set(i.ref,{ref:i.ref,label:s,rect:i.rect,overlayRect:l,score:c})}return ct(e,a,o,n,r),mt([...o.values()]).sort(Y).slice(0,i.maxRefs??24).sort(J).map(e=>({ref:e.ref,label:e.label,rect:e.rect,overlayRect:e.overlayRect,center:t(e.overlayRect)}))}function ct(e,t,n,r,i){let a=ie(e.nodes).primaryAction;if(!a?.ref||!a.rect||!D(a.rect))return;let o=H(e,t,a.rect,r,i);if(!D(o))return;let s={ref:a.ref,label:a.label,rect:a.rect,overlayRect:o,score:100},c=n.get(a.ref);n.set(a.ref,c?{...c,score:Math.max(c.score,s.score)}:s)}function lt(e,t,n){return e.backend===`android`?tt(t,n,U,e=>!!q(e))??t.rect:t.rect}function ut(e,t,n){let r=[n.label,n.value].some(G)||K(n.identifier);return et(e,t,n)?!0:U(n)?r:r&&ht(n)}function dt(e,t){return[W(t)?t:null,h(e,t,W),t.hittable?t:null,h(e,t,e=>e.hittable===!0)].find(gt)??null}function ft(e,t,n){let r=q(e);return e.ref!==t.ref&&r?r:_t(t,n)||q(t)}function pt(e,t,n){let r=0;return e.ref===t.ref&&(r+=4),t.hittable&&(r+=3),U(t)&&(r+=3),U(e)&&(r+=2),n&&(r+=2),K(t.identifier)&&(r+=1),d(t.value)&&(r+=1),r}function mt(e){let t=[];for(let n of e.sort((e,t)=>O(e.overlayRect)-O(t.overlayRect))){let e=t.findIndex(e=>e.label!==void 0&&e.label===n.label&&(y(e.overlayRect,n.overlayRect)||y(n.overlayRect,e.overlayRect)));if(e===-1){t.push(n);continue}O(n.overlayRect)<O(t[e].overlayRect)&&(t[e]=n)}return t}function H(e,t,n,r,i){return Ct(z(e.backend===`android`?`device-pixels`:`viewport-points`,t,n,r,i),r,i)}function U(e){let t=[e.type,e.role,e.subrole].map(e=>p(e??``)).join(` `);return ot.some(e=>t.includes(e))}function W(e){return U(e)&&!u(e)}function ht(e){let t=p(e.type??``);return t.includes(`statictext`)||t.includes(`image`)||t.includes(`text`)||t.includes(`other`)}function gt(e){return!!(e?.rect&&D(e.rect)&&!u(e))}function G(e){return d(e)?!bt(e):!1}function K(e){return typeof e!=`string`||!G(e)?!1:!xt(e)}function q(e){let t=[e.label,e.value].find(G);if(t)return t.trim();if(K(e.identifier))return e.identifier.trim()}function _t(e,t){let n=null;for(let r of t){if(r.ref===e.ref||!vt(r,e,t))continue;let i=q(r);if(!i)continue;let a=yt(r);(!n||a>n.score)&&(n={label:i,score:a})}return n?.label}function vt(e,t,n){let r=e;for(;r.parentIndex!==void 0;){let e=n[r.parentIndex];if(!e)return!1;if(e.ref===t.ref)return!0;r=e}return!1}function yt(e){let t=0;return p(e.type??``).includes(`text`)&&(t+=2),G(e.label)&&(t+=2),G(e.value)&&(t+=1),t}function bt(e){let t=e?.trim().toLowerCase();return t===`toolbar`||t===`window`||t===`application`||t?.startsWith(`vertical scroll bar`)===!0}function xt(e){return/^[a-z0-9_.]+:id\/[a-z0-9_.-]+$/i.test(e.trim())}function St(e,t){return Number.parseInt(e.replace(/^\D+/,``),10)-Number.parseInt(t.replace(/^\D+/,``),10)}function Ct(e,t,n){let r=E(e.x,0,Math.max(0,t-1)),i=E(e.y,0,Math.max(0,n-1)),a=Math.max(1,t-r),o=Math.max(1,n-i);return{x:r,y:i,width:E(e.width,1,a),height:E(e.height,1,o)}}function J(e,t){let n=e.overlayRect.y-t.overlayRect.y;if(n!==0)return n;let r=e.overlayRect.x-t.overlayRect.x;return r===0?St(e.ref,t.ref):r}function Y(e,t){return t.score===e.score?J(e,t):t.score-e.score}async function X(e){let t=f({overlayRefs:e.overlayRefs,cropOn:e.cropOn!==void 0}),n=await ye({device:e.device,plan:t,inspectFacts:e.inspectFacts});return n.admitted?{ok:!0,runtime:await wt(e.bindDevice,n)}:{ok:!1,response:Et(t.kind,n.operation,n.fact)}}async function wt(e,t){let n=ve(e),{device:r,plan:i}=ge(t);switch(i.kind){case`capture`:{let e=await n(r,i.use);return Object.freeze({captureScreenshot:Z(e)})}case`capture-with-overlay-refs`:case`capture-with-crop-on`:{let e=await n(r,i.use);return Object.freeze({captureScreenshot:Z(e),captureSnapshot:Tt(e)})}}}function Z(e){return async t=>await e.operations.captureScreenshot(t)}function Tt(e){return async t=>await e.operations.captureSnapshot(t)}function Et(e,t,r){return t===`captureScreenshot`?_e(`screenshot`,r):e===`capture-with-crop-on`?n(`UNSUPPORTED_OPERATION`,`--crop-on crops the capture to a selector frame using a snapshot taken on the same screen, which this target cannot capture.`,{reason:r.available?void 0:r.reason},{hint:(r.available?void 0:r.hint)??`Re-run screenshot without --crop-on.`}):n(`UNSUPPORTED_OPERATION`,`--overlay-refs annotates a capture with the refs of a snapshot taken on the same screen, which this target cannot capture.`,{reason:r.available?void 0:r.reason},{hint:(r.available?void 0:r.hint)??`Re-run screenshot without --overlay-refs.`})}async function Dt(t){let{req:n,session:i}=t,a=r(`screenshot`,n.flags);if(a)throw new e(`INVALID_ARGS`,a);pe(i.device,n.flags?.screenshotPixelDensity);let o=Mt(n),s=typeof n.flags?.screenshotCropOn==`string`&&n.flags.screenshotCropOn.length>0?n.flags.screenshotCropOn:void 0;s!==void 0&&Ve({device:i.device,surface:i.surface,cropOn:s,overlayRefs:n.flags?.overlayRefs===!0,fullscreen:n.flags?.screenshotFullscreen===!0});let c=await X({device:i.device,overlayRefs:n.flags?.overlayRefs===!0,cropOn:s,inspectFacts:t.inspectFacts,bindDevice:t.bindDevice});if(!c.ok)return c;let l=c.runtime,u={warnings:[]};return{ok:!0,recorded:o.recorded,execute:async e=>await Ot({session:e.session,sessionName:e.sessionName,logPath:e.logPath,dispatchContext:e.dispatchContext,flags:e.request.flags,outPath:o.outPath,runtime:l,cropOn:s,cropRun:u})}}async function Q(e){let{session:t,sessionName:n,outPath:r,dispatchContext:a}=e;return await x({backend:Nt(e),artifacts:Pt(),sessions:w({sessionName:n,getSession:()=>t,recordOptions:{includeSnapshot:!1},setRecord:()=>{}}),policy:se()}).capture.screenshot({session:n,requestId:a.requestId,appBundleId:t.appBundleId,...i(a),surface:t.surface,...r?{out:{kind:`path`,path:r}}:{}})}function $(e){return C(e)}async function Ot(e){let{session:t,runtime:n,flags:r}=e,i=kt({cropOn:e.cropOn,captureSnapshot:n.captureSnapshot,cropRun:e.cropRun,logPath:e.logPath}),a=await Q({session:t,sessionName:e.sessionName,outPath:e.outPath,dispatchContext:e.dispatchContext,captureScreenshot:n.captureScreenshot,...i?{crop:i}:{}}),o=[...a.warnings??[],...i?.run?.warnings??[]];return{...a,...o.length>0?{warnings:o}:{},...await At({session:t,cropOn:e.cropOn,captureSnapshot:n.captureSnapshot,screenshotPath:a.path,logPath:e.logPath,dispatchContext:e.dispatchContext}),...await fe({device:t.device,path:a.path,requestedPixelDensity:r?.screenshotPixelDensity,scale:r?.screenshotScale})}}function kt(e){let{cropOn:t,captureSnapshot:n,cropRun:r}=e;if(t!==void 0&&n!==void 0&&r!==void 0)return{cropOn:t,captureSnapshot:n,run:r,logPath:e.logPath}}async function At(e){let{session:t,cropOn:n,captureSnapshot:r}=e;return n!==void 0||r===void 0?{}:{overlayRefs:await jt({session:t,logPath:e.logPath,screenshotPath:e.screenshotPath,dispatchContext:e.dispatchContext,captureSnapshot:r})}}async function jt(e){let{session:t,dispatchContext:n}=e,r={snapshotInteractiveOnly:!0},i=await b({device:t.device,session:t,flags:r,logPath:e.logPath,snapshotScope:void 0,captureData:async()=>await e.captureSnapshot({options:{appBundleId:t.appBundleId,interactiveOnly:!0,surface:t.surface},execution:$(n)})}),a=T(i,r);return S(t,a),await V({screenshotPath:e.screenshotPath,snapshot:a})}function Mt(e){let t=e.positionals??[],n=e.flags??{},r=t=>t===void 0?void 0:re.expandHome(t,e.meta?.cwd),i=r(t[0]),a=r(n.out);return{outPath:i??a,recorded:{positionals:i?[i,...t.slice(1)]:t,flags:a?{...n,out:a}:n}}}function Nt(e){let{session:t,dispatchContext:n,captureScreenshot:r,crop:o}=e;return{platform:s(t.device),captureScreenshot:async(e,s,l)=>{let u=i({...n,...a(l)});if(await r({outPath:s,options:{appBundleId:n.appBundleId,pixelDensity:u.pixelDensity,fullscreen:u.fullscreen,normalizeStatusBar:u.normalizeStatusBar,stabilize:u.stabilize,surface:l?.surface,skipIosSimulatorBootCheck:n.skipIosSimulatorBootCheck??(c(t.device)&&t.device.kind===`simulator`),captureBackend:n.screenshotCaptureBackend},execution:$(n)}),o){let e=await Ze({device:t.device,session:t,surface:t.surface,cropOn:o.cropOn,screenshotPath:s,logPath:o.logPath,dispatchContext:n,captureSnapshot:o.captureSnapshot});o.run.warnings.push(...Xe(e))}}}}function Pt(){return{resolveInput:async()=>{throw new e(`UNSUPPORTED_OPERATION`,`screenshot does not resolve input artifacts`)},reserveOutput:async e=>{let t,n;return e?.kind===`path`?n=e.path:(t=await A.mkdtemp(k.join(j.tmpdir(),`agent-device-screenshot-`)),n=k.join(t,`screenshot.png`)),await A.mkdir(k.dirname(n),{recursive:!0}),{path:n,visibility:`client-visible`,publish:async()=>void 0,...t?{cleanup:async()=>{await A.rm(t,{recursive:!0,force:!0})}}:{}}},createTempFile:async e=>{let t=await A.mkdtemp(k.join(j.tmpdir(),`${e.prefix}-`));return{path:k.join(t,`file${e.ext}`),visibility:`internal`,cleanup:async()=>{await A.rm(t,{recursive:!0,force:!0})}}}}}export{we as _,V as a,xe as b,P as c,be as d,Ee as f,Me as g,Ne as h,X as i,F as l,Pe as m,Dt as n,De as o,Te as p,$ as r,Ce as s,Q as t,ke as u,Oe as v,Se as y};
|
|
1
|
+
import{D as e,g as t,o as n}from"./sdk-contracts.js";import{f as r,l as i,r as a,u as o}from"./capture.js";import{b as s,d as c,w as l}from"./sdk-device.js";import{Ar as u,Fr as d,Ft as f,Ir as p,Jr as m,Rr as h,Wr as g,d as _,l as v,mn as ee,qr as y,x as te,y as ne}from"./sdk-batch.js";import{t as re}from"./session-store.js";import{c as b,f as x,i as S,m as C,o as w}from"./session-snapshot.js";import{F as ie,h as ae,l as oe,v as se}from"./runtime.js";import{t as T}from"./snapshot-state.js";import{i as ce,o as le,r as ue}from"./png-worker-client.js";import{t as de}from"./png-size.js";import{r as fe,t as pe}from"./screenshot-density.js";import{a as E,c as me,o as D,s as O,t as he}from"./screenshot-overlay-draw.js";import{a as ge,i as _e,n as ve,t as ye}from"./session-runtime-admission.js";import k from"node:path";import{promises as A}from"node:fs";import j from"node:os";const M=v(_),N=Fe(M);function P(e){return I(e)?.route??`generic`}function F(e){return I(e)?.sessionKind}function be(e){return I(e)?.leaseAdmissionExempt===!0}function xe(e){return I(e)?.selectorValidationExempt!==!0}function Se(e){return I(e)?.sessionExecutionLockExempt!==!0}function Ce(e){return I(e)?.replayScopedAction===!0}function we(e){return I(e)?.allowInvalidRecording!==!0}function Te(e){return I(e)?.saveScriptFlagOwner===!0}function Ee(){return M.filter(e=>e.saveScriptFlagOwner===!0).map(e=>e.command).sort()}function De(e){return I(e)?.lockPolicySelectorOverride===!0}function Oe(e){return I(e)?.androidBlockingDialogGuard===!0}function ke(e){if(e.command===`human_control`||e.command===`lease_heartbeat`)return!1;let t=te(e);return t===void 0?F(e.command)!==`observability`&&ne(e.command)!==`observe`:t!==`observes-app`}function Ae(e){return I(e.command)?.preferExplicitDeviceOverExistingSession===!0}function je(e){let t=I(e.command)?.allowSessionlessDefaultDevice;return typeof t==`function`&&t(e)}function Me(e){return I(e.command)?.sessionlessLeaseAdmissionExemption?.(e)}function Ne(e){let t=I(e.command)?.refFrameEffect;return typeof t==`function`?t(e):t}function Pe(e,t){return t.hasExistingSession?Ae(e)&&t.hasExplicitDeviceIdentity?`explicit-device`:`existing-session`:Ie(e)?`skip`:t.hasDeviceSelectionInput?`explicit-device`:je(e)?`sessionless-default-device`:`skip`}function I(e){return N.descriptorsByCommand.get(e)}function Fe(e){let t=new Map;for(let n of e){if(t.has(n.command))throw Error(`Duplicate daemon command descriptor: ${n.command}`);t.set(n.command,n)}return{descriptorsByCommand:t}}function Ie(e){let t=I(e.command);if(t?.route===`lease`)return!0;let n=t?.skipSessionlessProviderDevice;return typeof n==`function`&&n(e)}const L=a.pendingPixelIdentityEvidence,Le=[{target:`ios-simulator`,status:`accepted`},{target:`android-emulator`,status:`accepted`},{target:`android-device`,status:`rejected`,rejectionReason:L},{target:`macos-app-window`,status:`rejected`,rejectionReason:L},{target:`ios-physical`,status:`rejected`,rejectionReason:L},{target:`macos-helper`,status:`rejected`,rejectionReason:L},{target:`web`,status:`rejected`,rejectionReason:L},{target:`linux`,status:`rejected`,rejectionReason:L},{target:`tvos`,status:`rejected`,rejectionReason:L},{target:`harmonyos`,status:`rejected`,rejectionReason:L},{target:`vega`,status:`rejected`,rejectionReason:L}];function Re(e,t){switch(e.platform){case`apple`:return ze(e,t);case`android`:return e.kind===`device`?`android-device`:`android-emulator`;case`harmonyos`:return`harmonyos`;case`vega`:return`vega`;case`linux`:return`linux`;case`web`:return`web`}}function ze(e,t){let n=l(e);switch(n){case`ios`:case`ipados`:return e.kind===`device`?`ios-physical`:`ios-simulator`;case`tvos`:return`tvos`;case`macos`:return Be(t);case`watchos`:case`visionos`:throw R(n)}}function Be(e){return e===`app`||e===`frontmost-app`?`macos-app-window`:`macos-helper`}function R(t,n){return new e(`UNSUPPORTED_OPERATION`,`screenshot --crop-on is not accepted on ${t} targets`,{reason:a.targetNotAccepted,...n?{rejectionReason:n}:{}})}function Ve(t){if(t.overlayRefs||t.fullscreen)throw new e(`INVALID_ARGS`,`--crop-on cannot be combined with --overlay-refs or --fullscreen: both move the captured frame away from the snapshot viewport the crop is measured against`,{reason:a.frameMismatch});try{ee(t.cropOn)}catch{throw new e(`INVALID_ARGS`,`screenshot --crop-on requires a valid selector expression`,{reason:a.selectorInvalid})}let n=Re(t.device,t.surface),r=Le.find(e=>e.target===n);if(!r||r.status===`rejected`)throw R(n,r?.status===`rejected`?r.rejectionReason:void 0)}async function He(t,n){if(!Ue(n))throw new e(`INVALID_ARGS`,`Screenshot crop box must be positive integer pixel offsets`);let r=await ue(await A.readFile(t),n,`screenshot`);r!==null&&await A.writeFile(t,r)}function Ue(e){return Number.isInteger(e.x)&&e.x>=0&&Number.isInteger(e.y)&&e.y>=0&&Number.isInteger(e.width)&&e.width>0&&Number.isInteger(e.height)&&e.height>0}function We(t){switch(t){case`android`:return`device-pixels`;case`xctest`:case`macos-helper`:return`viewport-points`;default:throw new e(`UNSUPPORTED_OPERATION`,`screenshot --crop-on does not accept snapshot backend "${t??`unknown`}"`,{reason:a.targetNotAccepted})}}function z(e,t,n,r,i){if(e===`device-pixels`||t===null)return Je(n);let a=r/t.width,o=i/t.height;return{x:Math.round((n.x-t.x)*a),y:Math.round((n.y-t.y)*o),width:Math.round(n.width*a),height:Math.round(n.height*o)}}function Ge(e,t,n){let r=Math.max(e.x,0),i=Math.max(e.y,0),a=Math.min(e.x+e.width,t),o=Math.min(e.y+e.height,n);return a<=r||o<=i?null:{x:r,y:i,width:a-r,height:o-i}}function B(e){let t=null;for(let n of e)!u(n)||!g(n.rect)||(!t||y(n.rect)>y(t))&&(t=n.rect);return t||Ke(e.filter(e=>g(e.rect)&&!qe(e)))}function Ke(e){let t=1/0,n=1/0,r=-1/0,i=-1/0;for(let a of e)g(a.rect)&&(t=Math.min(t,a.rect.x),n=Math.min(n,a.rect.y),r=Math.max(r,a.rect.x+a.rect.width),i=Math.max(i,a.rect.y+a.rect.height));return!Number.isFinite(t)||!Number.isFinite(n)||r<=t||i<=n?null:{x:t,y:n,width:r-t,height:i-n}}function qe(e){return p(e.type??``)===`image`&&!d(e.label)}function Je(e){return{x:Math.round(e.x),y:Math.round(e.y),width:Math.round(e.width),height:Math.round(e.height)}}const Ye=`${a.partialIntersection}: the selector frame extends past the captured image; the crop was clipped to the image frame`;function Xe(e){return e?.partialIntersection?[Ye]:[]}async function Ze(t){let{device:n,session:r,surface:i,cropOn:o,screenshotPath:s,logPath:c,dispatchContext:l}=t,u={snapshotInteractiveOnly:!1},d=await b({device:n,session:r,flags:u,logPath:c,snapshotScope:void 0,captureData:async()=>await t.captureSnapshot({options:{appBundleId:l.appBundleId,interactiveOnly:!1,includeRects:!0,surface:i},execution:C(l)})}),f=T(d,u);if(f.snapshotQuality?.state===`sparse`)throw new e(`COMMAND_FAILED`,`the snapshot taken for --crop-on was sparse and cannot be read as the screen`,{reason:a.captureUnreadable});let p=await Qe(f.nodes,o,f.truncated,n),m=await de(s),h=z(We(f.backend),B(f.nodes),p.rect,m.width,m.height),g=Ge(h,m.width,m.height);if(g===null)throw new e(`COMMAND_FAILED`,`the frame resolved by --crop-on occupies no pixel of the capture`,{reason:a.emptyIntersection});let _=g.x!==h.x||g.y!==h.y||g.width<h.width||g.height<h.height;return await He(s,g),{partialIntersection:_}}async function Qe(t,n,r,i){let o=await oe(ae.cropTarget,t,n,{platform:s(i)});if(o.kind===`ambiguous`)throw new e(`COMMAND_FAILED`,`--crop-on matched ${o.matchedNodes.length} nodes and must resolve to one`,{reason:a.targetAmbiguous,candidates:o.matchedNodes.map(e=>e.label??e.ref),matches:o.matchedNodes.length});if(o.kind===`none`)throw r?new e(`COMMAND_FAILED`,`the snapshot taken for --crop-on was truncated, so a missing match is not proven`,{reason:a.captureIncomplete}):new e(`COMMAND_FAILED`,`--crop-on matched no node: ${n}`,{reason:a.targetNotFound,hint:`find ${n} list`});return o.node}const $e=[`scroll`,`list`,`recyclerview`,`edittext`,`textfield`];function et(e,t,n){if(e.backend!==`android`||!n.hittable||!D(n.rect)||u(n))return!1;let r=p(n.type??``);return!($e.some(e=>r.includes(e))||t&&O(n.rect)>O(t)*.25)}function tt(e,t,n,r){return!e.rect||e.hittable!==!0||n(e)||r(e)?null:nt(e,t,r)}function nt(e,t,n){let r=e.rect,i=rt(e,t,n);if(!i)return null;let a=i.y-r.y,o=r.y+r.height-(i.y+i.height);if(a<0||o<0||Math.abs(o-a)<16)return null;let s=Math.min(a,o),c=Math.round(i.y-s),l=Math.round(i.height+s*2);return l<=0||l>=r.height?null:{x:r.x,y:c,width:r.width,height:l}}function rt(e,t,n){let r=e.rect,i=new Map(t.map(e=>[e.index,e])),a=t.filter(t=>t.ref!==e.ref&&at(t,e,i)&&it(t,n)&&D(t.rect)&&m(r,t.rect)).map(e=>e.rect);return a.length<2?null:me(a)}function it(e,t){let n=p(e.type??``);return n.includes(`text`)||n.includes(`image`)&&t(e)}function at(e,t,n){let r=e;for(;r.parentIndex!==void 0;){let e=n.get(r.parentIndex);if(!e)return!1;if(e.ref===t.ref)return!0;r=e}return!1}const ot=[`button`,`link`,`menu`,`tab`,`textfield`,`searchfield`,`securetextfield`,`checkbox`,`radio`,`switch`,`cell`];async function V(e){let t=await A.readFile(e.screenshotPath),n=await ce(t,`screenshot`),r=st(e.snapshot,n.width,n.height,{maxRefs:e.maxRefs});for(let e of r)he(n,e);return await A.writeFile(e.screenshotPath,await le(n)),r}function st(e,n,r,i={}){let a=B(e.nodes),o=new Map;for(let t of e.nodes){if(!ut(e,a,t))continue;let i=dt(e.nodes,t);if(!i?.rect||!D(i.rect))continue;let s=ft(t,i,e.nodes),c=pt(t,i,s),l=H(e,a,lt(e,i,e.nodes),n,r);if(!D(l))continue;let u=o.get(i.ref);(!u||c>u.score)&&o.set(i.ref,{ref:i.ref,label:s,rect:i.rect,overlayRect:l,score:c})}return ct(e,a,o,n,r),mt([...o.values()]).sort(Y).slice(0,i.maxRefs??24).sort(J).map(e=>({ref:e.ref,label:e.label,rect:e.rect,overlayRect:e.overlayRect,center:t(e.overlayRect)}))}function ct(e,t,n,r,i){let a=ie(e.nodes).primaryAction;if(!a?.ref||!a.rect||!D(a.rect))return;let o=H(e,t,a.rect,r,i);if(!D(o))return;let s={ref:a.ref,label:a.label,rect:a.rect,overlayRect:o,score:100},c=n.get(a.ref);n.set(a.ref,c?{...c,score:Math.max(c.score,s.score)}:s)}function lt(e,t,n){return e.backend===`android`?tt(t,n,U,e=>!!q(e))??t.rect:t.rect}function ut(e,t,n){let r=[n.label,n.value].some(G)||K(n.identifier);return et(e,t,n)?!0:U(n)?r:r&&ht(n)}function dt(e,t){return[W(t)?t:null,h(e,t,W),t.hittable?t:null,h(e,t,e=>e.hittable===!0)].find(gt)??null}function ft(e,t,n){let r=q(e);return e.ref!==t.ref&&r?r:_t(t,n)||q(t)}function pt(e,t,n){let r=0;return e.ref===t.ref&&(r+=4),t.hittable&&(r+=3),U(t)&&(r+=3),U(e)&&(r+=2),n&&(r+=2),K(t.identifier)&&(r+=1),d(t.value)&&(r+=1),r}function mt(e){let t=[];for(let n of e.sort((e,t)=>O(e.overlayRect)-O(t.overlayRect))){let e=t.findIndex(e=>e.label!==void 0&&e.label===n.label&&(m(e.overlayRect,n.overlayRect)||m(n.overlayRect,e.overlayRect)));if(e===-1){t.push(n);continue}O(n.overlayRect)<O(t[e].overlayRect)&&(t[e]=n)}return t}function H(e,t,n,r,i){return Ct(z(e.backend===`android`?`device-pixels`:`viewport-points`,t,n,r,i),r,i)}function U(e){let t=[e.type,e.role,e.subrole].map(e=>p(e??``)).join(` `);return ot.some(e=>t.includes(e))}function W(e){return U(e)&&!u(e)}function ht(e){let t=p(e.type??``);return t.includes(`statictext`)||t.includes(`image`)||t.includes(`text`)||t.includes(`other`)}function gt(e){return!!(e?.rect&&D(e.rect)&&!u(e))}function G(e){return d(e)?!bt(e):!1}function K(e){return typeof e!=`string`||!G(e)?!1:!xt(e)}function q(e){let t=[e.label,e.value].find(G);if(t)return t.trim();if(K(e.identifier))return e.identifier.trim()}function _t(e,t){let n=null;for(let r of t){if(r.ref===e.ref||!vt(r,e,t))continue;let i=q(r);if(!i)continue;let a=yt(r);(!n||a>n.score)&&(n={label:i,score:a})}return n?.label}function vt(e,t,n){let r=e;for(;r.parentIndex!==void 0;){let e=n[r.parentIndex];if(!e)return!1;if(e.ref===t.ref)return!0;r=e}return!1}function yt(e){let t=0;return p(e.type??``).includes(`text`)&&(t+=2),G(e.label)&&(t+=2),G(e.value)&&(t+=1),t}function bt(e){let t=e?.trim().toLowerCase();return t===`toolbar`||t===`window`||t===`application`||t?.startsWith(`vertical scroll bar`)===!0}function xt(e){return/^[a-z0-9_.]+:id\/[a-z0-9_.-]+$/i.test(e.trim())}function St(e,t){return Number.parseInt(e.replace(/^\D+/,``),10)-Number.parseInt(t.replace(/^\D+/,``),10)}function Ct(e,t,n){let r=E(e.x,0,Math.max(0,t-1)),i=E(e.y,0,Math.max(0,n-1)),a=Math.max(1,t-r),o=Math.max(1,n-i);return{x:r,y:i,width:E(e.width,1,a),height:E(e.height,1,o)}}function J(e,t){let n=e.overlayRect.y-t.overlayRect.y;if(n!==0)return n;let r=e.overlayRect.x-t.overlayRect.x;return r===0?St(e.ref,t.ref):r}function Y(e,t){return t.score===e.score?J(e,t):t.score-e.score}async function X(e){let t=f({overlayRefs:e.overlayRefs,cropOn:e.cropOn!==void 0}),n=await ye({device:e.device,plan:t,inspectFacts:e.inspectFacts});return n.admitted?{ok:!0,runtime:await wt(e.bindDevice,n)}:{ok:!1,response:Et(t.kind,n.operation,n.fact)}}async function wt(e,t){let n=ve(e),{device:r,plan:i}=ge(t);switch(i.kind){case`capture`:{let e=await n(r,i.use);return Object.freeze({captureScreenshot:Z(e)})}case`capture-with-overlay-refs`:case`capture-with-crop-on`:{let e=await n(r,i.use);return Object.freeze({captureScreenshot:Z(e),captureSnapshot:Tt(e)})}}}function Z(e){return async t=>await e.operations.captureScreenshot(t)}function Tt(e){return async t=>await e.operations.captureSnapshot(t)}function Et(e,t,r){return t===`captureScreenshot`?_e(`screenshot`,r):e===`capture-with-crop-on`?n(`UNSUPPORTED_OPERATION`,`--crop-on crops the capture to a selector frame using a snapshot taken on the same screen, which this target cannot capture.`,{reason:r.available?void 0:r.reason},{hint:(r.available?void 0:r.hint)??`Re-run screenshot without --crop-on.`}):n(`UNSUPPORTED_OPERATION`,`--overlay-refs annotates a capture with the refs of a snapshot taken on the same screen, which this target cannot capture.`,{reason:r.available?void 0:r.reason},{hint:(r.available?void 0:r.hint)??`Re-run screenshot without --overlay-refs.`})}async function Dt(t){let{req:n,session:r}=t,a=i(`screenshot`,n.flags);if(a)throw new e(`INVALID_ARGS`,a);pe(r.device,n.flags?.screenshotPixelDensity);let o=Mt(n),s=typeof n.flags?.screenshotCropOn==`string`&&n.flags.screenshotCropOn.length>0?n.flags.screenshotCropOn:void 0;s!==void 0&&Ve({device:r.device,surface:r.surface,cropOn:s,overlayRefs:n.flags?.overlayRefs===!0,fullscreen:n.flags?.screenshotFullscreen===!0});let c=await X({device:r.device,overlayRefs:n.flags?.overlayRefs===!0,cropOn:s,inspectFacts:t.inspectFacts,bindDevice:t.bindDevice});if(!c.ok)return c;let l=c.runtime,u={warnings:[]};return{ok:!0,recorded:o.recorded,execute:async e=>await Ot({session:e.session,sessionName:e.sessionName,logPath:e.logPath,dispatchContext:e.dispatchContext,flags:e.request.flags,outPath:o.outPath,runtime:l,cropOn:s,cropRun:u})}}async function Q(e){let{session:t,sessionName:n,outPath:i,dispatchContext:a}=e;return await x({backend:Nt(e),artifacts:Pt(),sessions:w({sessionName:n,getSession:()=>t,recordOptions:{includeSnapshot:!1},setRecord:()=>{}}),policy:se()}).capture.screenshot({session:n,requestId:a.requestId,appBundleId:t.appBundleId,...r(a),surface:t.surface,...i?{out:{kind:`path`,path:i}}:{}})}function $(e){return C(e)}async function Ot(e){let{session:t,runtime:n,flags:r}=e,i=kt({cropOn:e.cropOn,captureSnapshot:n.captureSnapshot,cropRun:e.cropRun,logPath:e.logPath}),a=await Q({session:t,sessionName:e.sessionName,outPath:e.outPath,dispatchContext:e.dispatchContext,captureScreenshot:n.captureScreenshot,...i?{crop:i}:{}}),o=[...a.warnings??[],...i?.run?.warnings??[]];return{...a,...o.length>0?{warnings:o}:{},...await At({session:t,cropOn:e.cropOn,captureSnapshot:n.captureSnapshot,screenshotPath:a.path,logPath:e.logPath,dispatchContext:e.dispatchContext}),...await fe({device:t.device,path:a.path,requestedPixelDensity:r?.screenshotPixelDensity,scale:r?.screenshotScale})}}function kt(e){let{cropOn:t,captureSnapshot:n,cropRun:r}=e;if(t!==void 0&&n!==void 0&&r!==void 0)return{cropOn:t,captureSnapshot:n,run:r,logPath:e.logPath}}async function At(e){let{session:t,cropOn:n,captureSnapshot:r}=e;return n!==void 0||r===void 0?{}:{overlayRefs:await jt({session:t,logPath:e.logPath,screenshotPath:e.screenshotPath,dispatchContext:e.dispatchContext,captureSnapshot:r})}}async function jt(e){let{session:t,dispatchContext:n}=e,r={snapshotInteractiveOnly:!0},i=await b({device:t.device,session:t,flags:r,logPath:e.logPath,snapshotScope:void 0,captureData:async()=>await e.captureSnapshot({options:{appBundleId:t.appBundleId,interactiveOnly:!0,surface:t.surface},execution:$(n)})}),a=T(i,r);return S(t,a),await V({screenshotPath:e.screenshotPath,snapshot:a})}function Mt(e){let t=e.positionals??[],n=e.flags??{},r=t=>t===void 0?void 0:re.expandHome(t,e.meta?.cwd),i=r(t[0]),a=r(n.out);return{outPath:i??a,recorded:{positionals:i?[i,...t.slice(1)]:t,flags:a?{...n,out:a}:n}}}function Nt(e){let{session:t,dispatchContext:n,captureScreenshot:i,crop:a}=e;return{platform:s(t.device),captureScreenshot:async(e,s,l)=>{let u=r({...n,...o(l)});if(await i({outPath:s,options:{appBundleId:n.appBundleId,pixelDensity:u.pixelDensity,fullscreen:u.fullscreen,normalizeStatusBar:u.normalizeStatusBar,stabilize:u.stabilize,surface:l?.surface,skipIosSimulatorBootCheck:n.skipIosSimulatorBootCheck??(c(t.device)&&t.device.kind===`simulator`),captureBackend:n.screenshotCaptureBackend},execution:$(n)}),a){let e=await Ze({device:t.device,session:t,surface:t.surface,cropOn:a.cropOn,screenshotPath:s,logPath:a.logPath,dispatchContext:n,captureSnapshot:a.captureSnapshot});a.run.warnings.push(...Xe(e))}}}}function Pt(){return{resolveInput:async()=>{throw new e(`UNSUPPORTED_OPERATION`,`screenshot does not resolve input artifacts`)},reserveOutput:async e=>{let t,n;return e?.kind===`path`?n=e.path:(t=await A.mkdtemp(k.join(j.tmpdir(),`agent-device-screenshot-`)),n=k.join(t,`screenshot.png`)),await A.mkdir(k.dirname(n),{recursive:!0}),{path:n,visibility:`client-visible`,publish:async()=>void 0,...t?{cleanup:async()=>{await A.rm(t,{recursive:!0,force:!0})}}:{}}},createTempFile:async e=>{let t=await A.mkdtemp(k.join(j.tmpdir(),`${e.prefix}-`));return{path:k.join(t,`file${e.ext}`),visibility:`internal`,cleanup:async()=>{await A.rm(t,{recursive:!0,force:!0})}}}}}export{we as _,V as a,xe as b,P as c,be as d,Ee as f,Me as g,Ne as h,X as i,F as l,Pe as m,Dt as n,De as o,Te as p,$ as r,Ce as s,Q as t,ke as u,Oe as v,Se as y};
|
package/dist/src/screenshot3.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{D as e,s as t}from"./sdk-contracts.js";import{
|
|
1
|
+
import{D as e,s as t}from"./sdk-contracts.js";import{u as n}from"./registry.js";import{n as r}from"./path-resolution.js";import"./file.js";import{n as i}from"./screenshot-result.js";import{t as a}from"./shared.js";import{t as o}from"./cli-runner.js";import{n as s,t as c}from"./color.js";import l from"node:path";function u(e){let t=e.baselineInitialized===!0,r=e.summary??{},i=v(r.additions),a=v(r.removals),o=v(r.unchanged),l=s(),u=n(e),d=u.length>0?`${u.join(`
|
|
2
2
|
`)}\n`:``;if(t)return`${d}Baseline initialized (${o} lines).\n`;let f=y(Array.isArray(e.lines)?e.lines:[],1).map(e=>{let t=typeof e.text==`string`?e.text:``;if(e.kind===`added`){let e=t.startsWith(` `)?`+${t}`:`+ ${t}`;return l?c(e,`green`):e}if(e.kind===`removed`){let e=t.startsWith(` `)?`-${t}`:`- ${t}`;return l?c(e,`red`):e}return l?c(t,`dim`):t}),p=f.length>0?`${f.join(`
|
|
3
3
|
`)}\n`:``;return l?`${d}${p}${[`${c(String(i),`green`)} additions`,`${c(String(a),`red`)} removals`,`${c(String(o),`dim`)} unchanged`].join(`, `)}\n`:`${d}${p}${i} additions, ${a} removals, ${o} unchanged\n`}function d(e){let t=s(),n=e.match===!0,r=e.dimensionMismatch,i=[];return i.push(...f(e,t)),i.push(...p(e,n,t)),!n&&!r&&(i.push(...m(e,t)),i.push(...h(e,t))),`${i.join(`
|
|
4
4
|
`)}\n`}function f(e,t){if(e.match===!0)return[`${t?c(`✓`,`green`):`✓`} Screenshots match.`];let n=e.dimensionMismatch,r=t?c(`✗`,`red`):`✗`;if(n){let e=n.expected,t=n.actual;return[`${r} Screenshots have different dimensions: expected ${e?.width}x${e?.height}, got ${t?.width}x${t?.height}`]}let i=v(e.differentPixels),a=v(e.mismatchPercentage),o=`${a===0&&i>0?`<0.01`:String(a)}% pixels differ`;return[`${r} ${t?c(o,`red`):o}`]}function p(e,t,n){if(t)return[];let r=[];if(e.diffPath){let t=_(e.diffPath),i=n?c(`Diff image:`,`dim`):`Diff image:`,a=n?c(t,`green`):t;r.push(` ${i} ${a}`)}if(e.currentOverlayPath){let t=_(e.currentOverlayPath),i=n?c(`Current overlay:`,`dim`):`Current overlay:`,a=n?c(t,`green`):t,o=v(e.currentOverlayRefCount),s=o>0?` (${o} refs)`:``;r.push(` ${i} ${a}${s}`)}return r}function m(e,t){let n=v(e.differentPixels),r=v(e.totalPixels);return[` ${t?c(String(n),`red`):String(n)} different / ${r} total pixels`]}function h(e,t){let n=Array.isArray(e.regions)?e.regions:[];if(n.length===0)return[];let r=[` ${b(`Changed regions:`,t)}`];for(let e of n.slice(0,5))r.push(...g(e));return r}function g(e){let t=e.shareOfDiffPercentage===0&&e.differentPixels>0?`<0.01`:String(e.shareOfDiffPercentage),n=e.rect,r=[` ${e.index}. x=${n.x} y=${n.y} ${n.width}x${n.height}, ${t}% of diff`],i=e.currentOverlayMatches?.[0];if(i){let e=i.label?` "${i.label}"`:``;r.push(` overlaps @${i.ref}${e}, ${i.regionCoveragePercentage}% of region`)}return r}function _(e){let t=process.cwd(),n=l.relative(t,e);return n===``||!n.startsWith(`..`)&&!l.isAbsolute(n)?n===``?`.`:`.${l.sep}${n}`:e}function v(e){return typeof e==`number`&&Number.isFinite(e)?e:0}function y(e,t){if(e.length===0)return e;let n=e.map((e,t)=>({index:t,kind:e.kind})).filter(e=>e.kind===`added`||e.kind===`removed`).map(e=>e.index);if(n.length===0)return e;let r=Array(e.length).fill(!1);for(let i of n){let n=Math.max(0,i-t),a=Math.min(e.length-1,i+t);for(let e=n;e<=a;e+=1)r[e]=!0}return e.filter((e,t)=>r[t])}function b(e,t){return t?c(e,`dim`):e}const x=async({positionals:e,flags:n,client:r})=>{let s=await o({client:r,command:`screenshot`,positionals:e,flags:n});if(t(n.responseLevel))return await a(n,s,()=>JSON.stringify(s,null,2)),!0;let c=i(s);return await a(n,c,()=>{let e=s.overlayRefs?`Annotated ${s.overlayRefs.length} refs onto ${s.path}`:w(s),t=s.warnings??[];return t.length>0?[e,...t].join(`
|
package/dist/src/script.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{D as e,T as t}from"./sdk-contracts.js";import{o as n,s as r,t as i}from"./capture.js";import{p as a}from"./sdk-batch-runner.js";import{r as o}from"./sdk-device.js";import{er as s,tr as c}from"./sdk-batch.js";import{i as l}from"./recording-export-quality.js";import{n as u,s as d}from"./scroll-gesture.js";import{t as f}from"./gesture-plan-types.js";const p=[`pan`,`fling`,`swipe`,`pinch`,`rotate`,`transform`,`drag`];function m(t){let n=g(t),r=x(n,`kind`,p);if(r===`pan`)return{kind:r,origin:_(n,`origin`),delta:_(n,`delta`),pointerCount:a(n,`pointerCount`,{min:1,max:2}),durationMs:h(n)};if(r===`drag`)return ee(n);if(n.pointerCount!==void 0)throw new e(`INVALID_ARGS`,`pointerCount is supported only for gesture pan`);if(r===`fling`){if(n.durationMs!==void 0)throw new e(`INVALID_ARGS`,`gesture fling does not accept durationMs; use gesture pan for timed movement`);return{kind:r,direction:x(n,`direction`,u),origin:_(n,`origin`),distance:a(n,`distance`,{min:0})}}if(r===`swipe`){if(n.durationMs!==void 0)throw new e(`INVALID_ARGS`,`gesture swipe does not accept durationMs; use gesture pan for timed movement`);return{kind:r,preset:x(n,`preset`,d)}}if(r===`pinch`)return{kind:r,scale:y(n,`scale`),origin:v(n,`origin`)};if(r===`rotate`){if(n.velocity!==void 0)throw new e(`INVALID_ARGS`,`gesture rotate does not accept velocity; rotation pacing derives from degrees`);return{kind:r,degrees:y(n,`degrees`),origin:v(n,`origin`)}}return{kind:r,origin:_(n,`origin`),delta:_(n,`delta`),scale:y(n,`scale`),degrees:y(n,`degrees`),durationMs:h(n)}}function ee(t){let n=a(t,`sourceHoldMs`,{min:1,max:1e4}),r=a(t,`moveMs`,{min:16,max:1e4}),i=a(t,`destinationHoldMs`,{min:0,max:1e4});if((n??800)+(r??500)+(i??0)>1e4)throw new e(`INVALID_ARGS`,`gesture drag total duration must be at most ${f}`);return{kind:`drag`,source:b(t,`source`),destination:b(t,`destination`),sourceHoldMs:n,moveMs:r,destinationHoldMs:i}}function h(t){let n=a(t,`durationMs`);if(n!==void 0){if(n<16||n>1e4)throw new e(`INVALID_ARGS`,`Expected durationMs to be an integer between 16 and ${f}.`);return n}}function g(t){if(!t||typeof t!=`object`||Array.isArray(t))throw new e(`INVALID_ARGS`,`gesture requires structured object input`);return t}function _(e,t){let n=g(e[t]);return{x:y(n,`x`),y:y(n,`y`)}}function v(e,t){return e[t]===void 0?void 0:_(e,t)}function y(t,n){let r=t[n];if(typeof r!=`number`||!Number.isFinite(r))throw new e(`INVALID_ARGS`,`Expected ${n} to be a finite number.`);return r}function b(t,n){let r=t[n];if(typeof r!=`string`||r.trim().length===0)throw new e(`INVALID_ARGS`,`Expected ${n} to be a non-empty string.`);return r.trim()}function x(t,n,r){let i=t[n];if(typeof i!=`string`||!r.includes(i))throw new e(`INVALID_ARGS`,`Expected ${n} to be one of: ${r.join(`, `)}.`);return i}const S={swipe:{max:4,usage:`swipe accepts 4 arguments: x1 y1 x2 y2`,retired:{positional:`durationMs`,migrate:te}},"gesture pan":{max:5,usage:`gesture pan accepts at most 5 arguments: x y dx dy [durationMs]`},"gesture fling":{max:4,usage:`gesture fling accepts at most 4 arguments: direction x y [distance]`,retired:{positional:`durationMs`,migrate:(e,t)=>`use "${t}", or gesture pan for timed movement.`}},"gesture swipe":{max:1,usage:`gesture swipe accepts 1 argument: preset`,retired:{positional:`durationMs`,migrate:(e,t)=>`use "${t}", or gesture pan for timed movement.`}},"gesture pinch":{max:3,usage:`gesture pinch accepts at most 3 arguments: scale [x] [y]`},"gesture rotate":{max:3,usage:`gesture rotate accepts at most 3 arguments: degrees [x] [y]`,retired:{positional:`velocity`,migrate:(e,t)=>`use "${t}"; rotation pacing derives from degrees.`}},"gesture transform":{max:7,usage:`gesture transform accepts at most 7 arguments: x y dx dy scale degrees [durationMs]`},"gesture drag":{max:5,usage:`gesture drag accepts at most 5 arguments: source destination [sourceHoldMs] [moveMs] [destinationHoldMs]`}};function te(e,t){let[n,r,i,a,o]=e,s=C(n,i),c=C(r,a);return s===void 0||c===void 0?`use "gesture pan x1 y1 dx dy durationMs" for the same timed drag, or "${t}" for a default-duration swipe.`:`use "gesture pan ${n} ${r} ${s} ${c} ${o}" for the same timed drag, or "${t}" for a default-duration swipe.`}function C(e,t){let n=Number(t)-Number(e);return Number.isFinite(n)?n:void 0}function w(e,t){let n=S[e];if(t.length<=n.max)return;let r=n.retired;if(!r||t.length!==n.max+1||!T(t[n.max]))return{usage:n.usage};let i=`${e} ${t.slice(0,n.max).join(` `)}`;return{usage:n.usage,migration:`The trailing ${r.positional} positional was removed: ${r.migrate(t,i)}`}}function T(e){return e===void 0||e.trim().length===0?!1:e.startsWith("${")||Number.isFinite(Number(e))}function ne(t){if(!(!t||typeof t!=`object`||Array.isArray(t))&&t.durationMs!==void 0)throw new e(`INVALID_ARGS`,`swipe does not accept durationMs; use gesture pan for timed movement`)}function E(e,t){let n=t?`${e.usage} (${t})`:e.usage;return e.migration?`${n}. ${e.migration}`:`${n}.`}function D(t,n){let r=w(t,n);if(r)throw new e(`INVALID_ARGS`,E(r))}function re(e,t,n){let r=ie(e,t);return r?E(r,n):void 0}function ie(e,t){if(e===`swipe`)return w(`swipe`,t);if(e!==`gesture`)return;let n=`gesture ${t[0]}`;if(Object.hasOwn(S,n))return w(n,t.slice(1))}function O(e){return{origin:{x:Number(e[0]),y:Number(e[1])},delta:{x:Number(e[2]),y:Number(e[3])}}}function k(e,t){let n=e[0],r=e.slice(1);switch(n){case`pan`:{D(`gesture pan`,r);let{origin:e,delta:i}=O(r);return m({kind:n,origin:e,delta:i,pointerCount:t,durationMs:A(r[4])})}case`fling`:return D(`gesture fling`,r),m({kind:n,direction:r[0],origin:{x:Number(r[1]),y:Number(r[2])},distance:A(r[3])});case`swipe`:return D(`gesture swipe`,r),m({kind:n,preset:r[0]});case`pinch`:return D(`gesture pinch`,r),m({kind:n,scale:Number(r[0]),origin:j(r[1],r[2])});case`rotate`:return D(`gesture rotate`,r),m({kind:n,degrees:Number(r[0]),origin:j(r[1],r[2])});case`transform`:{D(`gesture transform`,r);let{origin:e,delta:t}=O(r);return m({kind:n,origin:e,delta:t,scale:Number(r[4]),degrees:Number(r[5]),durationMs:A(r[6])})}case`drag`:return D(`gesture drag`,r),m({kind:n,source:r[0],destination:r[1],sourceHoldMs:A(r[2]),moveMs:A(r[3]),destinationHoldMs:A(r[4])});default:return m({kind:n})}}function ae(e){if(e[0]!==`drag`)return;let t=k(e);return t.kind===`drag`?t:void 0}function oe(e){switch(e.kind){case`pan`:return M([e.kind,e.origin.x,e.origin.y,e.delta.x,e.delta.y,e.durationMs]);case`fling`:return M([e.kind,e.direction,e.origin.x,e.origin.y,e.distance]);case`swipe`:return[e.kind,e.preset];case`pinch`:return M([e.kind,e.scale,e.origin?.x,e.origin?.y]);case`rotate`:return e.origin?M([e.kind,e.degrees,e.origin.x,e.origin.y]):[e.kind,String(e.degrees)];case`transform`:return M([e.kind,e.origin.x,e.origin.y,e.delta.x,e.delta.y,e.scale,e.degrees,e.durationMs]);case`drag`:return[e.kind,e.source,e.destination,String(e.sourceHoldMs??800),String(e.moveMs??500),String(e.destinationHoldMs??0)]}}function se(e,t={}){return D(`swipe`,e),{from:{x:Number(e[0]),y:Number(e[1])},to:{x:Number(e[2]),y:Number(e[3])},...t.count===void 0?{}:{count:t.count},...t.pauseMs===void 0?{}:{pauseMs:t.pauseMs},...t.pattern===void 0?{}:{pattern:t.pattern}}}function ce(t){switch(t.kind){case`pan`:return{gesture:{intent:`pan`,origin:t.origin,delta:t.delta,pointerCount:t.pointerCount,durationMs:t.durationMs}};case`fling`:return{gesture:{intent:`fling`,direction:t.direction,origin:t.origin,distance:t.distance}};case`swipe`:return{gesture:{intent:`fling`,preset:t.preset}};case`pinch`:return{gesture:{intent:`pinch`,origin:t.origin,scale:t.scale}};case`rotate`:return{gesture:{intent:`rotate`,origin:t.origin,degrees:t.degrees}};case`transform`:return{gesture:{intent:`transform`,origin:t.origin,delta:t.delta,scale:t.scale,degrees:t.degrees,durationMs:t.durationMs}};case`drag`:throw new e(`INVALID_ARGS`,`gesture drag targets must be resolved before coordinate normalization`)}}function le(e){return e.kind===`drag`?{intent:`drag`,source:e.source,destination:e.destination,sourceHoldMs:e.sourceHoldMs,moveMs:e.moveMs,destinationHoldMs:e.destinationHoldMs}:ce(e).gesture}function ue(e){return{gesture:{intent:`fling`,from:e.from,to:e.to}}}function A(e){return e===void 0?void 0:Number(e)}function j(t,n){if(t===void 0!=(n===void 0))throw new e(`INVALID_ARGS`,`gesture origin requires both x and y coordinates`);return t===void 0?void 0:{x:Number(t),y:Number(n)}}function M(e){return e.filter(e=>e!==void 0).map(String)}const de={ios:!0,android:!0,harmonyos:!0};function N(e){return typeof e==`string`&&Object.hasOwn(de,e)}function P(e){return e.startsWith(`@`)?t(e)?.base??e:e}const F=/^-?\d+(\.\d+)?$/,fe=/^[^\s"\\]+$/,pe=new Map([[`--count`,`count`],[`--interval-ms`,`intervalMs`],[`--hold-ms`,`holdMs`],[`--jitter-px`,`jitterPx`]]),me=new Map([[`--count`,`count`],[`--pause-ms`,`pauseMs`]]),he=new Map([[`--pointer-count`,`pointerCount`]]),ge=new Map([[`--delay-ms`,`delayMs`]]);function I(e){return e===`click`||e===`press`}function L(e){return I(e)||e===`longpress`||e===`hover`}function R(e){return e===`type`||e===`fill`}function z(e){return H(e,_e)}function B(e){return JSON.stringify(e)}function V(e){return H(e,U)}function H(e,t){return t(e)?e:B(e)}function _e(e){return U(e)&&e.startsWith(`@`)||F.test(e)}function U(e){return fe.test(e)}const ve=new Set([`fill`,`type`]);function ye(e){if(!ve.has(e.command)){let t=(e.positionals??[]).map(e=>z(e));return[e.command,...t].join(` `)}let t=be(e).map(e=>z(e)).join(` `);return[e.command,t,`<text>`].filter(e=>e.length>0).join(` `)}function be(e){if(e.command===`type`)return[];let t=e.positionals??[],n=t[0];return n===void 0?[]:n.startsWith(`@`)?[n]:t.length>=3&&F.test(n)&&F.test(t[1]??``)?[n,t[1]]:[n]}function W(e,t){let n=t.flags??{};if(I(t.command)){typeof n.count==`number`&&e.push(`--count`,String(n.count)),typeof n.intervalMs==`number`&&e.push(`--interval-ms`,String(n.intervalMs)),typeof n.holdMs==`number`&&e.push(`--hold-ms`,String(n.holdMs)),typeof n.jitterPx==`number`&&e.push(`--jitter-px`,String(n.jitterPx)),n.doubleTap===!0&&e.push(`--double-tap`);let t=n.clickButton;t&&t!==`primary`&&e.push(`--button`,t);return}if(t.command===`swipe`){typeof n.count==`number`&&e.push(`--count`,String(n.count)),typeof n.pauseMs==`number`&&e.push(`--pause-ms`,String(n.pauseMs)),(n.pattern===`one-way`||n.pattern===`ping-pong`)&&e.push(`--pattern`,n.pattern);return}if(t.command===`gesture`){typeof n.pointerCount==`number`&&e.push(`--pointer-count`,String(n.pointerCount));return}R(t.command)&&typeof n.delayMs==`number`&&e.push(`--delay-ms`,String(n.delayMs))}function G(e,t){t&&(N(t.platform)&&e.push(`--platform`,t.platform),typeof t.metroHost==`string`&&t.metroHost.length>0&&e.push(`--metro-host`,V(t.metroHost)),typeof t.metroPort==`number`&&e.push(`--metro-port`,String(t.metroPort)),typeof t.bundleUrl==`string`&&t.bundleUrl.length>0&&e.push(`--bundle-url`,V(t.bundleUrl)),typeof t.launchUrl==`string`&&t.launchUrl.length>0&&e.push(`--launch-url`,V(t.launchUrl)))}function xe(e,t){let[n,...r]=t.positionals??[];n&&e.push(V(n));for(let t of r)e.push(z(t));typeof t.flags?.fps==`number`&&e.push(`--fps`,String(t.flags.fps)),(typeof t.flags?.quality==`number`||typeof t.flags?.quality==`string`)&&e.push(`--quality`,String(t.flags.quality)),t.flags?.hideTouches&&e.push(`--hide-touches`)}function Se(e,t){t.flags?.snapshotInteractiveOnly&&e.push(`-i`),typeof t.flags?.snapshotDepth==`number`&&e.push(`-d`,String(t.flags.snapshotDepth)),t.flags?.snapshotScope&&e.push(`-s`,z(t.flags.snapshotScope)),t.flags?.snapshotRaw&&e.push(`--raw`)}function Ce(e,t){for(let n of t.positionals??[])e.push(z(n));let r=t.flags?.screenshotCropOn;typeof r==`string`&&r.length>0&&e.push(`--crop-on`,V(r)),n(e,t.flags)}function we(e,t,n={}){let r=t.positionals??[],i=n.includeAllPositionals?r:r.slice(0,1);for(let t of i)e.push(V(t));G(e,t.flags)}function Te(e,t){for(let n of t.positionals??[])e.push(z(t.command===`wait`?P(n):n));W(e,t)}function K(e,t){let n=[],r={},i=I(e)?pe:e===`swipe`?me:e===`gesture`?he:R(e)?ge:void 0;for(let a=0;a<t.length;a+=1){let o=t[a];if(I(e)&&o===`--double-tap`){r.doubleTap=!0;continue}let s=t[a+1];if(I(e)&&o===`--button`&&s!==void 0){let e=s;(e===`primary`||e===`secondary`||e===`middle`)&&(r.clickButton=e),a+=1;continue}let c=i?.get(o);if(c&&s!==void 0){let e=J(s);if(e!==null){r[c]=e,a+=1;continue}}if(e===`swipe`&&o===`--pattern`&&s!==void 0){let e=s;(e===`one-way`||e===`ping-pong`)&&(r.pattern=e),a+=1;continue}n.push(o)}return{positionals:n,flags:r}}function q(e){let t=[],n={};for(let r=0;r<e.length;r+=1){let i=e[r],a=e[r+1];if(i===`--platform`&&a!==void 0){let e=a;N(e)&&(n.platform=e),r+=1;continue}if(i===`--metro-host`&&a!==void 0){n.metroHost=a,r+=1;continue}if(i===`--metro-port`&&a!==void 0){let e=J(a);e!==null&&(n.metroPort=e),r+=1;continue}if(i===`--bundle-url`&&a!==void 0){n.bundleUrl=a,r+=1;continue}if(i===`--launch-url`&&a!==void 0){n.launchUrl=a,r+=1;continue}t.push(i)}return{positionals:t,flags:n}}function J(e){if(!e)return null;let t=Number(e);return!Number.isFinite(t)||t<0?null:Math.floor(t)}function Ee(e){let t;for(let n of e){if(n.command===`runtime`&&typeof n.flags.platform==`string`){t=n.flags.platform;continue}if(n.command===`open`)return n.runtime?.platform??t}return t}function De(e,t){for(let n of t.positionals??[])e.push(z(n));t.flags?.relaunch&&e.push(`--relaunch`),t.flags?.testIme===!0?e.push(`--test-ime`):t.flags?.testIme===!1&&e.push(`--no-test-ime`),G(e,t.runtime)}function Oe(e){let t=[],n={};for(let r of e){if(r===`--relaunch`){n.relaunch=!0;continue}if(r===`--test-ime`){n.testIme=!0;continue}if(r===`--no-test-ime`){n.testIme=!1;continue}t.push(r)}let r=q(t);return{positionals:r.positionals,flags:n,runtime:ke(r.flags)?r.flags:void 0}}function ke(e){return!!(e.platform||e.metroHost||e.metroPort!==void 0||e.bundleUrl||e.launchUrl)}const Y=/^[A-Z_][A-Z0-9_]*$/,Ae=new Set(o.filter(e=>e!==`web`)),je=new Set([`mobile`,`tv`,`desktop`]);function Me(t){let n=[],r=[],i=t.split(/\r?\n/),a=!1,o,l=(t,n,r)=>{let i=t.kind===`multiple`?`targets-v1`:`target-v1`;throw new e(`INVALID_ARGS`,`${i} annotation on line ${t.line} must be immediately followed by its action line (line ${n+1} ${r}).`)};for(let[t,u]of i.entries()){let i=u.trim();if(i.length===0){o&&l(o,t,`is blank`);continue}if(i.startsWith(`#`)){let e=s(i);if(e.kind===`v1`){o&&l(o,t,`is another target annotation`),o={kind:`multiple`,evidence:e.evidence,line:t+1};continue}let n=c(i);if(n.kind===`v1`){o&&l(o,t,`is another target annotation`),o={kind:`single`,evidence:n.evidence,line:t+1};continue}o&&l(o,t,`is a comment`);continue}if(X(i)){if(o&&l(o,t,`is an env directive`),a)throw new e(`INVALID_ARGS`,`env directives must precede all actions (line ${t+1}).`);continue}let d=Le(u);if(!d){o&&l(o,t,`did not parse as an action`);continue}let f=re(d.command,d.positionals??[],`line ${t+1}`);if(f)throw new e(`INVALID_ARGS`,f);o&&=(o.kind===`single`?d.targetEvidence=o.evidence:d.targetEvidences=o.evidence,void 0),n.push(d),r.push(t+1),a=!0}if(o){let t=o.kind===`multiple`?`targets-v1`:`target-v1`;throw new e(`INVALID_ARGS`,`${t} annotation on line ${o.line} must be immediately followed by its action line (end of script reached).`)}return{actions:n,actionLines:r}}function Ne(e){let t=e.split(/\r?\n/),n={};for(let[e,r]of t.entries()){let t=r.trim();if(t.length===0||t.startsWith(`#`))continue;if(X(t)){Ie(n,t,e+1);continue}if(!t.startsWith(`context `))break;let i=t.match(/(?:^|\s)platform=([^\s]+)/);if(i){let e=i[1];e&&Ae.has(e)&&Z(n,`platform`,e)}let a=t.match(/(?:^|\s)target=([^\s]+)/);if(a){let e=a[1];e&&je.has(e)&&Z(n,`target`,e)}let o=t.match(/(?:^|\s)timeout=(\d+)/);if(o){let e=Number(o[1]);Number.isFinite(e)&&e>=1&&Z(n,`timeoutMs`,Math.floor(e))}let s=t.match(/(?:^|\s)retries=(\d+)/);if(s){let e=Number(s[1]);Number.isFinite(e)&&e>=0&&Z(n,`retries`,Math.floor(e))}}return n}function X(e){return e===`env`||e.startsWith(`env `)||e.startsWith(`env `)}function Pe(t,n){let r=t.slice(3).replace(/^[\s]+/,``),i=r.indexOf(`=`);if(i<=0)throw new e(`INVALID_ARGS`,`Invalid env directive on line ${n}: expected "env KEY=VALUE".`);let a=r.slice(0,i);if(!Y.test(a))throw new e(`INVALID_ARGS`,`Invalid env key "${a}" on line ${n}: keys must be uppercase letters, digits, and underscores (e.g. APP_ID).`);if(a.startsWith(`AD_`))throw new e(`INVALID_ARGS`,`Invalid env key "${a}" on line ${n}: the AD_* namespace is reserved for built-in variables. Rename ${a} to avoid the AD_ prefix.`);return{key:a,value:Fe(r.slice(i+1),n)}}function Fe(t,n){if(t.length===0)return``;if(t.startsWith(`"`))try{let e=JSON.parse(t);if(typeof e!=`string`)throw Error(`not a string literal`);return e}catch{throw new e(`INVALID_ARGS`,`Invalid quoted env value on line ${n}.`)}return t}function Ie(t,n,r){let{key:i,value:a}=Pe(n,r),o=t.env??{};if(Object.prototype.hasOwnProperty.call(o,i))throw new e(`INVALID_ARGS`,`Duplicate env directive "${i}" on line ${r}.`);o[i]=a,t.env=o}function Z(t,n,r){let i=t[n];if(i!==void 0){let t=i===r?`Duplicate replay test metadata "${n}" in context header.`:`Conflicting replay test metadata "${n}" in context header: ${String(i)} vs ${String(r)}.`;throw new e(`INVALID_ARGS`,t)}t[n]=r}function Le(t){let n=t.trim();if(n.length===0||n.startsWith(`#`))return null;let[a,...o]=Re(n);if(a===void 0||a===`context`)return null;let s={ts:Date.now(),command:a,positionals:[],flags:{}};if(a===`snapshot`){s.positionals=[];for(let e=0;e<o.length;e+=1){let t=o[e];if(t===`-i`){s.flags.snapshotInteractiveOnly=!0;continue}if(t!==`-c`){if(t===`--raw`){s.flags.snapshotRaw=!0;continue}if(t===`--force-full`){s.flags.snapshotForceFull=!0;continue}if((t===`-d`||t===`--depth`)&&e+1<o.length){let t=Number(o[e+1]);Number.isFinite(t)&&t>=0&&(s.flags.snapshotDepth=Math.floor(t)),e+=1;continue}if((t===`-s`||t===`--scope`)&&e+1<o.length){s.flags.snapshotScope=o[e+1],e+=1;continue}if(t===`--backend`&&e+1<o.length){e+=1;continue}}}return s}if(a===`open`){let e=Oe(o);return s.positionals=e.positionals,Object.assign(s.flags,e.flags),s.runtime=e.runtime,s}if(a===`runtime`){let e=q(o);return s.positionals=e.positionals,Object.assign(s.flags,e.flags),s}if(I(a)){let e=K(a,o);Object.assign(s.flags,e.flags);let t=e.positionals[0];if(t===void 0)return s;if(t.startsWith(`@`))return s.positionals=[P(t)],e.positionals[1]&&(s.result={refLabel:e.positionals[1]}),s;let n=e.positionals[0],r=e.positionals[1];return $(n)&&$(r)&&e.positionals.length>=2?(s.positionals=[n,r],s):(s.positionals=[e.positionals.join(` `)],s)}if(a===`fill`){let e=K(a,o);if(Object.assign(s.flags,e.flags),!Q(e.positionals))return s.positionals=e.positionals,s;let[t,n,...r]=e.positionals;if($(t)&&$(n))return s.positionals=[t,n,r.join(` `)],s;let[i,c,...l]=e.positionals;if(i.startsWith(`@`)){let e=P(i);return l.length>0?(s.positionals=[e,l.join(` `)],s.result={refLabel:c},s):(s.positionals=[e,c],s)}return s.positionals=[i,[c,...l].join(` `)],s}if(a===`get`){let e=o[0],t=o[1];return e===void 0||t===void 0?(s.positionals=o,s):t.startsWith(`@`)?(s.positionals=[e,P(t)],o[2]&&(s.result={refLabel:o[2]}),s):(s.positionals=[e,o.slice(1).join(` `)],s)}if(a===`swipe`||a===`type`||a===`gesture`){let e=K(a,o);return Object.assign(s.flags,e.flags),s.positionals=e.positionals,s}if(a===`record`){let t=[];for(let n=0;n<o.length;n+=1){let r=o[n];if(r===i.cliToken)throw new e(`INVALID_ARGS`,i.migration.record);if(r===`--hide-touches`){s.flags.hideTouches=!0;continue}if(r===`--fps`&&n+1<o.length){let e=Number(o[n+1]);Number.isFinite(e)&&(s.flags.fps=Math.floor(e)),n+=1;continue}if(r===`--quality`&&n+1<o.length){let e=o[n+1],t=l(e);t!==void 0&&(s.flags.quality=t),n+=1;continue}t.push(r)}return s.positionals=t,s}if(a===`screenshot`){let e=[];for(let t=0;t<o.length;t+=1){let n=o[t],i=r({args:o,index:t,flags:s.flags});if(i.handled){t=i.nextIndex;continue}e.push(n)}return s.positionals=e,s}return s.positionals=a===`wait`||a===`longpress`||a===`hover`?o.map(e=>P(e)):o,s}function Q(e){return e.length>=2}function $(e){return e?!Number.isNaN(Number(e)):!1}function Re(e){let t=[],n=0;for(;n<e.length&&(n=ze(e,n),!(n>=e.length));){let r=e[n]===`"`?Be(e,n):Ve(e,n);t.push(r.value),n=r.nextCursor}return t}function ze(e,t){let n=t;for(;n<e.length&&/\s/.test(e.charAt(n));)n+=1;return n}function Be(t,n){let r=n+1,i=!1,a=r;for(;a<t.length;a+=1){let e=t.charAt(a);if(e===`"`&&!i)break;if(i){i=!1;continue}i=e===`\\`}if(a>=t.length)throw new e(`INVALID_ARGS`,`Invalid replay script line: ${t}`);let o=t.slice(n,a+1),s;try{s=JSON.parse(o)}catch{throw new e(`INVALID_ARGS`,`Invalid quoted value ${o} in replay script line: ${t}`,{hint:`Quoted replay values are JSON strings: escape backslashes, quotes, tabs, and newlines (\\\\, \\", \\t, \\n).`})}return{value:s,nextCursor:a+1}}function Ve(e,t){let n=t;for(;n<e.length&&!/\s/.test(e.charAt(n));)n+=1;return{value:e.slice(t,n),nextCursor:n}}export{ue as C,m as E,le as S,p as T,P as _,Ee as a,k as b,we as c,Se as d,ye as f,L as g,I as h,De as i,Ce as l,B as m,Me as n,Te as o,z as p,Ne as r,xe as s,Y as t,W as u,ne as v,se as w,oe as x,ae as y};
|
|
1
|
+
import{D as e,T as t}from"./sdk-contracts.js";import{c as n,s as r,t as i}from"./capture.js";import{p as a}from"./sdk-batch-runner.js";import{r as o}from"./sdk-device.js";import{er as s,tr as c}from"./sdk-batch.js";import{i as l}from"./recording-export-quality.js";import{n as u,s as d}from"./scroll-gesture.js";import{t as f}from"./gesture-plan-types.js";const p=[`pan`,`fling`,`swipe`,`pinch`,`rotate`,`transform`,`drag`];function m(t){let n=g(t),r=x(n,`kind`,p);if(r===`pan`)return{kind:r,origin:_(n,`origin`),delta:_(n,`delta`),pointerCount:a(n,`pointerCount`,{min:1,max:2}),durationMs:h(n)};if(r===`drag`)return ee(n);if(n.pointerCount!==void 0)throw new e(`INVALID_ARGS`,`pointerCount is supported only for gesture pan`);if(r===`fling`){if(n.durationMs!==void 0)throw new e(`INVALID_ARGS`,`gesture fling does not accept durationMs; use gesture pan for timed movement`);return{kind:r,direction:x(n,`direction`,u),origin:_(n,`origin`),distance:a(n,`distance`,{min:0})}}if(r===`swipe`){if(n.durationMs!==void 0)throw new e(`INVALID_ARGS`,`gesture swipe does not accept durationMs; use gesture pan for timed movement`);return{kind:r,preset:x(n,`preset`,d)}}if(r===`pinch`)return{kind:r,scale:y(n,`scale`),origin:v(n,`origin`)};if(r===`rotate`){if(n.velocity!==void 0)throw new e(`INVALID_ARGS`,`gesture rotate does not accept velocity; rotation pacing derives from degrees`);return{kind:r,degrees:y(n,`degrees`),origin:v(n,`origin`)}}return{kind:r,origin:_(n,`origin`),delta:_(n,`delta`),scale:y(n,`scale`),degrees:y(n,`degrees`),durationMs:h(n)}}function ee(t){let n=a(t,`sourceHoldMs`,{min:1,max:1e4}),r=a(t,`moveMs`,{min:16,max:1e4}),i=a(t,`destinationHoldMs`,{min:0,max:1e4});if((n??800)+(r??500)+(i??0)>1e4)throw new e(`INVALID_ARGS`,`gesture drag total duration must be at most ${f}`);return{kind:`drag`,source:b(t,`source`),destination:b(t,`destination`),sourceHoldMs:n,moveMs:r,destinationHoldMs:i}}function h(t){let n=a(t,`durationMs`);if(n!==void 0){if(n<16||n>1e4)throw new e(`INVALID_ARGS`,`Expected durationMs to be an integer between 16 and ${f}.`);return n}}function g(t){if(!t||typeof t!=`object`||Array.isArray(t))throw new e(`INVALID_ARGS`,`gesture requires structured object input`);return t}function _(e,t){let n=g(e[t]);return{x:y(n,`x`),y:y(n,`y`)}}function v(e,t){return e[t]===void 0?void 0:_(e,t)}function y(t,n){let r=t[n];if(typeof r!=`number`||!Number.isFinite(r))throw new e(`INVALID_ARGS`,`Expected ${n} to be a finite number.`);return r}function b(t,n){let r=t[n];if(typeof r!=`string`||r.trim().length===0)throw new e(`INVALID_ARGS`,`Expected ${n} to be a non-empty string.`);return r.trim()}function x(t,n,r){let i=t[n];if(typeof i!=`string`||!r.includes(i))throw new e(`INVALID_ARGS`,`Expected ${n} to be one of: ${r.join(`, `)}.`);return i}const S={swipe:{max:4,usage:`swipe accepts 4 arguments: x1 y1 x2 y2`,retired:{positional:`durationMs`,migrate:te}},"gesture pan":{max:5,usage:`gesture pan accepts at most 5 arguments: x y dx dy [durationMs]`},"gesture fling":{max:4,usage:`gesture fling accepts at most 4 arguments: direction x y [distance]`,retired:{positional:`durationMs`,migrate:(e,t)=>`use "${t}", or gesture pan for timed movement.`}},"gesture swipe":{max:1,usage:`gesture swipe accepts 1 argument: preset`,retired:{positional:`durationMs`,migrate:(e,t)=>`use "${t}", or gesture pan for timed movement.`}},"gesture pinch":{max:3,usage:`gesture pinch accepts at most 3 arguments: scale [x] [y]`},"gesture rotate":{max:3,usage:`gesture rotate accepts at most 3 arguments: degrees [x] [y]`,retired:{positional:`velocity`,migrate:(e,t)=>`use "${t}"; rotation pacing derives from degrees.`}},"gesture transform":{max:7,usage:`gesture transform accepts at most 7 arguments: x y dx dy scale degrees [durationMs]`},"gesture drag":{max:5,usage:`gesture drag accepts at most 5 arguments: source destination [sourceHoldMs] [moveMs] [destinationHoldMs]`}};function te(e,t){let[n,r,i,a,o]=e,s=C(n,i),c=C(r,a);return s===void 0||c===void 0?`use "gesture pan x1 y1 dx dy durationMs" for the same timed drag, or "${t}" for a default-duration swipe.`:`use "gesture pan ${n} ${r} ${s} ${c} ${o}" for the same timed drag, or "${t}" for a default-duration swipe.`}function C(e,t){let n=Number(t)-Number(e);return Number.isFinite(n)?n:void 0}function w(e,t){let n=S[e];if(t.length<=n.max)return;let r=n.retired;if(!r||t.length!==n.max+1||!T(t[n.max]))return{usage:n.usage};let i=`${e} ${t.slice(0,n.max).join(` `)}`;return{usage:n.usage,migration:`The trailing ${r.positional} positional was removed: ${r.migrate(t,i)}`}}function T(e){return e===void 0||e.trim().length===0?!1:e.startsWith("${")||Number.isFinite(Number(e))}function ne(t){if(!(!t||typeof t!=`object`||Array.isArray(t))&&t.durationMs!==void 0)throw new e(`INVALID_ARGS`,`swipe does not accept durationMs; use gesture pan for timed movement`)}function E(e,t){let n=t?`${e.usage} (${t})`:e.usage;return e.migration?`${n}. ${e.migration}`:`${n}.`}function D(t,n){let r=w(t,n);if(r)throw new e(`INVALID_ARGS`,E(r))}function re(e,t,n){let r=ie(e,t);return r?E(r,n):void 0}function ie(e,t){if(e===`swipe`)return w(`swipe`,t);if(e!==`gesture`)return;let n=`gesture ${t[0]}`;if(Object.hasOwn(S,n))return w(n,t.slice(1))}function O(e){return{origin:{x:Number(e[0]),y:Number(e[1])},delta:{x:Number(e[2]),y:Number(e[3])}}}function k(e,t){let n=e[0],r=e.slice(1);switch(n){case`pan`:{D(`gesture pan`,r);let{origin:e,delta:i}=O(r);return m({kind:n,origin:e,delta:i,pointerCount:t,durationMs:A(r[4])})}case`fling`:return D(`gesture fling`,r),m({kind:n,direction:r[0],origin:{x:Number(r[1]),y:Number(r[2])},distance:A(r[3])});case`swipe`:return D(`gesture swipe`,r),m({kind:n,preset:r[0]});case`pinch`:return D(`gesture pinch`,r),m({kind:n,scale:Number(r[0]),origin:j(r[1],r[2])});case`rotate`:return D(`gesture rotate`,r),m({kind:n,degrees:Number(r[0]),origin:j(r[1],r[2])});case`transform`:{D(`gesture transform`,r);let{origin:e,delta:t}=O(r);return m({kind:n,origin:e,delta:t,scale:Number(r[4]),degrees:Number(r[5]),durationMs:A(r[6])})}case`drag`:return D(`gesture drag`,r),m({kind:n,source:r[0],destination:r[1],sourceHoldMs:A(r[2]),moveMs:A(r[3]),destinationHoldMs:A(r[4])});default:return m({kind:n})}}function ae(e){if(e[0]!==`drag`)return;let t=k(e);return t.kind===`drag`?t:void 0}function oe(e){switch(e.kind){case`pan`:return M([e.kind,e.origin.x,e.origin.y,e.delta.x,e.delta.y,e.durationMs]);case`fling`:return M([e.kind,e.direction,e.origin.x,e.origin.y,e.distance]);case`swipe`:return[e.kind,e.preset];case`pinch`:return M([e.kind,e.scale,e.origin?.x,e.origin?.y]);case`rotate`:return e.origin?M([e.kind,e.degrees,e.origin.x,e.origin.y]):[e.kind,String(e.degrees)];case`transform`:return M([e.kind,e.origin.x,e.origin.y,e.delta.x,e.delta.y,e.scale,e.degrees,e.durationMs]);case`drag`:return[e.kind,e.source,e.destination,String(e.sourceHoldMs??800),String(e.moveMs??500),String(e.destinationHoldMs??0)]}}function se(e,t={}){return D(`swipe`,e),{from:{x:Number(e[0]),y:Number(e[1])},to:{x:Number(e[2]),y:Number(e[3])},...t.count===void 0?{}:{count:t.count},...t.pauseMs===void 0?{}:{pauseMs:t.pauseMs},...t.pattern===void 0?{}:{pattern:t.pattern}}}function ce(t){switch(t.kind){case`pan`:return{gesture:{intent:`pan`,origin:t.origin,delta:t.delta,pointerCount:t.pointerCount,durationMs:t.durationMs}};case`fling`:return{gesture:{intent:`fling`,direction:t.direction,origin:t.origin,distance:t.distance}};case`swipe`:return{gesture:{intent:`fling`,preset:t.preset}};case`pinch`:return{gesture:{intent:`pinch`,origin:t.origin,scale:t.scale}};case`rotate`:return{gesture:{intent:`rotate`,origin:t.origin,degrees:t.degrees}};case`transform`:return{gesture:{intent:`transform`,origin:t.origin,delta:t.delta,scale:t.scale,degrees:t.degrees,durationMs:t.durationMs}};case`drag`:throw new e(`INVALID_ARGS`,`gesture drag targets must be resolved before coordinate normalization`)}}function le(e){return e.kind===`drag`?{intent:`drag`,source:e.source,destination:e.destination,sourceHoldMs:e.sourceHoldMs,moveMs:e.moveMs,destinationHoldMs:e.destinationHoldMs}:ce(e).gesture}function ue(e){return{gesture:{intent:`fling`,from:e.from,to:e.to}}}function A(e){return e===void 0?void 0:Number(e)}function j(t,n){if(t===void 0!=(n===void 0))throw new e(`INVALID_ARGS`,`gesture origin requires both x and y coordinates`);return t===void 0?void 0:{x:Number(t),y:Number(n)}}function M(e){return e.filter(e=>e!==void 0).map(String)}const de={ios:!0,android:!0,harmonyos:!0};function N(e){return typeof e==`string`&&Object.hasOwn(de,e)}function P(e){return e.startsWith(`@`)?t(e)?.base??e:e}const F=/^-?\d+(\.\d+)?$/,fe=/^[^\s"\\]+$/,pe=new Map([[`--count`,`count`],[`--interval-ms`,`intervalMs`],[`--hold-ms`,`holdMs`],[`--jitter-px`,`jitterPx`]]),me=new Map([[`--count`,`count`],[`--pause-ms`,`pauseMs`]]),he=new Map([[`--pointer-count`,`pointerCount`]]),ge=new Map([[`--delay-ms`,`delayMs`]]);function I(e){return e===`click`||e===`press`}function L(e){return I(e)||e===`longpress`||e===`hover`}function R(e){return e===`type`||e===`fill`}function z(e){return H(e,_e)}function B(e){return JSON.stringify(e)}function V(e){return H(e,U)}function H(e,t){return t(e)?e:B(e)}function _e(e){return U(e)&&e.startsWith(`@`)||F.test(e)}function U(e){return fe.test(e)}const ve=new Set([`fill`,`type`]);function ye(e){if(!ve.has(e.command)){let t=(e.positionals??[]).map(e=>z(e));return[e.command,...t].join(` `)}let t=be(e).map(e=>z(e)).join(` `);return[e.command,t,`<text>`].filter(e=>e.length>0).join(` `)}function be(e){if(e.command===`type`)return[];let t=e.positionals??[],n=t[0];return n===void 0?[]:n.startsWith(`@`)?[n]:t.length>=3&&F.test(n)&&F.test(t[1]??``)?[n,t[1]]:[n]}function W(e,t){let n=t.flags??{};if(I(t.command)){typeof n.count==`number`&&e.push(`--count`,String(n.count)),typeof n.intervalMs==`number`&&e.push(`--interval-ms`,String(n.intervalMs)),typeof n.holdMs==`number`&&e.push(`--hold-ms`,String(n.holdMs)),typeof n.jitterPx==`number`&&e.push(`--jitter-px`,String(n.jitterPx)),n.doubleTap===!0&&e.push(`--double-tap`);let t=n.clickButton;t&&t!==`primary`&&e.push(`--button`,t);return}if(t.command===`swipe`){typeof n.count==`number`&&e.push(`--count`,String(n.count)),typeof n.pauseMs==`number`&&e.push(`--pause-ms`,String(n.pauseMs)),(n.pattern===`one-way`||n.pattern===`ping-pong`)&&e.push(`--pattern`,n.pattern);return}if(t.command===`gesture`){typeof n.pointerCount==`number`&&e.push(`--pointer-count`,String(n.pointerCount));return}R(t.command)&&typeof n.delayMs==`number`&&e.push(`--delay-ms`,String(n.delayMs))}function G(e,t){t&&(N(t.platform)&&e.push(`--platform`,t.platform),typeof t.metroHost==`string`&&t.metroHost.length>0&&e.push(`--metro-host`,V(t.metroHost)),typeof t.metroPort==`number`&&e.push(`--metro-port`,String(t.metroPort)),typeof t.bundleUrl==`string`&&t.bundleUrl.length>0&&e.push(`--bundle-url`,V(t.bundleUrl)),typeof t.launchUrl==`string`&&t.launchUrl.length>0&&e.push(`--launch-url`,V(t.launchUrl)))}function xe(e,t){let[n,...r]=t.positionals??[];n&&e.push(V(n));for(let t of r)e.push(z(t));typeof t.flags?.fps==`number`&&e.push(`--fps`,String(t.flags.fps)),(typeof t.flags?.quality==`number`||typeof t.flags?.quality==`string`)&&e.push(`--quality`,String(t.flags.quality)),t.flags?.hideTouches&&e.push(`--hide-touches`)}function Se(e,t){t.flags?.snapshotInteractiveOnly&&e.push(`-i`),typeof t.flags?.snapshotDepth==`number`&&e.push(`-d`,String(t.flags.snapshotDepth)),t.flags?.snapshotScope&&e.push(`-s`,z(t.flags.snapshotScope)),t.flags?.snapshotRaw&&e.push(`--raw`)}function Ce(e,t){for(let n of t.positionals??[])e.push(z(n));let n=t.flags?.screenshotCropOn;typeof n==`string`&&n.length>0&&e.push(`--crop-on`,V(n)),r(e,t.flags)}function we(e,t,n={}){let r=t.positionals??[],i=n.includeAllPositionals?r:r.slice(0,1);for(let t of i)e.push(V(t));G(e,t.flags)}function Te(e,t){for(let n of t.positionals??[])e.push(z(t.command===`wait`?P(n):n));t.command===`fold`&&t.flags?.keyframes!==void 0&&e.push(`--keyframes`,z(t.flags.keyframes)),W(e,t)}function K(e,t){let n=[],r={},i=I(e)?pe:e===`swipe`?me:e===`gesture`?he:R(e)?ge:void 0;for(let a=0;a<t.length;a+=1){let o=t[a];if(I(e)&&o===`--double-tap`){r.doubleTap=!0;continue}let s=t[a+1];if(e===`fold`&&o===`--keyframes`&&s!==void 0){r.keyframes=s,a+=1;continue}if(I(e)&&o===`--button`&&s!==void 0){let e=s;(e===`primary`||e===`secondary`||e===`middle`)&&(r.clickButton=e),a+=1;continue}let c=i?.get(o);if(c&&s!==void 0){let e=J(s);if(e!==null){r[c]=e,a+=1;continue}}if(e===`swipe`&&o===`--pattern`&&s!==void 0){let e=s;(e===`one-way`||e===`ping-pong`)&&(r.pattern=e),a+=1;continue}n.push(o)}return{positionals:n,flags:r}}function q(e){let t=[],n={};for(let r=0;r<e.length;r+=1){let i=e[r],a=e[r+1];if(i===`--platform`&&a!==void 0){let e=a;N(e)&&(n.platform=e),r+=1;continue}if(i===`--metro-host`&&a!==void 0){n.metroHost=a,r+=1;continue}if(i===`--metro-port`&&a!==void 0){let e=J(a);e!==null&&(n.metroPort=e),r+=1;continue}if(i===`--bundle-url`&&a!==void 0){n.bundleUrl=a,r+=1;continue}if(i===`--launch-url`&&a!==void 0){n.launchUrl=a,r+=1;continue}t.push(i)}return{positionals:t,flags:n}}function J(e){if(!e)return null;let t=Number(e);return!Number.isFinite(t)||t<0?null:Math.floor(t)}function Ee(e){let t;for(let n of e){if(n.command===`runtime`&&typeof n.flags.platform==`string`){t=n.flags.platform;continue}if(n.command===`open`)return n.runtime?.platform??t}return t}function De(e,t){for(let n of t.positionals??[])e.push(z(n));t.flags?.relaunch&&e.push(`--relaunch`),t.flags?.testIme===!0?e.push(`--test-ime`):t.flags?.testIme===!1&&e.push(`--no-test-ime`),G(e,t.runtime)}function Oe(e){let t=[],n={};for(let r of e){if(r===`--relaunch`){n.relaunch=!0;continue}if(r===`--test-ime`){n.testIme=!0;continue}if(r===`--no-test-ime`){n.testIme=!1;continue}t.push(r)}let r=q(t);return{positionals:r.positionals,flags:n,runtime:ke(r.flags)?r.flags:void 0}}function ke(e){return!!(e.platform||e.metroHost||e.metroPort!==void 0||e.bundleUrl||e.launchUrl)}const Y=/^[A-Z_][A-Z0-9_]*$/,Ae=new Set(o.filter(e=>e!==`web`)),je=new Set([`mobile`,`tv`,`desktop`]);function Me(t){let n=[],r=[],i=t.split(/\r?\n/),a=!1,o,l=(t,n,r)=>{let i=t.kind===`multiple`?`targets-v1`:`target-v1`;throw new e(`INVALID_ARGS`,`${i} annotation on line ${t.line} must be immediately followed by its action line (line ${n+1} ${r}).`)};for(let[t,u]of i.entries()){let i=u.trim();if(i.length===0){o&&l(o,t,`is blank`);continue}if(i.startsWith(`#`)){let e=s(i);if(e.kind===`v1`){o&&l(o,t,`is another target annotation`),o={kind:`multiple`,evidence:e.evidence,line:t+1};continue}let n=c(i);if(n.kind===`v1`){o&&l(o,t,`is another target annotation`),o={kind:`single`,evidence:n.evidence,line:t+1};continue}o&&l(o,t,`is a comment`);continue}if(X(i)){if(o&&l(o,t,`is an env directive`),a)throw new e(`INVALID_ARGS`,`env directives must precede all actions (line ${t+1}).`);continue}let d=Le(u);if(!d){o&&l(o,t,`did not parse as an action`);continue}let f=re(d.command,d.positionals??[],`line ${t+1}`);if(f)throw new e(`INVALID_ARGS`,f);o&&=(o.kind===`single`?d.targetEvidence=o.evidence:d.targetEvidences=o.evidence,void 0),n.push(d),r.push(t+1),a=!0}if(o){let t=o.kind===`multiple`?`targets-v1`:`target-v1`;throw new e(`INVALID_ARGS`,`${t} annotation on line ${o.line} must be immediately followed by its action line (end of script reached).`)}return{actions:n,actionLines:r}}function Ne(e){let t=e.split(/\r?\n/),n={};for(let[e,r]of t.entries()){let t=r.trim();if(t.length===0||t.startsWith(`#`))continue;if(X(t)){Ie(n,t,e+1);continue}if(!t.startsWith(`context `))break;let i=t.match(/(?:^|\s)platform=([^\s]+)/);if(i){let e=i[1];e&&Ae.has(e)&&Z(n,`platform`,e)}let a=t.match(/(?:^|\s)target=([^\s]+)/);if(a){let e=a[1];e&&je.has(e)&&Z(n,`target`,e)}let o=t.match(/(?:^|\s)timeout=(\d+)/);if(o){let e=Number(o[1]);Number.isFinite(e)&&e>=1&&Z(n,`timeoutMs`,Math.floor(e))}let s=t.match(/(?:^|\s)retries=(\d+)/);if(s){let e=Number(s[1]);Number.isFinite(e)&&e>=0&&Z(n,`retries`,Math.floor(e))}}return n}function X(e){return e===`env`||e.startsWith(`env `)||e.startsWith(`env `)}function Pe(t,n){let r=t.slice(3).replace(/^[\s]+/,``),i=r.indexOf(`=`);if(i<=0)throw new e(`INVALID_ARGS`,`Invalid env directive on line ${n}: expected "env KEY=VALUE".`);let a=r.slice(0,i);if(!Y.test(a))throw new e(`INVALID_ARGS`,`Invalid env key "${a}" on line ${n}: keys must be uppercase letters, digits, and underscores (e.g. APP_ID).`);if(a.startsWith(`AD_`))throw new e(`INVALID_ARGS`,`Invalid env key "${a}" on line ${n}: the AD_* namespace is reserved for built-in variables. Rename ${a} to avoid the AD_ prefix.`);return{key:a,value:Fe(r.slice(i+1),n)}}function Fe(t,n){if(t.length===0)return``;if(t.startsWith(`"`))try{let e=JSON.parse(t);if(typeof e!=`string`)throw Error(`not a string literal`);return e}catch{throw new e(`INVALID_ARGS`,`Invalid quoted env value on line ${n}.`)}return t}function Ie(t,n,r){let{key:i,value:a}=Pe(n,r),o=t.env??{};if(Object.prototype.hasOwnProperty.call(o,i))throw new e(`INVALID_ARGS`,`Duplicate env directive "${i}" on line ${r}.`);o[i]=a,t.env=o}function Z(t,n,r){let i=t[n];if(i!==void 0){let t=i===r?`Duplicate replay test metadata "${n}" in context header.`:`Conflicting replay test metadata "${n}" in context header: ${String(i)} vs ${String(r)}.`;throw new e(`INVALID_ARGS`,t)}t[n]=r}function Le(t){let r=t.trim();if(r.length===0||r.startsWith(`#`))return null;let[a,...o]=Re(r);if(a===void 0||a===`context`)return null;let s={ts:Date.now(),command:a,positionals:[],flags:{}};if(a===`snapshot`){s.positionals=[];for(let e=0;e<o.length;e+=1){let t=o[e];if(t===`-i`){s.flags.snapshotInteractiveOnly=!0;continue}if(t!==`-c`){if(t===`--raw`){s.flags.snapshotRaw=!0;continue}if(t===`--force-full`){s.flags.snapshotForceFull=!0;continue}if((t===`-d`||t===`--depth`)&&e+1<o.length){let t=Number(o[e+1]);Number.isFinite(t)&&t>=0&&(s.flags.snapshotDepth=Math.floor(t)),e+=1;continue}if((t===`-s`||t===`--scope`)&&e+1<o.length){s.flags.snapshotScope=o[e+1],e+=1;continue}if(t===`--backend`&&e+1<o.length){e+=1;continue}}}return s}if(a===`open`){let e=Oe(o);return s.positionals=e.positionals,Object.assign(s.flags,e.flags),s.runtime=e.runtime,s}if(a===`runtime`){let e=q(o);return s.positionals=e.positionals,Object.assign(s.flags,e.flags),s}if(I(a)){let e=K(a,o);Object.assign(s.flags,e.flags);let t=e.positionals[0];if(t===void 0)return s;if(t.startsWith(`@`))return s.positionals=[P(t)],e.positionals[1]&&(s.result={refLabel:e.positionals[1]}),s;let n=e.positionals[0],r=e.positionals[1];return $(n)&&$(r)&&e.positionals.length>=2?(s.positionals=[n,r],s):(s.positionals=[e.positionals.join(` `)],s)}if(a===`fill`){let e=K(a,o);if(Object.assign(s.flags,e.flags),!Q(e.positionals))return s.positionals=e.positionals,s;let[t,n,...r]=e.positionals;if($(t)&&$(n))return s.positionals=[t,n,r.join(` `)],s;let[i,c,...l]=e.positionals;if(i.startsWith(`@`)){let e=P(i);return l.length>0?(s.positionals=[e,l.join(` `)],s.result={refLabel:c},s):(s.positionals=[e,c],s)}return s.positionals=[i,[c,...l].join(` `)],s}if(a===`get`){let e=o[0],t=o[1];return e===void 0||t===void 0?(s.positionals=o,s):t.startsWith(`@`)?(s.positionals=[e,P(t)],o[2]&&(s.result={refLabel:o[2]}),s):(s.positionals=[e,o.slice(1).join(` `)],s)}if(a===`swipe`||a===`type`||a===`gesture`||a===`fold`){let e=K(a,o);return Object.assign(s.flags,e.flags),s.positionals=e.positionals,s}if(a===`record`){let t=[];for(let n=0;n<o.length;n+=1){let r=o[n];if(r===i.cliToken)throw new e(`INVALID_ARGS`,i.migration.record);if(r===`--hide-touches`){s.flags.hideTouches=!0;continue}if(r===`--fps`&&n+1<o.length){let e=Number(o[n+1]);Number.isFinite(e)&&(s.flags.fps=Math.floor(e)),n+=1;continue}if(r===`--quality`&&n+1<o.length){let e=o[n+1],t=l(e);t!==void 0&&(s.flags.quality=t),n+=1;continue}t.push(r)}return s.positionals=t,s}if(a===`screenshot`){let e=[];for(let t=0;t<o.length;t+=1){let r=o[t],i=n({args:o,index:t,flags:s.flags});if(i.handled){t=i.nextIndex;continue}e.push(r)}return s.positionals=e,s}return s.positionals=a===`wait`||a===`longpress`||a===`hover`?o.map(e=>P(e)):o,s}function Q(e){return e.length>=2}function $(e){return e?!Number.isNaN(Number(e)):!1}function Re(e){let t=[],n=0;for(;n<e.length&&(n=ze(e,n),!(n>=e.length));){let r=e[n]===`"`?Be(e,n):Ve(e,n);t.push(r.value),n=r.nextCursor}return t}function ze(e,t){let n=t;for(;n<e.length&&/\s/.test(e.charAt(n));)n+=1;return n}function Be(t,n){let r=n+1,i=!1,a=r;for(;a<t.length;a+=1){let e=t.charAt(a);if(e===`"`&&!i)break;if(i){i=!1;continue}i=e===`\\`}if(a>=t.length)throw new e(`INVALID_ARGS`,`Invalid replay script line: ${t}`);let o=t.slice(n,a+1),s;try{s=JSON.parse(o)}catch{throw new e(`INVALID_ARGS`,`Invalid quoted value ${o} in replay script line: ${t}`,{hint:`Quoted replay values are JSON strings: escape backslashes, quotes, tabs, and newlines (\\\\, \\", \\t, \\n).`})}return{value:s,nextCursor:a+1}}function Ve(e,t){let n=t;for(;n<e.length&&!/\s/.test(e.charAt(n));)n+=1;return{value:e.slice(t,n),nextCursor:n}}export{ue as C,m as E,le as S,p as T,P as _,Ee as a,k as b,we as c,Se as d,ye as f,L as g,I as h,De as i,Ce as l,B as m,Me as n,Te as o,z as p,Ne as r,xe as s,Y as t,W as u,ne as v,se as w,oe as x,ae as y};
|