agent-device 0.21.22 → 0.21.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -6
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.22.apk → agent-device-android-ime-helper-0.21.24.apk} +0 -0
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.24.apk.sha256 +1 -0
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.22.manifest.json → agent-device-android-ime-helper-0.21.24.manifest.json} +4 -4
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.24.apk +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.24.apk.sha256 +1 -0
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.22.manifest.json → agent-device-android-snapshot-helper-0.21.24.manifest.json} +6 -6
- package/apple/macos-helper/Sources/AgentDeviceMacOSHelper/SnapshotTraversal.swift +12 -6
- package/apple/macos-helper/Tests/AgentDeviceMacOSHelperTests/RectResponseTests.swift +21 -0
- package/apple/snapshot-bridge/README.md +9 -7
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandDispatch.swift +56 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +14 -5
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +8 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +12 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCaptureTarget.swift +1 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotExecution.swift +29 -5
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +34 -10
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntryFocus.swift +19 -5
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextTyping.swift +3 -3
- package/dist/src/adapter.js +1 -1
- package/dist/src/adb.js +1 -1
- package/dist/src/agent-browser-lifecycle.js +1 -1
- package/dist/src/agent-browser-process-record.js +1 -1
- package/dist/src/agent-browser-provider.js +1 -1
- package/dist/src/agent-device-client.js +2 -2
- package/dist/src/alert-runtime.js +1 -1
- package/dist/src/alert.js +1 -1
- package/dist/src/android-adb.d.ts +3 -2
- package/dist/src/android-input-ownership.js +1 -1
- package/dist/src/app-backend.js +1 -1
- package/dist/src/app-inventory.d.ts +4 -0
- package/dist/src/app-launch.js +1 -1
- package/dist/src/app-lifecycle.js +1 -1
- package/dist/src/app-log-reconnect.js +1 -1
- package/dist/src/app-log-runtime2.js +3 -3
- package/dist/src/app-resolution.js +2 -2
- package/dist/src/app-state-runtime.d.ts +15 -0
- package/dist/src/apple-runner-platform.js +1 -1
- package/dist/src/application-lifecycle-interaction.js +1 -1
- package/dist/src/aws-device-farm-connection.js +1 -0
- package/dist/src/back-mode.js +1 -1
- package/dist/src/backend-snapshot-options.js +1 -1
- package/dist/src/browserstack-connection.js +1 -0
- package/dist/src/browserstack-device-features.js +1 -0
- package/dist/src/browserstack.js +1 -0
- package/dist/src/cache.js +1 -1
- package/dist/src/cli-config.js +1 -1
- package/dist/src/cli-help.js +35 -19
- package/dist/src/cli-runner.js +1 -1
- package/dist/src/cli.js +3 -4
- package/dist/src/client-companion-tunnel.js +1 -0
- package/dist/src/client-metro-companion.js +1 -1
- package/dist/src/client-metro.js +1 -1
- package/dist/src/client-options.js +3 -3
- package/dist/src/client-types.d.ts +7 -5
- package/dist/src/cloud-artifacts.d.ts +9 -2
- package/dist/src/code-signature-cache.js +1 -1
- package/dist/src/command-metadata.js +1 -1
- package/dist/src/command-schema.js +1 -1
- package/dist/src/command-tools.js +2 -2
- package/dist/src/connection-runtime.js +1 -1
- package/dist/src/connection-verification.js +1 -0
- package/dist/src/connection.js +5 -5
- package/dist/src/contracts.d.ts +1 -1
- package/dist/src/daemon-client-lease-beat.js +1 -1
- package/dist/src/daemon-client-lifecycle.js +1 -1
- package/dist/src/daemon-client-transport.js +1 -1
- package/dist/src/daemon-http.js +1 -1
- package/dist/src/daemon-policy-file.js +1 -1
- package/dist/src/daemon-registration-owner.js +1 -1
- package/dist/src/device-claim-inspection.js +1 -1
- package/dist/src/device-input-state.d.ts +2 -15
- package/dist/src/device-readiness-runtime.js +1 -1
- package/dist/src/device-selection-resolver.js +1 -1
- package/dist/src/device-session.js +3 -1
- package/dist/src/device.js +1 -1
- package/dist/src/device2.js +1 -1
- package/dist/src/device3.js +1 -1
- package/dist/src/dispatch-resolve.js +3 -3
- package/dist/src/doctor-facade.js +1 -1
- package/dist/src/durable-capture-resource.js +1 -1
- package/dist/src/durable-resource.js +1 -1
- package/dist/src/exec.js +1 -1
- package/dist/src/file.js +1 -1
- package/dist/src/find.js +1 -1
- package/dist/src/finders.js +1 -1
- package/dist/src/format.js +2 -1
- package/dist/src/gesture-admission.js +1 -1
- package/dist/src/gesture-plan-types.d.ts +2 -5
- package/dist/src/gesture-runtime.js +1 -1
- package/dist/src/helper.js +2 -2
- package/dist/src/human-control.js +1 -1
- package/dist/src/ime-rebind.js +1 -0
- package/dist/src/ime-settings-record.js +1 -0
- package/dist/src/ime-state.js +1 -0
- package/dist/src/index.d.ts +3 -3
- package/dist/src/input-actions.js +1 -1
- package/dist/src/input-actions2.js +1 -1
- package/dist/src/install-source2.js +1 -1
- package/dist/src/instance-client.js +1 -1
- package/dist/src/interaction-positionals.js +1 -1
- package/dist/src/interaction-ref-policy.js +1 -1
- package/dist/src/interaction.js +1 -1
- package/dist/src/interaction2.js +1 -1
- package/dist/src/interactor.js +5 -5
- package/dist/src/interactors.js +1 -1
- package/dist/src/internal/bin.js +1 -1
- package/dist/src/internal/daemon.js +1 -1
- package/dist/src/inventory2.js +1 -1
- package/dist/src/ios-client.js +4 -4
- package/dist/src/ios-snapshot-acquisition.js +1 -1
- package/dist/src/ios-snapshot-engine.js +1 -1
- package/dist/src/ios-snapshot-runtime.js +1 -1
- package/dist/src/launch-confirmation.js +1 -1
- package/dist/src/lease-scope.js +1 -1
- package/dist/src/lease.js +1 -1
- package/dist/src/limrun.d.ts +4 -555
- package/dist/src/load.js +1 -1
- package/dist/src/local-interactor-operation-set.js +1 -1
- package/dist/src/log-stream.js +33 -0
- package/dist/src/managed-device-scope.js +1 -1
- package/dist/src/manifest.js +1 -0
- package/dist/src/mechanics.js +16 -16
- package/dist/src/mobile-snapshot-semantics.js +1 -1
- package/dist/src/node-http.js +1 -0
- package/dist/src/observation.js +1 -2
- package/dist/src/overlay.js +3 -3
- package/dist/src/owner-identity.js +3 -3
- package/dist/src/perf-facade.js +1 -1
- package/dist/src/perf-runtime-plan.js +1 -1
- package/dist/src/perf-target.js +1 -1
- package/dist/src/physical-device-control.js +1 -1
- package/dist/src/platform-request-scope.js +1 -1
- package/dist/src/platform-runtime-app-log-process.js +1 -1
- package/dist/src/platform-runtime-open-target.js +1 -1
- package/dist/src/platform-runtime-operation-host.js +4 -4
- package/dist/src/platform-runtime-runtime-hints.js +1 -1
- package/dist/src/platform-runtime-screen-recording-finalizer-host.js +1 -1
- package/dist/src/platform-runtime-screen-recording-process-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/plugin.js +1 -0
- package/dist/src/plugins/webdriver.d.ts +111 -0
- package/dist/src/plugins/webdriver.js +1 -0
- package/dist/src/plugins.d.ts +2 -1
- package/dist/src/plugins2.js +1 -1
- package/dist/src/process-exit.js +1 -1
- package/dist/src/process.js +1 -1
- package/dist/src/provider-credential-fingerprint.js +1 -1
- package/dist/src/provider-device-admission.js +1 -1
- package/dist/src/provider-device-runtime.d.ts +556 -0
- package/dist/src/provider-policy.js +1 -0
- package/dist/src/provider-profile-fields.js +1 -1
- package/dist/src/provider-webdriver.js +1 -2
- package/dist/src/providers.js +1 -1
- package/dist/src/proxy.js +2 -2
- package/dist/src/react-devtools.js +2 -0
- package/dist/src/react-native.js +1 -1
- package/dist/src/record-runtime.js +1 -1
- package/dist/src/record-trace.js +1 -1
- package/dist/src/recording.js +1 -1
- package/dist/src/registry.js +24 -24
- package/dist/src/remote-bridge.js +1 -0
- package/dist/src/remote-config-core.js +1 -0
- package/dist/src/remote-config.js +1 -1
- package/dist/src/remote-config2.js +1 -1
- package/dist/src/remote-connection-state.js +1 -0
- package/dist/src/replay.js +2 -2
- package/dist/src/request-admission.js +1 -1
- package/dist/src/request-runtime-binding.js +1 -1
- package/dist/src/result-serialization.js +1 -1
- package/dist/src/retry.js +1 -1
- package/dist/src/retry2.js +1 -0
- package/dist/src/runner-artifact-manifest.js +1 -1
- package/dist/src/runner-cache-metadata.js +2 -3
- package/dist/src/runner-cache-retention.js +1 -0
- package/dist/src/runner-cache-trim.js +1 -0
- 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-device-set.js +1 -0
- package/dist/src/runner-disposal.js +1 -1
- package/dist/src/runner-error-classification.js +1 -1
- package/dist/src/runner-exchange.js +1 -1
- package/dist/src/runner-lease.js +1 -0
- package/dist/src/runner-operations-facade.js +1 -1
- package/dist/src/runner-session-types.js +1 -1
- package/dist/src/runner-start-budget.js +1 -1
- package/dist/src/runner-toolchain-probe.js +2 -0
- package/dist/src/runner.js +1 -1
- package/dist/src/runtime-deployment.js +1 -0
- package/dist/src/runtime.js +1 -1
- package/dist/src/runtime10.js +1 -2
- package/dist/src/runtime11.js +2 -0
- package/dist/src/runtime2.js +2 -5
- package/dist/src/runtime3.js +5 -1
- package/dist/src/runtime4.js +1 -5
- package/dist/src/runtime5.js +5 -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-transport.js +1 -1
- package/dist/src/screenshot-density.js +1 -1
- package/dist/src/screenshot-overlay-draw.js +1 -1
- package/dist/src/screenshot3.js +2 -2
- package/dist/src/script.js +1 -1
- package/dist/src/scroll-gesture.js +1 -1
- package/dist/src/sdk-batch.js +2 -2
- package/dist/src/sdk-contracts.d.ts +25 -33
- package/dist/src/sdk-contracts.js +2 -2
- package/dist/src/sdk-device.js +1 -1
- package/dist/src/sdk-finders.d.ts +1 -1
- package/dist/src/sdk-finders.js +1 -1
- package/dist/src/sdk-remote-config.d.ts +4 -0
- package/dist/src/sdk-remote-config.js +1 -1
- package/dist/src/sdk-selectors.d.ts +1 -1
- package/dist/src/sdk-selectors.js +1 -1
- package/dist/src/selection.js +0 -0
- package/dist/src/selector-pipeline-policy.js +1 -1
- package/dist/src/selector-runtime.js +1 -1
- package/dist/src/selectors.js +1 -1
- package/dist/src/server.js +2 -2
- package/dist/src/session-snapshot.js +1 -1
- package/dist/src/session2.js +5 -5
- package/dist/src/simctl.js +1 -1
- package/dist/src/simulator-boot.js +1 -1
- package/dist/src/simulator-state.js +1 -1
- package/dist/src/simulator.js +1 -1
- package/dist/src/snapshot-capture-annotations.js +1 -1
- package/dist/src/snapshot-desktop-projection.js +1 -1
- package/dist/src/snapshot-private-evidence.js +1 -0
- 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/src2.js +1 -1
- package/dist/src/src3.js +1 -1
- package/dist/src/src4.js +1 -1
- package/dist/src/src5.js +1 -1
- package/dist/src/src6.js +1 -1
- package/dist/src/src7.js +1 -1
- package/dist/src/src8.js +20 -20
- package/dist/src/store.js +1 -1
- package/dist/src/target-evidence.js +1 -1
- package/dist/src/text-entry-focus.js +1 -1
- package/dist/src/tool-provider2.js +1 -1
- package/dist/src/touch-runtime2.js +1 -1
- package/dist/src/tree.js +1 -1
- package/dist/src/type-text-runtime.js +1 -1
- package/dist/src/video.js +1 -1
- package/package.json +24 -16
- package/server.json +2 -2
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.22.apk.sha256 +0 -1
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.22.apk +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.22.apk.sha256 +0 -1
- package/dist/src/capabilities.js +0 -1
- package/dist/src/compatibility-policy.js +0 -1
- package/dist/src/daemon-artifacts.js +0 -1
- package/dist/src/device-claim-rule.js +0 -1
- package/dist/src/human-control-contract.js +0 -1
- package/dist/src/prepare-kind.js +0 -1
- package/dist/src/provider-device-runtimes.js +0 -1
- package/dist/src/screen-recording-admission-ledger.js +0 -1
- package/dist/src/screenshot-runtime.js +0 -1
- package/dist/src/session-routing.js +0 -1
- package/dist/src/session-runtime-admission.js +0 -1
- package/dist/src/session-stream.js +0 -27
- package/dist/src/timeouts.js +0 -1
- package/dist/src/touch-reference-frame.js +0 -1
- package/dist/src/vars.js +0 -2
- package/dist/src/viewport.js +0 -1
|
@@ -1 +1,3 @@
|
|
|
1
|
-
import{B as e,P as t}from"./sdk-contracts.js";import{i as n}from"./sdk-batch-runner.js";import{n as r}from"./app-inventory.js";import"./device.js";import{t as i}from"./ios-client.js";import{t as a}from"./instance-client.js";import{t as o}from"./request-cancellation.js";import{i as s}from"./snapshot.js";import c from"node:fs";import l from"node:os";import u from"node:path";import{setTimeout as d}from"node:timers/promises";function f(e){return e?.trim()||void 0}async function p(e,t){let n=await a({apiUrl:e.apiUrl,adbUrl:e.adbUrl,token:e.token,logLevel:`warn`}),r={platform:`android`,lease:e.lease,instanceId:e.instanceId,ownership:e.ownership,device:e.device,client:n,token:e.token,dependencies:t},i={exec:async(e,t)=>await y(r,e,t),text:async e=>{await n.setText(e.target,e.text)}};return i.reverse=await t.android.createPortReverse(i.exec,{noRebind:e.ownership===`attached`}),Object.assign(r,{adbProvider:i})}function m(e){return e.dependencies.android.createInteractor(e.device,e.adbProvider)}async function h(e,t,n,r,i,a){i?.throwIfAborted();let s=f(r?.packageNameHint);r?.relaunch&&s&&await t.dependencies.android.forceStopApp(async(e,n)=>await y(t,e,n),s,i);let c=await o(a,e.assets.getOrUpload({path:n,name:T(s,n)},{signal:i}),i);await o(a,t.client.sendAsset(c.signedDownloadUrl),i),i?.throwIfAborted();let l=s?await t.dependencies.android.inferAppName(s):void 0;return{...s?{packageName:s,launchTarget:s}:{},...l?{appName:l}:{}}}async function g(e,t){await e.adbProvider.reverse?.ensure({local:w(t.devicePort),remote:w(t.hostPort),ownerId:t.name})}async function _(e){await e.adbTunnelPromise?.catch(()=>{});let t=e.adbSerial;t&&(await v(e),await e.dependencies.host.runAdb(e.dependencies.android.hostAdbInvocation([`disconnect`,t]),{allowFailure:!0,timeoutMs:1e4}).catch(()=>{})),e.adbTunnel?.close(),e.adbTunnel=void 0,e.adbSerial=void 0,e.adbTunnelPromise=void 0}async function v(e){let t=e.adbProvider.reverse;if(!t?.list)return;let n=await t.list().catch(()=>[]),r=new Set,i=[],a=e.ownership===`attached`;for(let e of n)e.ownerId?r.add(e.ownerId):a||i.push(e.local);await Promise.allSettled([...[...r].map(async e=>await t.removeAllOwned(e)),...i.map(async e=>await t.remove(e))])}async function y(e,t,n){let{invocation:r,result:i}=await b(e,t,n);return await x(r,i,n?.allowFailure,e.dependencies)}async function b(e,t,n){let r=await S(e),i=e.dependencies.android.deviceAdbInvocation(r,t);return{invocation:i,result:await e.dependencies.host.runAdb(i,{allowFailure:n?.allowFailure,binaryStdout:n?.binaryStdout,stdin:n?.stdin,timeoutMs:n?.timeoutMs??3e4,signal:n?.signal})}}async function x(e,t,n,r){if(t.exitCode!==0&&n!==!0)throw await r.android.adbError(`Limrun Android ADB command failed`,t,e);return t}async function S(e){if(e.adbSerial)return e.adbSerial;let t=e.adbTunnelPromise??C(e);e.adbTunnelPromise=t;try{return await t}catch(n){throw e.adbTunnelPromise===t&&(e.adbTunnelPromise=void 0),n}}async function C(e){let t=await e.client.startAdbTunnel(),n=`${t.address.address}:${t.address.port}`;return e.adbTunnel=t,e.adbSerial=n,n}function w(e){if(!Number.isInteger(e)||e<1||e>65535)throw new t(`INVALID_ARGS`,`Invalid Android tcp reverse port: ${e}`);return`tcp:${e}`}function T(e,t){let n=u.extname(t)||`.apk`;return`${e?.replaceAll(/[^a-zA-Z0-9_.-]+/g,`-`)||`android-app`}${n}`}async function E(e,t){let n=await i({apiUrl:e.apiUrl,token:e.token,logLevel:`warn`});return{platform:`ios`,lease:e.lease,instanceId:e.instanceId,ownership:e.ownership,device:e.device,client:n,token:e.token,dependencies:t}}async function D(e,t,n,r,i,a){i?.throwIfAborted();let s=await j(n,t.dependencies);try{i?.throwIfAborted();let n=await o(a,e.assets.getOrUpload({path:s.uploadPath,name:s.assetName},{signal:i}),i),c=(await O(t,n.signedDownloadUrl,{md5:n.md5,relaunch:r?.relaunch,appIdentifierHint:r?.appIdentifierHint},i,a)).appId;return{...c?{bundleId:c,launchTarget:c}:{},...s.appName?{appName:s.appName}:{}}}finally{await s.cleanup()}}async function O(e,n,r,i,a){i?.throwIfAborted();let s=await o(a,e.client.listApps(),i).catch(e=>{if(i?.aborted)throw e}),c=f((await o(a,e.client.installApp(n,{md5:r?.md5,launchMode:r?.relaunch?`RelaunchIfRunning`:`ForegroundIfRunning`}),i)).bundleId),l=f(r?.appIdentifierHint),u=[];for(let t of N){t>0&&await d(t,void 0,{signal:i}),u=await o(a,e.client.listApps(),i);let n=I({resultBundleId:c,requestedBundleId:l,beforeInstallApps:s,afterInstallApps:u});if(n)return{appId:n}}throw new t(`COMMAND_FAILED`,`Limrun iOS app installation could not be verified.`,{resultBundleId:c,requestedBundleId:l,installedUserApps:u.filter(R).map(e=>e.bundleId).sort()})}function k(e){return new A(e)}var A=class{session;constructor(e){this.session=e}async open(e,t){if(t?.url){await this.launch(e,t.launchArgs),await this.session.client.openUrl(t.url);return}if(n(e)){await this.session.client.openUrl(e);return}await this.launch(e,t?.launchArgs)}async launch(e,n=[]){let r=await this.session.dependencies.ios.resolveAppAlias(e);if(n.length===0){await this.session.client.launchApp(r);return}let i=await this.session.client.simctl([`launch`,`--terminate-running-process`,`booted`,r,...n]).wait();if(i.code!==0)throw new t(`COMMAND_FAILED`,`Limrun iOS could not launch ${r} with arguments.`,{bundleId:r,exitCode:i.code,stderr:i.stderr.trim()})}async openDevice(){}async close(e){e&&await this.session.client.terminateApp(await this.session.dependencies.ios.resolveAppAlias(e)).catch(()=>{})}async tap(e,t){await this.session.client.tap(e,t)}async tapElementSelector(e){await this.session.client.tapElement(s(e))}async doubleTap(e,t){await this.session.client.performActions([{type:`tap`,x:e,y:t},{type:`wait`,durationMs:F},{type:`tap`,x:e,y:t}])}async longPress(e,t,n=P){await this.session.client.performActions([{type:`touchDown`,x:e,y:t},{type:`wait`,durationMs:n},{type:`touchUp`,x:e,y:t}])}async focus(e,t){await this.tap(e,t)}async type(e,t){await this.enterText(e,t)}async fill(e,t,n,r){let{awaitLimrunTextEntryFocus:i,readLimrunUnambiguousTapTargets:a,readLimrunTextEntryFocus:o}=await import(`./text-entry-focus.js`),s=a(await this.session.client.elementTree(),e,t);await this.tap(e,t);let c=await i({targetsAtPoint:s,readFocus:async()=>o(await this.session.client.elementTree()),sleep:e=>d(e),x:e,y:t});return await this.session.client.pressKey(`a`,[`command`]),n.length===0?(await this.session.client.pressKey(`delete`),{textEntryReadiness:c}):(await this.enterText(n,r),{textEntryReadiness:c})}async enterText(t,n){if(n&&n>0){let r=0;try{for(let e of Array.from(t))await this.session.client.typeText(e,!1,{requireFocus:!1}),r+=1,await d(n)}catch(t){throw e(t,r)}return}await this.session.client.typeText(t,!1,{requireFocus:!1})}async scroll(e,t){await this.session.client.scroll(e,t?.pixels??300)}async screenshot(e){let{transcodeScreenshotToPngAsync:t}=await import(`./png-worker-client.js`).then(e=>e.s),n=await this.session.client.screenshot(),r=await t(Buffer.from(n.base64,`base64`),`Limrun iOS screenshot`);c.mkdirSync(u.dirname(e),{recursive:!0}),await c.promises.writeFile(e,r)}async snapshot(){let{captureLimrunIosSnapshot:e}=await import(`./ios-snapshot-adapter.js`);return await e(this.session)}async back(){await this.session.client.pressKey(`escape`)}async setOrientation(e){if(e===`portrait-upside-down`)throw z(`orientation`,`Limrun iOS direct sessions support portrait and landscape orientation, not portrait upside-down.`);await this.session.client.setOrientation(e===`portrait`?`Portrait`:`Landscape`)}async setSetting(e,t,n,r){let{setLimrunIosSetting:i}=await import(`./ios-settings.js`);return await i(this.session,e,t,n,r)}};async function j(e,t){if(!(await c.promises.stat(e)).isDirectory())return{uploadPath:e,assetName:u.basename(e),appName:M(e),cleanup:async()=>{}};let n=await c.promises.mkdtemp(u.join(l.tmpdir(),`agent-device-limrun-ios-app-`)),r=u.join(n,`${u.basename(e)}.zip`);try{await t.host.archiveDirectory({sourceDirectory:u.dirname(e),entryName:u.basename(e),archivePath:r})}catch(e){throw await c.promises.rm(n,{recursive:!0,force:!0}),e}return{uploadPath:r,assetName:u.basename(r),appName:await t.ios.readBundleAppName(e)??M(e),cleanup:async()=>{await c.promises.rm(n,{recursive:!0,force:!0})}}}function M(e){return u.basename(e).replace(/\.(?:app|ipa|apk|aab|zip)$/i,``)||void 0}const N=[0,250],P=800,F=80;function I(e){let t=new Set(e.afterInstallApps.map(e=>e.bundleId));return(e.resultBundleId&&t.has(e.resultBundleId)?e.resultBundleId:void 0)??(e.requestedBundleId&&t.has(e.requestedBundleId)?e.requestedBundleId:void 0)??L(e.beforeInstallApps,e.afterInstallApps)}function L(e,t){if(!e)return;let n=new Set(e.map(e=>e.bundleId)),r=t.filter(e=>R(e)&&!n.has(e.bundleId));return r.length===1?r[0]?.bundleId:void 0}function R(e){return!e.bundleId.startsWith(`com.apple.`)&&!e.installType.toLowerCase().includes(`system`)}function z(e,n){throw new t(`UNSUPPORTED_OPERATION`,n,{command:e})}function B(e){return e.platform===`android`?V(e):H(e)}function V(e){let t=e.adbProvider.exec;return{platform:`android`,device:e.device,interactor:m(e),adb:e.adbProvider,listApps:async n=>await e.dependencies.android.listApps(t,r(n)),getForegroundApp:async n=>await e.dependencies.android.getForegroundApp(e.device,t,n),pressKey:async(t,n)=>{await e.client.pressKey(t,n)},getKeyboardState:async()=>await e.dependencies.android.getKeyboardState(t),dismissKeyboard:async()=>await e.dependencies.android.dismissKeyboard(t),readLogs:async n=>await e.dependencies.android.readLogs(t,n),...U(e.client,e.token,e.dependencies.host),installRemoteApp:async t=>{await e.client.sendAsset(t)}}}function H(e){return{platform:`ios`,device:e.device,interactor:k(e),viewport:{width:e.client.deviceInfo.screenWidth,height:e.client.deviceInfo.screenHeight},listApps:async t=>(await e.client.listApps()).filter(e=>r(t)===`all`||R(e)).map(e=>({id:e.bundleId,name:e.name,installType:e.installType})).sort((e,t)=>e.id.localeCompare(t.id)),pressKey:async(t,n)=>{await e.client.pressKey(t,n)},readLogs:async(t,n)=>await e.client.appLogTail(t,n),...U(e.client,e.token,e.dependencies.host),installRemoteApp:async(t,n)=>await O(e,t,n),runSimctl:t=>e.client.simctl(t)}}function U(e,t,n){return{startRecording:async t=>{await e.startRecording(t)},stopRecording:async()=>({downloadUrl:await e.stopRecording({})}),downloadRecording:async e=>{await n.downloadFile({url:e.downloadUrl,headers:{Authorization:`Bearer ${t}`},destinationPath:e.outPath,timeoutMs:6e4})}}}export{_ as a,p as c,D as i,h as l,k as n,g as o,E as r,m as s,B as t};
|
|
1
|
+
import{B as e,P as t}from"./sdk-contracts.js";import{i as n}from"./sdk-batch-runner.js";import{n as r}from"./app-inventory.js";import"./device.js";import{t as i}from"./ios-client.js";import{t as a}from"./instance-client.js";import{t as o}from"./request-cancellation.js";import{i as s}from"./snapshot.js";import c from"node:fs";import l from"node:os";import u from"node:path";import{setTimeout as d}from"node:timers/promises";function f(e){return e?.trim()||void 0}async function p(e,t){let n=await a({apiUrl:e.apiUrl,adbUrl:e.adbUrl,token:e.token,logLevel:`warn`}),r={platform:`android`,lease:e.lease,instanceId:e.instanceId,ownership:e.ownership,device:e.device,client:n,token:e.token,dependencies:t},i={exec:async(e,t)=>await y(r,e,t),text:async e=>{await n.setText(e.target,e.text)}};return i.reverse=await t.android.createPortReverse(i.exec,{noRebind:e.ownership===`attached`}),Object.assign(r,{adbProvider:i})}function m(e){return e.dependencies.android.createInteractor(e.device,e.adbProvider)}async function h(e,t,n,r,i,a){i?.throwIfAborted();let s=f(r?.packageNameHint);r?.relaunch&&s&&await t.dependencies.android.forceStopApp(async(e,n)=>await y(t,e,n),s,i);let c=await o(a,e.assets.getOrUpload({path:n,name:T(s,n)},{signal:i}),i);await o(a,t.client.sendAsset(c.signedDownloadUrl),i),i?.throwIfAborted();let l=s?await t.dependencies.android.inferAppName(s):void 0;return{...s?{packageName:s,launchTarget:s}:{},...l?{appName:l}:{}}}async function g(e,t){await e.adbProvider.reverse?.ensure({local:w(t.devicePort),remote:w(t.hostPort),ownerId:t.name})}async function _(e){await e.adbTunnelPromise?.catch(()=>{});let t=e.adbSerial;t&&(await v(e),await e.dependencies.host.runAdb(e.dependencies.android.hostAdbInvocation([`disconnect`,t]),{allowFailure:!0,timeoutMs:1e4}).catch(()=>{})),e.adbTunnel?.close(),e.adbTunnel=void 0,e.adbSerial=void 0,e.adbTunnelPromise=void 0}async function v(e){let t=e.adbProvider.reverse;if(!t?.list)return;let n=await t.list().catch(()=>[]),r=new Set,i=[],a=e.ownership===`attached`;for(let e of n)e.ownerId?r.add(e.ownerId):a||i.push(e.local);await Promise.allSettled([...[...r].map(async e=>await t.removeAllOwned(e)),...i.map(async e=>await t.remove(e))])}async function y(e,t,n){let{invocation:r,result:i}=await b(e,t,n);return await x(r,i,n?.allowFailure,e.dependencies)}async function b(e,t,n){let r=await S(e),i=e.dependencies.android.deviceAdbInvocation(r,t);return{invocation:i,result:await e.dependencies.host.runAdb(i,{allowFailure:n?.allowFailure,binaryStdout:n?.binaryStdout,stdin:n?.stdin,timeoutMs:n?.timeoutMs??3e4,signal:n?.signal})}}async function x(e,t,n,r){if(t.exitCode!==0&&n!==!0)throw await r.android.adbError(`Limrun Android ADB command failed`,t,e);return t}async function S(e){if(e.adbSerial)return e.adbSerial;let t=e.adbTunnelPromise??C(e);e.adbTunnelPromise=t;try{return await t}catch(n){throw e.adbTunnelPromise===t&&(e.adbTunnelPromise=void 0),n}}async function C(e){let t=await e.client.startAdbTunnel(),n=`${t.address.address}:${t.address.port}`;return e.adbTunnel=t,e.adbSerial=n,n}function w(e){if(!Number.isInteger(e)||e<1||e>65535)throw new t(`INVALID_ARGS`,`Invalid Android tcp reverse port: ${e}`);return`tcp:${e}`}function T(e,t){let n=u.extname(t)||`.apk`;return`${e?.replaceAll(/[^a-zA-Z0-9_.-]+/g,`-`)||`android-app`}${n}`}async function E(e,t){let n=await i({apiUrl:e.apiUrl,token:e.token,logLevel:`warn`});return{platform:`ios`,lease:e.lease,instanceId:e.instanceId,ownership:e.ownership,device:e.device,client:n,token:e.token,dependencies:t}}async function D(e,t,n,r,i,a){i?.throwIfAborted();let s=await j(n,t.dependencies);try{i?.throwIfAborted();let n=await o(a,e.assets.getOrUpload({path:s.uploadPath,name:s.assetName},{signal:i}),i),c=(await O(t,n.signedDownloadUrl,{md5:n.md5,relaunch:r?.relaunch,appIdentifierHint:r?.appIdentifierHint},i,a)).appId;return{...c?{bundleId:c,launchTarget:c}:{},...s.appName?{appName:s.appName}:{}}}finally{await s.cleanup()}}async function O(e,n,r,i,a){i?.throwIfAborted();let s=await o(a,e.client.listApps(),i).catch(e=>{if(i?.aborted)throw e}),c=f((await o(a,e.client.installApp(n,{md5:r?.md5,launchMode:r?.relaunch?`RelaunchIfRunning`:`ForegroundIfRunning`}),i)).bundleId),l=f(r?.appIdentifierHint),u=[];for(let t of N){t>0&&await d(t,void 0,{signal:i}),u=await o(a,e.client.listApps(),i);let n=I({resultBundleId:c,requestedBundleId:l,beforeInstallApps:s,afterInstallApps:u});if(n)return{appId:n}}throw new t(`COMMAND_FAILED`,`Limrun iOS app installation could not be verified.`,{resultBundleId:c,requestedBundleId:l,installedUserApps:u.filter(R).map(e=>e.bundleId).sort()})}function k(e){return new A(e)}var A=class{session;constructor(e){this.session=e}async open(e,t){if(t?.url){await this.launch(e,t.launchArgs),await this.session.client.openUrl(t.url);return}if(n(e)){await this.session.client.openUrl(e);return}await this.launch(e,t?.launchArgs)}async launch(e,n=[]){let r=await this.session.dependencies.ios.resolveAppAlias(e);if(n.length===0){await this.session.client.launchApp(r);return}let i=await this.session.client.simctl([`launch`,`--terminate-running-process`,`booted`,r,...n]).wait();if(i.code!==0)throw new t(`COMMAND_FAILED`,`Limrun iOS could not launch ${r} with arguments.`,{bundleId:r,exitCode:i.code,stderr:i.stderr.trim()})}async openDevice(){}async close(e){e&&await this.session.client.terminateApp(await this.session.dependencies.ios.resolveAppAlias(e)).catch(()=>{})}async tap(e,t){await this.session.client.tap(e,t)}async tapElementSelector(e){await this.session.client.tapElement(s(e))}async doubleTap(e,t){await this.session.client.performActions([{type:`tap`,x:e,y:t},{type:`wait`,durationMs:F},{type:`tap`,x:e,y:t}])}async longPress(e,t,n=P){await this.session.client.performActions([{type:`touchDown`,x:e,y:t},{type:`wait`,durationMs:n},{type:`touchUp`,x:e,y:t}])}async focus(e,t){await this.tap(e,t)}async type(e,t){await this.enterText(e,t)}async fill(e,t,n,r){let{awaitLimrunTextEntryFocus:i,readLimrunUnambiguousTapTargets:a,readLimrunTextEntryFocus:o}=await import(`./text-entry-focus.js`),s=a(await this.session.client.elementTree(),e,t);await this.tap(e,t);let c=await i({targetsAtPoint:s,readFocus:async()=>o(await this.session.client.elementTree()),sleep:e=>d(e),x:e,y:t});return await this.session.client.pressKey(`a`,[`command`]),n.length===0?(await this.session.client.pressKey(`delete`),{textEntryReadiness:c}):(await this.enterText(n,r),{textEntryReadiness:c})}async enterText(t,n){if(n&&n>0){let r=0;try{for(let e of Array.from(t))await this.session.client.typeText(e,!1,{requireFocus:!1}),r+=1,await d(n)}catch(t){throw e(t,r)}return}await this.session.client.typeText(t,!1,{requireFocus:!1})}async scroll(e,t){await this.session.client.scroll(e,t?.pixels??300)}async screenshot(e){let{transcodeScreenshotToPngAsync:t}=await import(`./png-worker-client.js`).then(e=>e.s),n=await this.session.client.screenshot(),r=await t(Buffer.from(n.base64,`base64`),`Limrun iOS screenshot`);c.mkdirSync(u.dirname(e),{recursive:!0}),await c.promises.writeFile(e,r)}async snapshot(){let{captureLimrunIosSnapshot:e}=await import(`./ios-snapshot-adapter.js`);return await e(this.session)}async back(){await this.session.client.pressKey(`escape`)}async home(){await this.session.client.performActions([{type:`buttonDown`,button:`home`},{type:`buttonUp`,button:`home`}])}async readClipboard(){return(await this.pasteboard([`pbpaste`,`booted`])).stdout.replaceAll(`\r
|
|
2
|
+
`,`
|
|
3
|
+
`).replace(/\n$/,``)}async writeClipboard(e){await this.pasteboard([`pbcopy`,`booted`],e)}async pasteboard(e,n){let r=await this.session.client.simctl(e,n===void 0?void 0:{stdin:n}).wait();if(r.code!==0)throw new t(`COMMAND_FAILED`,`Limrun iOS could not access the clipboard.`,{command:e[0],exitCode:r.code,stderr:r.stderr.trim()});return r}async setOrientation(e){if(e===`portrait-upside-down`)throw z(`orientation`,`Limrun iOS direct sessions support portrait and landscape orientation, not portrait upside-down.`);await this.session.client.setOrientation(e===`portrait`?`Portrait`:`Landscape`)}async setSetting(e,t,n,r){let{setLimrunIosSetting:i}=await import(`./ios-settings.js`);return await i(this.session,e,t,n,r)}};async function j(e,t){if(!(await c.promises.stat(e)).isDirectory())return{uploadPath:e,assetName:u.basename(e),appName:M(e),cleanup:async()=>{}};let n=await c.promises.mkdtemp(u.join(l.tmpdir(),`agent-device-limrun-ios-app-`)),r=u.join(n,`${u.basename(e)}.zip`);try{await t.host.archiveDirectory({sourceDirectory:u.dirname(e),entryName:u.basename(e),archivePath:r})}catch(e){throw await c.promises.rm(n,{recursive:!0,force:!0}),e}return{uploadPath:r,assetName:u.basename(r),appName:await t.ios.readBundleAppName(e)??M(e),cleanup:async()=>{await c.promises.rm(n,{recursive:!0,force:!0})}}}function M(e){return u.basename(e).replace(/\.(?:app|ipa|apk|aab|zip)$/i,``)||void 0}const N=[0,250],P=800,F=80;function I(e){let t=new Set(e.afterInstallApps.map(e=>e.bundleId));return(e.resultBundleId&&t.has(e.resultBundleId)?e.resultBundleId:void 0)??(e.requestedBundleId&&t.has(e.requestedBundleId)?e.requestedBundleId:void 0)??L(e.beforeInstallApps,e.afterInstallApps)}function L(e,t){if(!e)return;let n=new Set(e.map(e=>e.bundleId)),r=t.filter(e=>R(e)&&!n.has(e.bundleId));return r.length===1?r[0]?.bundleId:void 0}function R(e){return!e.bundleId.startsWith(`com.apple.`)&&!e.installType.toLowerCase().includes(`system`)}function z(e,n){throw new t(`UNSUPPORTED_OPERATION`,n,{command:e})}function B(e){return e.platform===`android`?V(e):H(e)}function V(e){let t=e.adbProvider.exec;return{platform:`android`,device:e.device,interactor:m(e),adb:e.adbProvider,listApps:async n=>await e.dependencies.android.listApps(t,r(n)),getForegroundApp:async n=>await e.dependencies.android.getForegroundApp(e.device,t,n),pressKey:async(t,n)=>{await e.client.pressKey(t,n)},getKeyboardState:async()=>await e.dependencies.android.getKeyboardState(t),dismissKeyboard:async()=>await e.dependencies.android.dismissKeyboard(t),readLogs:async n=>await e.dependencies.android.readLogs(t,n),...U(e.client,e.token,e.dependencies.host),installRemoteApp:async t=>{await e.client.sendAsset(t)}}}function H(e){return{platform:`ios`,device:e.device,interactor:k(e),viewport:{width:e.client.deviceInfo.screenWidth,height:e.client.deviceInfo.screenHeight},listApps:async t=>(await e.client.listApps()).filter(e=>r(t)===`all`||R(e)).map(e=>({id:e.bundleId,name:e.name,installType:e.installType})).sort((e,t)=>e.id.localeCompare(t.id)),pressKey:async(t,n)=>{await e.client.pressKey(t,n)},readLogs:async(t,n)=>await e.client.appLogTail(t,n),...U(e.client,e.token,e.dependencies.host),installRemoteApp:async(t,n)=>await O(e,t,n),runSimctl:t=>e.client.simctl(t)}}function U(e,t,n){return{startRecording:async t=>{await e.startRecording(t)},stopRecording:async()=>({downloadUrl:await e.stopRecording({})}),downloadRecording:async e=>{await n.downloadFile({url:e.downloadUrl,headers:{Authorization:`Bearer ${t}`},destinationPath:e.outPath,timeoutMs:6e4})}}}export{_ as a,p as c,D as i,h as l,k as n,g as o,E as r,m as s,B as t};
|
package/dist/src/device.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{g as e,h as t,w as n}from"./sdk-device.js";const r=[`android`,`harmonyos`,`apple`,`vega`,`linux`];function i(e){let{booted:t,kind:n,...r}=e;return r}const a={platform:`web`,id:`agent-browser-chrome`,name:`Agent Browser Chrome`,kind:`device`,target:`desktop`,booted:!0};function o(e){let t=c();for(let n of e){let e=l(n);t[e].available+=1,n.booted===!0&&(t[e].booted+=1)}return t}function s(e,t){return e.filter(e=>n(e,t.platform)&&(t.target===void 0||(e.target??`mobile`)===t.target)&&(t.kind===void 0||e.kind===t.kind)&&(t.booted===void 0||e.booted===t.booted))}function c(){return{android:{available:0,booted:0},harmonyos:{available:0,booted:0},apple:{available:0,booted:0},vega:{available:0,booted:0},linux:{available:0,booted:0},web:{available:0,booted:0}}}function l(n){return t(n)||e(n)?`apple`:n.platform}const u=new Set([`DEVICE_CLAIM_LIVE_OWNER`,`DEVICE_CLAIM_RECOVERY_PENDING`,`DEVICE_CLAIM_OWNER_UNCERTAIN`]);function d(e){return u.has(e)}export{d as a,s as i,a as n,i as o,o as r,r as t};
|
package/dist/src/device2.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createHash as e}from"node:crypto";const t=`limrun`,n={provider:t,label:`Limrun`,fields:{providerApp:`consumed`,providerOsVersion:`refused`,providerProject:`refused`,providerBuild:`refused`,providerSessionName:`refused`,providerDeviceOrientation:`refused`,providerGeoLocation:`refused`,providerTimezone:`refused`,providerAppiumVersion:`refused`,providerLanguage:`refused`,providerLocale:`refused`,providerNetworkProfile:`refused`,providerCustomNetwork:`refused`,providerNoResignApp:`refused`,awsProjectArn:`refused`,awsDeviceArn:`refused`,awsAppArn:`refused`,awsRegion:`refused`,awsInteractionMode:`refused`}},r=t;function i(e){if(e===`ios-instance`)return`ios`;if(e===`android-instance`)return`android`}function a(e,t,n){return{platform:e===`ios`?`apple`:`android`,...e===`ios`?{appleOs:`ios`}:{},id:c(e,t.leaseId),name:`Limrun ${e} ${n.slice(0,8)}`,kind:e===`ios`?`simulator`:`emulator`,target:`mobile`,booted:!0}}function o(t){return`attached-${e(`sha256`).update(t).digest(`hex`).slice(0,12)}`}function s(e){let[t,n,i]=e.split(`:`);if(t===r&&(n===`ios`||n===`android`)&&i)return{platform:n,leaseId:i}}function c(e,t){return`${r}:${e}:${t}`}function l(e){let t=s(e.id);return!t||e.target!==`mobile`?!1:t.platform===`ios`?u(e):d(e)}function u(e){return e.platform===`apple`&&e.appleOs===`ios`&&e.kind===`simulator`&&e.iosPhysicalDeviceBackend===void 0}function d(e){return e.platform===`android`&&e.appleOs===void 0&&e.kind===`emulator`&&e.iosPhysicalDeviceBackend===void 0}export{l as a,a as i,t as n,s as o,o as r,i as s,n as t};
|
|
1
|
+
import{createHash as e}from"node:crypto";const t=`limrun`,n={provider:t,label:`Limrun`,fields:{providerApp:`consumed`,providerOsVersion:`refused`,providerDeviceType:`refused`,providerProject:`refused`,providerBuild:`refused`,providerSessionName:`refused`,providerDeviceOrientation:`refused`,providerGeoLocation:`refused`,providerTimezone:`refused`,providerAppiumVersion:`refused`,providerLanguage:`refused`,providerLocale:`refused`,providerNetworkProfile:`refused`,providerCustomNetwork:`refused`,providerNoResignApp:`refused`,awsProjectArn:`refused`,awsDeviceArn:`refused`,awsAppArn:`refused`,awsRegion:`refused`,awsInteractionMode:`refused`}},r=t;function i(e){if(e===`ios-instance`)return`ios`;if(e===`android-instance`)return`android`}function a(e,t,n){return{platform:e===`ios`?`apple`:`android`,...e===`ios`?{appleOs:`ios`}:{},id:c(e,t.leaseId),name:`Limrun ${e} ${n.slice(0,8)}`,kind:e===`ios`?`simulator`:`emulator`,target:`mobile`,booted:!0}}function o(t){return`attached-${e(`sha256`).update(t).digest(`hex`).slice(0,12)}`}function s(e){let[t,n,i]=e.split(`:`);if(t===r&&(n===`ios`||n===`android`)&&i)return{platform:n,leaseId:i}}function c(e,t){return`${r}:${e}:${t}`}function l(e){let t=s(e.id);return!t||e.target!==`mobile`?!1:t.platform===`ios`?u(e):d(e)}function u(e){return e.platform===`apple`&&e.appleOs===`ios`&&e.kind===`simulator`&&e.iosPhysicalDeviceBackend===void 0}function d(e){return e.platform===`android`&&e.appleOs===void 0&&e.kind===`emulator`&&e.iosPhysicalDeviceBackend===void 0}export{l as a,a as i,t as n,s as o,o as r,i as s,n as t};
|
package/dist/src/device3.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{P as e}from"./sdk-contracts.js";import{
|
|
1
|
+
import{P as e}from"./sdk-contracts.js";import{E as t}from"./sdk-device.js";import{s as n}from"./device-shell.js";import{i as r,n as i,t as a}from"./device-claim-inspection.js";import{t as o}from"./shared.js";const s=async({positionals:t,flags:n})=>{if(t.length!==1||t[0]!==`status`&&t[0]!==`release`)throw new e(`INVALID_ARGS`,`device accepts only: status, release`);if(t[0]===`release`)return await c(n);let s=r({platform:n.platform,device:n.device,udid:n.udid,serial:n.serial}),l=s.filter(e=>i(e.classification)),u=(n.stale?l:s.filter(e=>!i(e.classification))).map(m),d={claims:u,...n.stale?{}:{hiddenStaleClaims:l.length}};return await o(n,d,()=>g(u,{staleOnly:n.stale===!0,hiddenStaleClaims:l.length,staleCommand:x(n,`status`),releasableClaims:l.filter(e=>a(e.classification)).length,releaseCommand:x(n,`release`)})),!0};async function c(t){if(t.stale!==!0)throw new e(`INVALID_ARGS`,`device release only releases provably stale claims; pass --stale to confirm.`,{hint:`A live owner is released by closing its session from its own workspace, or by stopping its daemon: agent-device daemon stop --state-dir <owner state dir>.`});let{runStaleDeviceClaimRelease:n}=await import(`./device-release.js`),r=await n({platform:t.platform,device:t.device,udid:t.udid,serial:t.serial}),i={released:r.filter(e=>e.status===`released`).map(l),retained:r.filter(e=>e.status===`retained`).map(l),refused:r.filter(e=>e.status===`refused`).map(l),changed:r.filter(e=>e.status===`changed`).map(l)};return await o(t,i,()=>u(r)),!0}function l(e){let{device:t,...n}=e;return{...n,...t?{device:h(t)}:{}}}function u(e){return e.length===0?`No local device claims matched.`:e.map(d).join(`
|
|
2
2
|
`)}function d(e){let n=e.device?`${t({platform:e.device.family,appleOs:e.device.appleOs})} ${e.device.name}`:e.deviceKey??e.fileName,r=f(e);switch(e.status){case`released`:return`released ${n}${r}`;case`retained`:return`retained ${n}${r} — resources not settled (${e.reason}); the claim stays until they are.`;case`refused`:return`refused ${n}${r} — ${e.reason} (${e.classification}); ${p(e)}`;case`changed`:return`changed ${n} — the claim changed while releasing; re-run device status.`}}function f(e){return e.allocator?` allocator=${e.allocator.instanceId} incarnation=${e.allocator.identityIncarnationId}`:e.session?` session=${e.session} workspace=${e.workspace}`:``}function p(e){return e.classification===`allocator-held`?`held by its managed-device allocator; it is cleared only after the allocator proves the identity removed.`:e.classification===`live`||e.classification===`owner-state-dir-gone`?e.stateDir?`close the owning session from its workspace, or stop its daemon: agent-device daemon stop --state-dir ${n(e.stateDir)}`:`close the owning session from its workspace first.`:`only provably dead owners are released; nothing was changed.`}function m(e){let t=e.claim??e.allocatorClaim;return{...e.deviceKey?{deviceKey:e.deviceKey}:{},...t?{}:{fileName:e.fileName},classification:e.classification,...t?{device:h(t.device)}:{},...e.claim?{owner:{session:e.claim.session,workspace:e.claim.workspace,stateDir:e.claim.stateDir,pid:e.claim.ownerPid,startTime:e.claim.ownerStartTime}}:{},...e.allocatorClaim?{owner:{kind:`allocator`,stateDir:e.allocatorClaim.stateDir,allocator:e.allocatorClaim.allocator}}:{},...e.error?{error:e.error}:{}}}function h(e){let{family:n,...r}=e;return{...r,platform:t({platform:n,appleOs:e.appleOs})}}function g(e,t){let n=e.map(v);if(n.length===0){if(t.staleOnly)return`No stale local device claims found.`;if(t.hiddenStaleClaims===0)return`No local device claims found.`}return[...n.length===0?[`No live local device claims found.`]:n,..._(t)].join(`
|
|
3
3
|
`)}function _(e){if(e.staleOnly)return e.releasableClaims>0?[`Release provably dead owners with: ${e.releaseCommand}`]:[];if(e.hiddenStaleClaims===0)return[];let t=e.hiddenStaleClaims===1?`claim`:`claims`;return[`${e.hiddenStaleClaims} stale ${t} hidden; inspect with: ${e.staleCommand}`]}function v(e){return`${y(e)}: ${e.classification}${b(e.owner)}`}function y(e){let t=e.device;return t?`${t.platform??`unknown`} ${t.name??t.id??`claim`}`:String(e.deviceKey??e.fileName??`claim`)}function b(e){if(!e||typeof e!=`object`)return``;let t=e;return t.allocator?` allocator=${t.allocator.instanceId} incarnation=${t.allocator.identityIncarnationId} installation=${t.stateDir}`:` session=${t.session} workspace=${t.workspace}`}function x(e,t){let r=[e.platform?`--platform ${n(e.platform)}`:null,e.device?`--device ${n(e.device)}`:null,e.udid?`--udid ${n(e.udid)}`:null,e.serial?`--serial ${n(e.serial)}`:null].filter(e=>!!e);return[`agent-device device ${t}`,...r,`--stale`].join(` `)}export{s as deviceCommand};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{P as e,it as t}from"./sdk-contracts.js";import{v as n}from"./sdk-batch-runner.js";import{a as r,c as i,r as a}from"./diagnostics.js";import"./diagnostics2.js";import{E as o,a as s,d as c,i as l,l as ee,n as te,w as ne}from"./sdk-device.js";import{$n as re,S as ie,er as ae,ln as u,m as oe,sn as se}from"./sdk-batch.js";import{t as ce}from"./recording-scope.js";import{a as le}from"./scroll-gesture.js";import{_ as d,c as ue,d as de,g as fe,h as pe,i as me,l as he,m as ge,o as _e,p as f,s as ve,u as p,y as ye}from"./script.js";import{C as be,D as xe,E as Se,F as Ce,M as we,O as Te,P as Ee,S as De,T as Oe,a as ke,b as Ae,d as je,i as Me,j as Ne,k as Pe,l as Fe,o as Ie,r as Le,s as Re,v as m,w as h,x as ze,y as Be}from"./provider-device-admission.js";import{n as g,t as _}from"./catalog.js";import{o as Ve,t as v}from"./back-mode.js";import{t as He}from"./session.js";import{r as Ue}from"./success-text.js";import{t as We}from"./click-button.js";import"./device.js";import{r as Ge,t as Ke}from"./device-rotation.js";import{A as qe}from"./owner-identity.js";import"./file.js";import{t as Je}from"./tv-remote.js";import{n as Ye,r as Xe,t as Ze}from"./session-paths.js";import{i as Qe,n as $e,r as et}from"./session-artifact-paths.js";import{i as tt,r as nt,t as rt}from"./session-repair-tombstone.js";import{t as it}from"./keyboard-actions.js";import{n as at,r as ot}from"./device-isolation.js";import{a as st,i as ct,r as lt}from"./device-inventory-context.js";import{AsyncLocalStorage as ut}from"node:async_hooks";import{createHash as dt}from"node:crypto";import y from"node:fs";import b from"node:path";import{StringDecoder as ft}from"node:string_decoder";function pt(e,t={}){let n=[e.command];return e.command===`snapshot`?de(n,e):e.command===`open`?me(n,e):e.command===`runtime`?ue(n,e,{includeAllPositionals:t.runtimeIncludeAllPositionals}):e.command===`record`?ve(n,e):e.command===`screenshot`?he(n,e):_e(n,e),n.join(` `)}function mt(e){return e.targetEvidences?[re(e.targetEvidences)]:e.targetEvidence?[ae(e.targetEvidence)]:[]}function x(e){return e?.scriptPublication??m}function ht(e,t){let n=x(e),r=typeof t.saveScript==`string`?Ze(t.saveScript):n.kind===`repair`?void 0:t.healedSiblingPath;e.scriptPublication=Ae(n,{requested:{path:r,force:t.force===!0},boundary:t.firstArm?e.actions.length:0,sourcePath:t.sourcePath})}function gt(e){e.scriptPublication=De(x(e))}function _t(e){e.scriptPublication=Se(x(e))}function vt(e,t){e.scriptPublication=xe(x(e),t)}function yt(e){e.scriptPublication=Be(x(e))}function bt(e,t){let n=x(e);return n.kind===`repair`&&n.closeReceipt===t}function xt(e){return x(e).kind===`repair`}function St(e){return Oe(x(e))}function S(e){return Te(x(e))}function Ct(e){return Pe(x(e))}function wt(e,t){if(t.flags?.noRecord||Pt(e,t))return;t.flags&&Fe(e,t.flags);let n=Et(t),r=kt(e,Dt(t,n));n&&Ot(e,n);let i={ts:Date.now(),command:r.command,positionals:r.positionals,runtime:r.runtime,flags:It(r.flags),result:r.result,...r.targetEvidence?{targetEvidence:r.targetEvidence}:{},...r.targetEvidences?{targetEvidences:r.targetEvidences}:{}};return e.actions.push(i),a({level:`debug`,phase:`record_action`,data:{command:t.command,session:e.name}}),i}function Tt(e,t,n,r,i,a){!t||!e.resolveCurrent(t)||e.recordAction(t,{command:r,positionals:a?.positionals??n.positionals??[],flags:a?.flags??n.flags??{},result:i??{}})}function Et(e){if(e.command!==`fill`||typeof e.flags.recordAs!=`string`)return;let t=Ce(e.flags.recordAs),n=Ee(t);return{literal:we({ts:0,command:e.command,positionals:e.positionals,flags:e.flags}),placeholder:n}}function Dt(e,t){if(!t)return e;let{literal:n,placeholder:r}=t;return{...e,positionals:jt(e.positionals,r),result:Le(e.result,n,r),targetEvidence:Me(e.targetEvidence,n,r)}}function Ot(e,t){t.literal.trim()&&(e.recordedFillLiterals??=new Map,!e.recordedFillLiterals.has(t.literal)&&e.recordedFillLiterals.set(t.literal,t.placeholder))}function kt(e,t){let n=e.recordedFillLiterals;if(!n||n.size===0)return t;let r=ke(t.result,n),i=(t.targetEvidenceMode??`action`)===`landmark`?At(t.targetEvidence,n):C(t.targetEvidence,n),a=t.targetEvidences?{source:C(t.targetEvidences.source,n),destination:C(t.targetEvidences.destination,n)}:t.targetEvidences;return{...t,result:r,targetEvidence:i,targetEvidences:a}}function At(e,t){return e&&(Re(e,t)?void 0:e)}function C(e,t){return!e||!Re(e,t)?e:{...Ie(e,t),verification:`unverifiable`}}function jt(e,t){let n=e[0];return n?.startsWith(`@`)?e.length>=3?[n,e[1],t]:[n,t]:e.length>=3&&Number.isFinite(Number(e[0]))&&Number.isFinite(Number(e[1]))?[e[0],e[1],t]:n===void 0?[t]:[n,t]}const Mt=new Set([`snapshot`,`get`,`is`,`find`]);function Nt(e){return e.internal?.replayPlanStep!==!0&&Mt.has(e.command)}function Pt(e,t){return!t.interactiveObservation||S(e)===void 0?!1:t.flags?.record!==!0}const Ft=Ve();function It(e){if(!e)return{};let t={};for(let n of Ft){let r=e[n];r!==void 0&&(t[n]=r)}return t}function w(e){return b.join(e,`idle-expiry.json`)}function Lt(e){let t;try{t=y.readFileSync(e,`utf8`)}catch{return}let n;try{n=JSON.parse(t)}catch{return}if(!(typeof n?.expiresAt!=`number`||!Number.isFinite(n.expiresAt))&&!(n.expiresAt<=Date.now())&&typeof n.owner==`string`&&!(!Rt(n.expiredAtMs)||!Rt(n.idleExpiryMs))&&(n.deviceKey===void 0||typeof n.deviceKey==`string`))return n}function Rt(e){return typeof e==`number`&&Number.isFinite(e)&&e>=0}function zt(t){let n=t.flatMap((e,t)=>e.command===`open`?[t]:[]);if(n.length!==1||n[0]!==0)throw new e(`COMMAND_FAILED`,`Cannot publish this session: an open-to-destination script requires exactly one initial recorded open.`,{retriable:!1,hint:`Close this session and start a fresh one with open <app> --save-script[=<path>].`});if(t.some(e=>e.command===`close`))throw new e(`COMMAND_FAILED`,`Cannot publish an active-session script containing close.`,{retriable:!1,hint:`Close this session and record the journey again from a fresh open --save-script session.`});let r=-1;for(let[e,n]of t.entries())ie({command:n.command,positionals:n.positionals,flags:n.flags})===`mutates-app`&&(r=e);if(!t.slice(r+1).some(Gt))throw new e(`COMMAND_FAILED`,`Cannot publish this session without a portable destination guard after the final mutating action.`,{retriable:!0,hint:`Record a selector-targeted wait on a labeled or id-bearing landmark, for example wait 'role="heading" label="Screen X"', so its recorded identity is captured, then retry session save-script.`})}function Bt(t){for(let n of t){if(Vt(n)){Ht(n);continue}let t=Kt(n),r=t??(n.command===`wait`?n.positionals[0]:void 0);if(r?.startsWith(`@`))throw new e(`COMMAND_FAILED`,`Cannot publish recorded step "${n.command} ${r}": the session-local ref was not converted to a portable selector.`,{retriable:!1,hint:`Close this session and record the journey again using selectors or resolvable refs.`});if(n.command===`find`&&ie(n)===`mutates-app`)throw new e(`COMMAND_FAILED`,`Cannot publish a recorded mutating find step because its target identity is not replay-verifiable.`,{retriable:!1,hint:`Close this session and record the journey again with an explicit selector-targeted click, press, fill, or focus action.`});let i=t;if(!(!i||!u(i)||n.targetEvidence))throw new e(`COMMAND_FAILED`,`Cannot publish recorded step "${n.command} ${i}": recording-time target identity evidence is missing.`,{retriable:!1,hint:`Close this session and record the journey again from open --save-script so target-v1 evidence is captured before each interaction.`})}}function Vt(e){return Ut(e)!==void 0}function Ht(t){let n=Ut(t);if(!n)return;let r=[n.source,n.destination];for(let n of r){if(n?.startsWith(`@`))throw new e(`COMMAND_FAILED`,`Cannot publish recorded drag endpoint "${n}": the session-local ref was not converted to a portable selector.`,{retriable:!1});if(!(!n||!u(n))&&!t.targetEvidences)throw new e(`COMMAND_FAILED`,`Cannot publish recorded drag endpoint "${n}": recording-time target identity evidence is missing.`,{retriable:!1,hint:`Close this session and record the journey again so targets-v1 evidence is captured for both drag endpoints.`})}}function Ut(e){return e.command===`gesture`?ye(e.positionals):void 0}function Wt(t,n){if(t instanceof e){if(t.details?.reason===`script_target_exists`)return new e(t.code,`A file already exists at ${String(t.details.path)}.`,{...t.details,retriable:!0,hint:`Retry session save-script with another path, or pass --force to replace the existing file. The session remains armed.`});let n=t.details?.retriable===!0;return new e(t.code,t.message,{...t.details,retriable:n,hint:t.details?.hint??(n?`Fix the recorded journey or target, then retry session save-script. The session remains armed.`:`Close this session and start a fresh one with open <app> --save-script[=<path>].`)})}let r=t instanceof Error?t.message:String(t);return new e(`COMMAND_FAILED`,`Failed to publish the active session script${n?` to ${n}`:``}: ${r}`,{retriable:!0,hint:`Check the target path and permissions, then retry session save-script. The session remains armed.`})}function Gt(e){if(e.command!==`wait`)return!1;let t=se(e.positionals);return t?.kind!==`selector`||!u(t.selectorExpression)?!1:e.targetEvidence?.verification===`verified`}function Kt(e){if(e.command===`get`)return e.positionals[1];if(fe(e.command)||e.command===`fill`){let[t,n]=e.positionals;return t!==void 0&&n!==void 0&&qt(t)&&qt(n)?void 0:t}}function qt(e){return e.trim().length>0&&Number.isFinite(Number(e))}function Jt(e){let t=e.scriptPublication??m;return t.kind===`repair`?t.status===`committed`||!h(t):!1}function Yt(e){return!be(e.scriptPublication??m)||Jt(e)}var Xt=class{sessionsDir;constructor(e){this.sessionsDir=e}write(e,t){let n=xt(e),r=t?.publication===`active`,i;try{if(Yt(e))return{written:!1};let a=Zt(e,{appendCompleteSentinel:n,activePublication:r});i=this.resolveScriptPath(e);let o=b.dirname(i);return y.existsSync(o)||y.mkdirSync(o,{recursive:!0}),en({scriptPath:i,script:a.script,force:t?.force}),n&&(e.scriptPublication=ze(e.scriptPublication??m)),{written:!0,path:i,actionCount:a.actionCount}}catch(t){return Qt({session:e,error:t,scriptPath:i,repairArmed:n,activePublication:r})}}resolveScriptPath(e){let t=Ne(e.scriptPublication??m);if(t)return Ze(t);let n=Xe(e.name),r=new Date(e.createdAt).toISOString().replaceAll(/[:.]/g,`-`);return b.join(this.sessionsDir,`${n}-${r}.ad`)}};function Zt(e,t){let n=tn(e,{strictPortableRefs:t.activePublication});return t.activePublication&&zt(n),{script:fn(e,n,t.appendCompleteSentinel),actionCount:n.length}}function Qt(t){let{session:n,error:r,scriptPath:i,repairArmed:o,activePublication:s}=t;if(a({level:`warn`,phase:`session_script_write_failed`,data:{session:n.name,path:i,error:r instanceof Error?r.message:String(r)}}),o)return{written:!1,error:$t(r,i)};if(s)return{written:!1,error:Wt(r,i)};if(r instanceof e)throw r;return{written:!1}}function $t(t,n){if(t instanceof e)return t;let r=t instanceof Error?t.message:String(t);return new e(`COMMAND_FAILED`,`Failed to write the healed script${n?` to ${n}`:``}: ${r}`,{hint:`The repair transaction completed but the healed .ad could not be published; check the target path and permissions, then retry close --save-script.`})}function en(t){let{scriptPath:n,script:r,force:i}=t;try{qe({destination:n,contents:r,publish:i?`replace`:`link-exclusive`})}catch(t){throw t.code===`EEXIST`?new e(`COMMAND_FAILED`,`A file already exists at ${n}; remove it, pass replay --save-script=<other-path>, or pass --force/--overwrite to replace it.`,{reason:`script_target_exists`,path:n}):t}}function tn(e,t={}){let n=S(e),r=n!==void 0,i=e.actions.slice(n??0),a=[];for(let n of i){if(n.command===`snapshot`)continue;let i=an(n);if(i){a.push(i);continue}(r||t.strictPortableRefs)&&nn(n);let o=dn(e,n);o&&a.push(o),a.push(n)}return t.strictPortableRefs&&Bt(a),a}function nn(t){let n=t.command===`gesture`?ye(t.positionals??[]):void 0;if(n){rn(n);return}if(!T(t.command))return;let r=t.command===`get`?t.positionals?.[1]:t.positionals?.[0];if(r?.startsWith(`@`))throw new e(`COMMAND_FAILED`,`Cannot write recorded step "${t.command} ${r}" to a script: it never resolved to a selector, so the ref would not resolve in a fresh replay session.`)}function rn(t){let n=[t.source,t.destination].find(e=>e.startsWith(`@`));if(n)throw new e(`COMMAND_FAILED`,`Cannot write recorded drag endpoint "${n}" to a script: it never resolved to a selector, so the ref would not resolve in a fresh replay session.`)}function an(e){let t=on(e);if(!(!t||!T(e.command)))return pe(e.command)||e.command===`hover`?{...e,positionals:[t]}:e.command===`longpress`?cn(e,t):e.command===`fill`?sn(e,t):ln(e,t)}function on(e){let t=Array.isArray(e.result?.selectorChain)&&e.result.selectorChain.every(e=>typeof e==`string`)?e.result.selectorChain:[];return t.length>0?t.join(` || `):void 0}function T(e){return fe(e)||e===`fill`||e===`get`}function sn(e,t){let n=we(e);return n.length>0?{...e,positionals:[t,n]}:void 0}function cn(e,t){let n=typeof e.result?.durationMs==`number`?String(e.result.durationMs):un(e.positionals??[]);return{...e,positionals:n?[t,n]:[t]}}function ln(e,t){let n=e.positionals?.[0];return n===`text`||n===`attrs`?{...e,positionals:[n,t]}:void 0}function un(e){let t=e.at(-1);if(!(e.length<=1||t===void 0||t.trim()===``))return Number.isFinite(Number(t))?t:void 0}function dn(e,t){if(!T(t.command))return;let n=t.result?.refLabel;if(typeof n!=`string`||n.trim().length===0)return;let r=n.trim();return{ts:t.ts,command:`snapshot`,positionals:[],flags:{platform:e.device.platform,snapshotInteractiveOnly:!0,snapshotScope:r},result:{scope:r}}}function fn(e,t,n){let r=[],i=e.device.kind?` kind=${e.device.kind}`:``;r.push(`context platform=${ne(e.device)} device=${ge(e.device.name)}${i} theme=unknown`);for(let e of t)e.flags?.noRecord||(r.push(...mt(e)),r.push(pn(e)));return n&&r.push(`# agent-device:heal-complete`),`${r.join(`
|
|
2
|
-
`)}\n`}function pn(e){return mn([e.command],e)||pt(e)}function mn(e,t){if(pe(t.command))return hn(e,t);if(t.command===`fill`)return gn(e,t);if(t.command===`get`)return _n(e,t)}function hn(e,t){let n=t.positionals?.[0];if(n){if(n.startsWith(`@`))return e.push(f(d(n))),E(e,t),p(e,t),e.join(` `);if(t.positionals.length===1)return e.push(f(n)),p(e,t),e.join(` `)}}function gn(e,t){let n=t.positionals?.[0];if(!n?.startsWith(`@`))return;e.push(f(d(n))),E(e,t);let r=t.positionals.slice(1).join(` `);return t.positionals.length>1&&e.push(f(r)),p(e,t),e.join(` `)}function _n(e,t){let n=t.positionals?.[0],r=t.positionals?.[1];if(!(!n||!r))return e.push(f(n)),e.push(f(d(r))),r.startsWith(`@`)&&E(e,t),e.join(` `)}function E(e,t){let n=t.result?.refLabel;typeof n==`string`&&n.trim().length>0&&e.push(f(n))}const vn=[`id`,`deviceId`,`device_id`,`serial`,`udid`,`device_udid`,`identifier`],yn={ios:`iOS`,ipados:`iPadOS`,tvos:`tvOS`,watchos:`watchOS`,visionos:`visionOS`,macos:`macOS`,apple:`Apple`,android:`Android`,linux:`Linux`,web:`Web`};function bn(e,t){let n=t??{};switch(e.command){case g.devices:return xn(n.devices);case g.apps:return Sn(n.apps,e.flags?.appsFilter);case g.boot:return Cn(`Booted`,n,!0);case g.shutdown:return Cn(`Shut down`,n,!1);case g.install:return wn(`Installed`,n);case g.reinstall:return wn(`Reinstalled`,n);case g.screenshot:return Tn(e,n);default:return{}}}function xn(e){if(!Array.isArray(e))return{};let t=e.flatMap(e=>{let t=Dn(e);return t?[t]:[]}),n=t.slice(0,5),r=Math.max(0,t.length-n.length),i=t.slice(0,3);return{summary:In(`Found ${t.length} ${Ln(`device`,t.length)}`,i.map(e=>Pn(e,!0)),Math.max(0,t.length-i.length)),details:{deviceCount:t.length,devices:n,...r>0?{omittedDeviceCount:r}:{}}}}function Sn(e,t){if(!Array.isArray(e))return{};let n=e.flatMap(e=>{let t=k(e);return t?[t]:[]}),r=n.slice(0,5),i=Math.max(0,n.length-r.length),a=n.slice(0,3);return{summary:In(`Found ${n.length} ${Ln(`app`,n.length)}`,a,Math.max(0,n.length-a.length)),details:{appCount:n.length,apps:r,...i>0?{omittedAppCount:i}:{},...t===`all`||t===`user-installed`?{filter:t}:{}}}}function Cn(e,t,n){let r=On(t);if(!r)return{};let i={device:r,...Nn(t),booted:n};return{summary:`${e} ${Pn(i,!1)}`,details:i}}function wn(e,t){let n=k(t.appName),r=k(t.bundleId),i=D(t,[`packageName`,`package`]),a=k(t.platform),o=k(t.launchTarget),s=D(t,[`bundleId`,`packageName`,`package`,`appId`,`launchTarget`]),c=Fn(n,s);if(!c)return{};let l={};return O(l,`appName`,n),O(l,`bundleId`,r),O(l,`packageName`,i),O(l,`platform`,a),o!==s&&O(l,`launchTarget`,o),{summary:`${e} ${c}`,details:l}}function Tn(e,t){let n=En(e,t);return n?{details:{requestedFileName:n}}:{}}function En(e,t){let n=F(e.meta?.clientArtifactPaths?.path)??F(t.path);if(n)return P(n)}function Dn(e){if(!n(e))return;let t=On(e);if(t)return{name:t,...Nn(e)}}function On(e){let t=D(e,[`name`,`deviceName`,`device`]);return!t||!kn(e,t)?t:jn(e)}function kn(e,t){let n=An(t);return vn.some(t=>{let r=k(e[t]);return r!==void 0&&An(r)===n})}function An(e){return e.toLowerCase()}function jn(e){let t=k(e.appleOs),n=k(e.platform),r=k(e.kind),i=Mn(t,n);return i&&(r===`simulator`||r===`emulator`)?`${i} ${r}`:i?`${i} device`:r===`simulator`?`Simulator`:r===`emulator`?`Emulator`:`Unnamed device`}function Mn(e,t){let n=e??t;if(!(!n||!Object.hasOwn(yn,n)))return yn[n]}function Nn(e){let t=k(e.platform),n=k(e.appleOs),r=k(e.kind),i=k(e.target);return{...t?{platform:t}:{},...n?{appleOs:n}:{},...r?{kind:r}:{},...i?{target:i}:{},...typeof e.booted==`boolean`?{booted:e.booted}:{}}}function Pn(e,t){let n=k(e.name)??k(e.device)??`device`,r=k(e.platform),i=k(e.appleOs),a=[r,i===r?void 0:i,k(e.kind),k(e.target),t&&typeof e.booted==`boolean`?e.booted?`booted`:`stopped`:void 0].filter(e=>!!e);return a.length>0?`${n} (${a.join(`, `)})`:n}function Fn(e,t){return e&&t&&e!==t?`${e} (${t})`:e??t}function D(e,t){for(let n of t){let t=k(e[n]);if(t)return t}}function O(e,t,n){n&&(e[t]=n)}function In(e,t,n){let r=[...t,...n>0?[`+${n} more`]:[]];return r.length>0?`${e}: ${r.join(`, `)}`:e}function Ln(e,t){return t===1?e:`${e}s`}function k(e){let t=F(e);if(!t)return;let n=t.trim(),r=Array.from(n);return r.length<=120?n:`${r.slice(0,119).join(``)}…`}function A(e){return k(e)}function j(e){return typeof e==`boolean`?e:void 0}function M(e,t){let n=A(e);return n&&t.includes(n)?n:void 0}function N(e){return Object.fromEntries(Object.entries(e).filter(([,e])=>e!==void 0))}function P(e){let t=F(e);return t?k(t.split(/[\\/]/).at(-1)):void 0}function F(e){if(typeof e==`string`)return e.trim().length>0?e:void 0}function I(e){return typeof e==`number`&&Number.isFinite(e)?e:void 0}const Rn=[`up`,`down`,`left`,`right`],zn=[`top`,`bottom`];function Bn(e){return`${e.command===g.reinstall?`Reinstalled`:`Installed`} ${Wn(e.result??{})??`app`}`}function Vn(e){let t=e.result??{};switch(e.command){case g.scroll:return Kn(t);case g.screenshot:return Yn(t);case g.home:return`Went home`;case g.back:return Zn(t);case g.appSwitcher:return`Opened app switcher`;case g.actionButton:return`Pressed Action Button`;case g.orientation:return $n(t);case g.fold:return Qn(t);case g.viewport:return er(t);case g.clipboard:return tr(t);case g.keyboard:return nr(t);case g.tvRemote:return ar(t);case g.gesture:return or(t);case g.swipe:return sr(t);case g.trace:return lr(`trace`,e);case g.record:return lr(`recording`,e);default:return}}function Hn(e){let t=e.result??{};switch(e.command){case g.scroll:return N({direction:M(t.direction,Rn),edge:M(t.edge,zn),passes:I(t.passes),amount:I(t.amount),pixels:I(t.pixels),durationMs:I(t.durationMs),x1:I(t.x1),y1:I(t.y1),x2:I(t.x2),y2:I(t.y2)});case g.screenshot:return N({requestedFileName:Xn(t)});case g.back:return N({mode:M(t.mode,v)});case g.orientation:return N({orientation:M(t.orientation,Ke)});case g.fold:return N({pose:M(t.pose,Ge)});case g.viewport:return N({width:I(t.width),height:I(t.height)});case g.clipboard:return N({action:M(t.action,[`read`,`write`])});case g.keyboard:return ir(t);case g.tvRemote:return N({button:M(t.button,Je),durationMs:I(t.durationMs)});case g.gesture:case g.swipe:return cr(t);case g.trace:case g.record:return N({action:M(t.action,[`start`,`stop`]),fileName:dr(e),showTouches:j(t.showTouches)});default:return{}}}function Un(e,t){if(e.command!==g.screenshot)return t;let n=En(e,t);return n?{...t,requestedFileName:n}:t}function Wn(e){let t=A(e.appName),n=fr(e,[`bundleId`,`packageName`,`appBundleId`,`launchTarget`]);return t&&n&&t!==n?`${t} (${n})`:t??n??Gn(e)}function Gn(e){let t=A(e.app);return t&&!t.includes(`/`)&&!t.includes(`\\`)?t:void 0}function Kn(e){let t=M(e.direction,Rn),n=M(e.edge,zn),r=I(e.passes);return n?qn(n,r):t?Jn(t,e):`Scrolled`}function qn(e,t){return t===0?`Already at ${e}`:t===void 0?`Scrolled to ${e}`:`Scrolled to ${e} in ${t} ${t===1?`pass`:`passes`}`}function Jn(e,t){let n=I(t.pixels);if(n!==void 0)return`Scrolled ${e} by ${n}px`;let r=I(t.amount);return r===void 0?`Scrolled ${e}`:`Scrolled ${e} by ${r}`}function Yn(e){let t=Xn(e);return t?`Captured screenshot ${t}`:`Captured screenshot`}function Xn(e){return P(e.requestedFileName)??P(e.path)}function Zn(e){return M(e.mode,v)===`system`?`Went back using system navigation`:`Went back`}function Qn(e){let t=M(e.pose,Ge);return t?`Folded to ${t}`:`Changed fold pose`}function $n(e){let t=M(e.orientation,Ke);return t?j(e.confirmed)===!1?`Requested ${t} (unconfirmed)`:`Rotated to ${t}`:`Changed orientation`}function er(e){let t=I(e.width),n=I(e.height);return t!==void 0&&n!==void 0?`Set viewport to ${t}×${n}`:`Changed viewport`}function tr(e){let t=M(e.action,[`read`,`write`]);return t===`read`?`Read clipboard`:t===`write`?`Updated clipboard`:`Used clipboard`}function nr(e){let t=F(e.action);if(!t||!it(t))return`Used keyboard`;if(t===`dismiss`)return rr(e);if(t===`enter`||t===`return`)return`Pressed keyboard return`;let n=j(e.visible);return n===void 0?`Inspected keyboard`:n?`Keyboard is visible`:`Keyboard is hidden`}function rr(e){return j(e.dismissed)===!1?`Keyboard was already hidden`:`Dismissed keyboard`}function ir(e){let t=F(e.action);return N({action:t&&it(t)?t:void 0,platform:M(e.platform,[`ios`,`android`]),visible:j(e.visible),wasVisible:j(e.wasVisible),dismissed:j(e.dismissed),attempts:I(e.attempts),mechanism:M(e.mechanism,[`dismissKey`])})}function ar(e){let t=M(e.button,Je);return t?`Pressed TV remote ${t}`:`Used TV remote`}function or(e){let t=M(e.kind,[`fling`,`pan`,`pinch`,`rotate`,`transform`]);return t?`Ran ${t} gesture`:`Ran gesture`}function sr(e){let t=I(e.count);return t!==void 0&&t>1?`Swiped ${t} times`:`Swiped`}function cr(e){return N({kind:M(e.kind,[`fling`,`pan`,`pinch`,`rotate`,`transform`]),durationMs:I(e.durationMs),pointerCount:I(e.pointerCount),x1:I(e.x1),y1:I(e.y1),x2:I(e.x2),y2:I(e.y2),count:I(e.count),pauseMs:I(e.pauseMs),pattern:M(e.pattern,[`one-way`,`ping-pong`]),scale:I(e.scale)})}function lr(e,t){let n=ur(e,M(t.result?.action,[`start`,`stop`])),r=dr(t);return r?`${n} ${r}`:n}function ur(e,t){return t===`start`?e===`trace`?`Started trace`:`Started recording`:t===`stop`?e===`trace`?`Stopped trace`:`Stopped recording`:e===`trace`?`Updated trace`:`Updated recording`}function dr(e){let t=e.result??{};return P(t.requestedFileName)??P(t.outPath)??P(t.path)??P(e.positionals[1])}function fr(e,t){for(let n of t){let t=A(e[n]);if(t)return t}}function pr(e){switch(e.command){case g.open:return`Opened ${L(e)??`session`}`;case g.close:return`Closed ${A(e.result?.session)??`session`}`;case g.click:case g.press:return`Tapped ${L(e)??`target`}`;case g.longPress:return`Long pressed ${L(e)??`target`}`;case g.hover:return`Hovered ${L(e)??`target`}`;case g.fill:return`Filled ${L(e)??`target`}`;case g.type:return`Typed text`;case g.install:case g.reinstall:case _.installSource:return Bn(e);default:return Vn(e)??`Ran ${e.command}`}}function mr(e){return N({command:e.command,positionals:Cr(e),flags:Fr(e),...hr(e),...gr(e),..._r(e),...Hn(e)})}function hr(e){if(!vr(e.command))return{};let t=e.result??{};return N({ref:H(t),targetLabel:L(e),selectorChainLength:jr(t.selectorChain)?.length,x:I(t.x),y:I(t.y),x2:I(t.x2),y2:I(t.y2),durationMs:I(t.durationMs)})}function gr(e){if(!yr(e.command))return{};let t=e.result??{};return N({platform:M(t.platform,s),target:M(t.target,te),appName:A(t.appName),appBundleId:A(t.appBundleId),bundleId:A(t.bundleId),packageName:A(t.packageName),launchTarget:A(t.launchTarget)})}function _r(e){let t=e.result??{};return e.command===g.snapshot?Array.isArray(t.nodes)?{nodeCount:t.nodes.length}:{}:e.command!==g.wait&&e.command!==g.find&&e.command!==g.get&&e.command!==g.is?{}:N({waitedMs:I(t.waitedMs),found:j(t.found)})}function vr(e){return e===g.click||e===g.press||e===g.longPress||e===g.hover||e===g.focus||e===g.fill}function yr(e){return e===g.open||e===g.install||e===g.reinstall||e===_.installSource}function L(e){let t=e.result??{};return br(t)??xr(t)??Sr(t)??kr(e.positionals[0])}function br(e){let t=H(e);if(t)return t.startsWith(`@`)?t:`@${t}`}function xr(e){let t=I(e.x),n=I(e.y);if(t!==void 0&&n!==void 0)return`(${t}, ${n})`}function Sr(e){return A(e.appName)??A(e.appBundleId)??A(e.bundleId)??A(e.packageName)}function Cr(e){if(e.positionals.length!==0)return e.command===g.type?[z(`text`)]:e.command===g.fill?wr(e):e.command===g.find?Tr(e):e.command===g.clipboard?Er(e):e.command===g.push?Dr(e,`app`,`payload`):e.command===g.triggerAppEvent?Dr(e,`event`,`payload`):e.positionals.map(R)}function wr(e){let t=z(`text`),n=e.result??{},r=H(n);if(r)return[`@${r}`,t];if(A(n.selector))return[z(`target`),t];let i=I(n.x),a=I(n.y);return i!==void 0&&a!==void 0?[String(i),String(a),t]:[t]}function Tr(e){let t=+!!Ar(e.positionals[0]);if(e.positionals[t]===void 0)return;let n=t+1,r=[...t===1?[String(e.positionals[0])]:[],z(`query`)],i=e.positionals[n];return i?i===`fill`||i===`type`?[...r,i,z(`text`)]:[...r,...e.positionals.slice(n).map(Or)]:r}function Er(e){let t=e.positionals[0]?.toLowerCase();return t===`read`?[`read`]:t===`write`?[`write`,z(`text`)]:e.positionals.map(R)}function Dr(e,t,n){let[r,i,...a]=e.positionals;return[...r?[z(t)]:[],...i?[z(n)]:[],...a.map(R)]}function Or(e){return e===`click`||e===`focus`||e===`exists`||e===`get`||e===`text`||e===`attrs`||e===`wait`?e:R(e)}function R(e){return kr(e)??z(`arg`)}function kr(e){if(!e)return;let t=e.trim();if(/^@[a-zA-Z0-9:_-]+$/.test(t))return t}function z(e){return`<${e}>`}function Ar(e){return e===`text`||e===`label`||e===`value`||e===`role`||e===`id`}function jr(e){return Array.isArray(e)&&e.every(e=>typeof e==`string`)?e:void 0}const Mr={enums:[{source:`platform`,values:l},{source:`target`,values:te}]},Nr={booleans:[{source:`settle`}],numbers:[{source:`settleQuietMs`}]},Pr={[g.open]:{booleans:[{source:`relaunch`},{source:`testIme`}],enums:[{source:`surface`,values:He}]},[g.click]:B(),[g.press]:B(),[g.longPress]:B(),[g.hover]:B(),[g.fill]:Lr(),[g.type]:Lr(),[g.scroll]:{numbers:[{source:`pixels`},{source:`durationMs`}]},[g.gesture]:Rr(),[g.swipe]:Rr(),[g.screenshot]:{booleans:[{source:`overlayRefs`},{source:`screenshotFullscreen`,output:`fullscreen`},{source:`screenshotNoStabilize`,output:`noStabilize`},{source:`screenshotNormalizeStatusBar`,output:`normalizeStatusBar`}],numbers:[{source:`screenshotPixelDensity`,output:`pixelDensity`},{source:`screenshotScale`,output:`scale`}]},[g.snapshot]:{booleans:[{source:`snapshotInteractiveOnly`,output:`interactiveOnly`},{source:`snapshotDiff`,output:`diff`},{source:`snapshotRaw`,output:`raw`},{source:`snapshotCustomActions`,output:`actions`},{source:`snapshotForceFull`,output:`forceFull`}],numbers:[{source:`snapshotDepth`,output:`depth`}]},[g.back]:{enums:[{source:`backMode`,output:`mode`,values:v}]},[g.record]:{booleans:[{source:`hideTouches`}],numbers:[{source:`fps`}],enums:[{source:`recordingScope`,output:`scope`,values:ce}]},[g.apps]:{enums:[{source:`appsFilter`,output:`filter`,values:[`user-installed`,`all`]}]},[g.boot]:{booleans:[{source:`headless`}]},[g.close]:{booleans:[{source:`shutdown`}]}};function Fr(e){let t=e.flags??{},n={},r=Object.hasOwn(Pr,e.command)?Pr[e.command]:void 0;return V(n,t,Mr),V(n,t,r),V(n,t,Ir(e.command)),Object.keys(n).length>0?n:void 0}function Ir(e){return oe(e)?Nr:void 0}function B(){return{booleans:[{source:`doubleTap`}],numbers:[{source:`count`},{source:`intervalMs`},{source:`holdMs`},{source:`jitterPx`}],enums:[{source:`clickButton`,values:We}]}}function Lr(){return{numbers:[{source:`delayMs`}]}}function Rr(){return{numbers:[{source:`pointerCount`},{source:`count`},{source:`pauseMs`}],enums:[{source:`pattern`,values:le}]}}function V(e,t,n){n&&(zr(e,t,n.booleans??[]),Br(e,t,n.numbers??[]),Vr(e,t,n.enums??[]))}function zr(e,t,n){for(let r of n)Hr(e,r.output??r.source,t[r.source])}function Br(e,t,n){for(let r of n)Ur(e,r.output??r.source,t[r.source])}function Vr(e,t,n){for(let r of n)Wr(e,r.output??r.source,t[r.source],r.values)}function H(e){let t=A(e.ref);if(!t)return;let n=t.startsWith(`@`)?t.slice(1):t;return/^[a-zA-Z0-9:_-]+$/.test(n)?n:void 0}function Hr(e,t,n){typeof n==`boolean`&&(e[t]=n)}function Ur(e,t,n){let r=I(n);r!==void 0&&(e[t]=r)}function Wr(e,t,n,r){let i=M(n,r);i!==void 0&&(e[t]=i)}const Gr=65536;function Kr(e){return dt(`sha256`).update(e,`utf8`).digest(`hex`).slice(0,32)}function U(e,t){let n=Xr(e);if(n===void 0)return!1;try{let e=Jr(t),r=Buffer.allocUnsafe(Gr),i=0;do if(i=y.readSync(n,r,0,r.length,null),!e.push(r.subarray(0,i)))return!0;while(i>0);return e.end(),!0}finally{y.closeSync(n)}}async function qr(e){let t=await Zr(e);if(t===void 0)return{lineCount:0,firstLineDigest:void 0};let n={lineCount:0,firstLineDigest:void 0};try{let e=Jr(e=>{n.lineCount===0&&(n.firstLineDigest=Kr(e)),n.lineCount+=1}),r=Buffer.allocUnsafe(Gr);for(;;){let{bytesRead:n}=await t.read(r,0,r.length,null);if(e.push(r.subarray(0,n)),n===0)break}return e.end(),n}finally{await t.close()}}function W(e){let t;return U(e,e=>(t=Kr(e),!1)),t}function Jr(e){let t=new ft(`utf8`),n=``,r=!1;return{push(i){if(r)return!1;let a=`${n}${t.write(i)}`,o=0;for(let t=a.indexOf(`
|
|
1
|
+
import{P as e,it as t}from"./sdk-contracts.js";import{v as n}from"./sdk-batch-runner.js";import{a as r,c as i,r as a}from"./diagnostics.js";import"./diagnostics2.js";import{E as o,O as s,a as c,f as l,i as ee,n as te,u as ne}from"./sdk-device.js";import{S as re,cn as ie,er as ae,m as oe,tr as se,un as u}from"./sdk-batch.js";import{t as ce}from"./recording-scope.js";import{a as le}from"./scroll-gesture.js";import{_ as d,c as ue,d as de,g as fe,h as pe,i as me,l as he,m as ge,o as _e,p as f,s as ve,u as p,y as ye}from"./script.js";import{C as be,D as xe,E as Se,F as Ce,M as we,O as Te,P as Ee,S as De,T as Oe,a as ke,b as Ae,d as je,i as Me,j as Ne,k as Pe,l as Fe,o as Ie,r as Le,s as Re,v as m,w as ze,x as Be,y as Ve}from"./provider-device-admission.js";import{n as h,t as He}from"./catalog.js";import{o as Ue,t as g}from"./back-mode.js";import{t as We}from"./session.js";import{r as Ge}from"./success-text.js";import{t as Ke}from"./click-button.js";import"./device.js";import{r as _,t as qe}from"./device-rotation.js";import{j as Je}from"./owner-identity.js";import"./file.js";import{t as Ye}from"./tv-remote.js";import{n as Xe,r as Ze,t as Qe}from"./session-paths.js";import{i as $e,n as et,r as tt}from"./session-artifact-paths.js";import{i as nt,r as rt,t as it}from"./session-repair-tombstone.js";import{t as at}from"./keyboard-actions.js";import{n as ot,r as st}from"./device-isolation.js";import{a as ct,i as lt,r as ut}from"./device-inventory-context.js";import{AsyncLocalStorage as dt}from"node:async_hooks";import{createHash as ft}from"node:crypto";import v from"node:fs";import y from"node:path";import{StringDecoder as pt}from"node:string_decoder";function mt(e,t={}){let n=[e.command];return e.command===`snapshot`?de(n,e):e.command===`open`?me(n,e):e.command===`runtime`?ue(n,e,{includeAllPositionals:t.runtimeIncludeAllPositionals}):e.command===`record`?ve(n,e):e.command===`screenshot`?he(n,e):_e(n,e),n.join(` `)}function ht(e){return e.targetEvidences?[ae(e.targetEvidences)]:e.targetEvidence?[se(e.targetEvidence)]:[]}function b(e){return e?.scriptPublication??m}function gt(e,t){let n=b(e),r=typeof t.saveScript==`string`?Qe(t.saveScript):n.kind===`repair`?void 0:t.healedSiblingPath;e.scriptPublication=Ae(n,{requested:{path:r,force:t.force===!0},boundary:t.firstArm?e.actions.length:0,sourcePath:t.sourcePath})}function _t(e){e.scriptPublication=De(b(e))}function vt(e){e.scriptPublication=Se(b(e))}function yt(e,t){e.scriptPublication=xe(b(e),t)}function bt(e){e.scriptPublication=Ve(b(e))}function xt(e,t){let n=b(e);return n.kind===`repair`&&n.closeReceipt===t}function St(e){return b(e).kind===`repair`}function Ct(e){return Oe(b(e))}function x(e){return Te(b(e))}function wt(e){return Pe(b(e))}function Tt(e,t){if(t.flags?.noRecord||Ft(e,t))return;t.flags&&Fe(e,t.flags);let n=Dt(t),r=At(e,Ot(t,n));n&&kt(e,n);let i={ts:Date.now(),command:r.command,positionals:r.positionals,runtime:r.runtime,flags:Lt(r.flags),result:r.result,...r.targetEvidence?{targetEvidence:r.targetEvidence}:{},...r.targetEvidences?{targetEvidences:r.targetEvidences}:{}};return e.actions.push(i),a({level:`debug`,phase:`record_action`,data:{command:t.command,session:e.name}}),i}function Et(e,t,n,r,i,a){!t||!e.resolveCurrent(t)||e.recordAction(t,{command:r,positionals:a?.positionals??n.positionals??[],flags:a?.flags??n.flags??{},result:i??{}})}function Dt(e){if(e.command!==`fill`||typeof e.flags.recordAs!=`string`)return;let t=Ce(e.flags.recordAs),n=Ee(t);return{literal:we({ts:0,command:e.command,positionals:e.positionals,flags:e.flags}),placeholder:n}}function Ot(e,t){if(!t)return e;let{literal:n,placeholder:r}=t;return{...e,positionals:Mt(e.positionals,r),result:Le(e.result,n,r),targetEvidence:Me(e.targetEvidence,n,r)}}function kt(e,t){t.literal.trim()&&(e.recordedFillLiterals??=new Map,!e.recordedFillLiterals.has(t.literal)&&e.recordedFillLiterals.set(t.literal,t.placeholder))}function At(e,t){let n=e.recordedFillLiterals;if(!n||n.size===0)return t;let r=ke(t.result,n),i=(t.targetEvidenceMode??`action`)===`landmark`?jt(t.targetEvidence,n):S(t.targetEvidence,n),a=t.targetEvidences?{source:S(t.targetEvidences.source,n),destination:S(t.targetEvidences.destination,n)}:t.targetEvidences;return{...t,result:r,targetEvidence:i,targetEvidences:a}}function jt(e,t){return e&&(Re(e,t)?void 0:e)}function S(e,t){return!e||!Re(e,t)?e:{...Ie(e,t),verification:`unverifiable`}}function Mt(e,t){let n=e[0];return n?.startsWith(`@`)?e.length>=3?[n,e[1],t]:[n,t]:e.length>=3&&Number.isFinite(Number(e[0]))&&Number.isFinite(Number(e[1]))?[e[0],e[1],t]:n===void 0?[t]:[n,t]}const Nt=new Set([`snapshot`,`get`,`is`,`find`]);function Pt(e){return e.internal?.replayPlanStep!==!0&&Nt.has(e.command)}function Ft(e,t){return!t.interactiveObservation||x(e)===void 0?!1:t.flags?.record!==!0}const It=Ue();function Lt(e){if(!e)return{};let t={};for(let n of It){let r=e[n];r!==void 0&&(t[n]=r)}return t}function C(e){return y.join(e,`idle-expiry.json`)}function Rt(e){let t;try{t=v.readFileSync(e,`utf8`)}catch{return}let n;try{n=JSON.parse(t)}catch{return}if(!(typeof n?.expiresAt!=`number`||!Number.isFinite(n.expiresAt))&&!(n.expiresAt<=Date.now())&&typeof n.owner==`string`&&!(!zt(n.expiredAtMs)||!zt(n.idleExpiryMs))&&(n.deviceKey===void 0||typeof n.deviceKey==`string`))return n}function zt(e){return typeof e==`number`&&Number.isFinite(e)&&e>=0}function Bt(t){let n=t.flatMap((e,t)=>e.command===`open`?[t]:[]);if(n.length!==1||n[0]!==0)throw new e(`COMMAND_FAILED`,`Cannot publish this session: an open-to-destination script requires exactly one initial recorded open.`,{retriable:!1,hint:`Close this session and start a fresh one with open <app> --save-script[=<path>].`});if(t.some(e=>e.command===`close`))throw new e(`COMMAND_FAILED`,`Cannot publish an active-session script containing close.`,{retriable:!1,hint:`Close this session and record the journey again from a fresh open --save-script session.`});let r=-1;for(let[e,n]of t.entries())re({command:n.command,positionals:n.positionals,flags:n.flags})===`mutates-app`&&(r=e);if(!t.slice(r+1).some(Gt))throw new e(`COMMAND_FAILED`,`Cannot publish this session without a portable destination guard after the final mutating action.`,{retriable:!0,hint:`Record a selector-targeted wait on a labeled or id-bearing landmark, for example wait 'role="heading" label="Screen X"', so its recorded identity is captured, then retry session save-script.`})}function Vt(t){for(let n of t){if(Ht(n)){Ut(n);continue}let t=Kt(n),r=t??(n.command===`wait`?n.positionals[0]:void 0);if(r?.startsWith(`@`))throw new e(`COMMAND_FAILED`,`Cannot publish recorded step "${n.command} ${r}": the session-local ref was not converted to a portable selector.`,{retriable:!1,hint:`Close this session and record the journey again using selectors or resolvable refs.`});if(n.command===`find`&&re(n)===`mutates-app`)throw new e(`COMMAND_FAILED`,`Cannot publish a recorded mutating find step because its target identity is not replay-verifiable.`,{retriable:!1,hint:`Close this session and record the journey again with an explicit selector-targeted click, press, fill, or focus action.`});let i=t;if(!(!i||!u(i)||n.targetEvidence))throw new e(`COMMAND_FAILED`,`Cannot publish recorded step "${n.command} ${i}": recording-time target identity evidence is missing.`,{retriable:!1,hint:`Close this session and record the journey again from open --save-script so target-v1 evidence is captured before each interaction.`})}}function Ht(e){return w(e)!==void 0}function Ut(t){let n=w(t);if(!n)return;let r=[n.source,n.destination];for(let n of r){if(n?.startsWith(`@`))throw new e(`COMMAND_FAILED`,`Cannot publish recorded drag endpoint "${n}": the session-local ref was not converted to a portable selector.`,{retriable:!1});if(!(!n||!u(n))&&!t.targetEvidences)throw new e(`COMMAND_FAILED`,`Cannot publish recorded drag endpoint "${n}": recording-time target identity evidence is missing.`,{retriable:!1,hint:`Close this session and record the journey again so targets-v1 evidence is captured for both drag endpoints.`})}}function w(e){return e.command===`gesture`?ye(e.positionals):void 0}function Wt(t,n){if(t instanceof e){if(t.details?.reason===`script_target_exists`)return new e(t.code,`A file already exists at ${String(t.details.path)}.`,{...t.details,retriable:!0,hint:`Retry session save-script with another path, or pass --force to replace the existing file. The session remains armed.`});let n=t.details?.retriable===!0;return new e(t.code,t.message,{...t.details,retriable:n,hint:t.details?.hint??(n?`Fix the recorded journey or target, then retry session save-script. The session remains armed.`:`Close this session and start a fresh one with open <app> --save-script[=<path>].`)})}let r=t instanceof Error?t.message:String(t);return new e(`COMMAND_FAILED`,`Failed to publish the active session script${n?` to ${n}`:``}: ${r}`,{retriable:!0,hint:`Check the target path and permissions, then retry session save-script. The session remains armed.`})}function Gt(e){if(e.command!==`wait`)return!1;let t=ie(e.positionals);return t?.kind!==`selector`||!u(t.selectorExpression)?!1:e.targetEvidence?.verification===`verified`}function Kt(e){if(e.command===`get`)return e.positionals[1];if(fe(e.command)||e.command===`fill`){let[t,n]=e.positionals;return t!==void 0&&n!==void 0&&qt(t)&&qt(n)?void 0:t}}function qt(e){return e.trim().length>0&&Number.isFinite(Number(e))}function Jt(e){let t=e.scriptPublication??m;return t.kind===`repair`?t.status===`committed`||!ze(t):!1}function Yt(e){return!be(e.scriptPublication??m)||Jt(e)}var Xt=class{sessionsDir;constructor(e){this.sessionsDir=e}write(e,t){let n=St(e),r=t?.publication===`active`,i;try{if(Yt(e))return{written:!1};let a=Zt(e,{appendCompleteSentinel:n,activePublication:r});i=this.resolveScriptPath(e);let o=y.dirname(i);return v.existsSync(o)||v.mkdirSync(o,{recursive:!0}),en({scriptPath:i,script:a.script,force:t?.force}),n&&(e.scriptPublication=Be(e.scriptPublication??m)),{written:!0,path:i,actionCount:a.actionCount}}catch(t){return Qt({session:e,error:t,scriptPath:i,repairArmed:n,activePublication:r})}}resolveScriptPath(e){let t=Ne(e.scriptPublication??m);if(t)return Qe(t);let n=Ze(e.name),r=new Date(e.createdAt).toISOString().replaceAll(/[:.]/g,`-`);return y.join(this.sessionsDir,`${n}-${r}.ad`)}};function Zt(e,t){let n=tn(e,{strictPortableRefs:t.activePublication});return t.activePublication&&Bt(n),{script:fn(e,n,t.appendCompleteSentinel),actionCount:n.length}}function Qt(t){let{session:n,error:r,scriptPath:i,repairArmed:o,activePublication:s}=t;if(a({level:`warn`,phase:`session_script_write_failed`,data:{session:n.name,path:i,error:r instanceof Error?r.message:String(r)}}),o)return{written:!1,error:$t(r,i)};if(s)return{written:!1,error:Wt(r,i)};if(r instanceof e)throw r;return{written:!1}}function $t(t,n){if(t instanceof e)return t;let r=t instanceof Error?t.message:String(t);return new e(`COMMAND_FAILED`,`Failed to write the healed script${n?` to ${n}`:``}: ${r}`,{hint:`The repair transaction completed but the healed .ad could not be published; check the target path and permissions, then retry close --save-script.`})}function en(t){let{scriptPath:n,script:r,force:i}=t;try{Je({destination:n,contents:r,publish:i?`replace`:`link-exclusive`})}catch(t){throw t.code===`EEXIST`?new e(`COMMAND_FAILED`,`A file already exists at ${n}; remove it, pass replay --save-script=<other-path>, or pass --force/--overwrite to replace it.`,{reason:`script_target_exists`,path:n}):t}}function tn(e,t={}){let n=x(e),r=n!==void 0,i=e.actions.slice(n??0),a=[];for(let n of i){if(n.command===`snapshot`)continue;let i=an(n);if(i){a.push(i);continue}(r||t.strictPortableRefs)&&nn(n);let o=dn(e,n);o&&a.push(o),a.push(n)}return t.strictPortableRefs&&Vt(a),a}function nn(t){let n=t.command===`gesture`?ye(t.positionals??[]):void 0;if(n){rn(n);return}if(!T(t.command))return;let r=t.command===`get`?t.positionals?.[1]:t.positionals?.[0];if(r?.startsWith(`@`))throw new e(`COMMAND_FAILED`,`Cannot write recorded step "${t.command} ${r}" to a script: it never resolved to a selector, so the ref would not resolve in a fresh replay session.`)}function rn(t){let n=[t.source,t.destination].find(e=>e.startsWith(`@`));if(n)throw new e(`COMMAND_FAILED`,`Cannot write recorded drag endpoint "${n}" to a script: it never resolved to a selector, so the ref would not resolve in a fresh replay session.`)}function an(e){let t=on(e);if(!(!t||!T(e.command)))return pe(e.command)||e.command===`hover`?{...e,positionals:[t]}:e.command===`longpress`?cn(e,t):e.command===`fill`?sn(e,t):ln(e,t)}function on(e){let t=Array.isArray(e.result?.selectorChain)&&e.result.selectorChain.every(e=>typeof e==`string`)?e.result.selectorChain:[];return t.length>0?t.join(` || `):void 0}function T(e){return fe(e)||e===`fill`||e===`get`}function sn(e,t){let n=we(e);return n.length>0?{...e,positionals:[t,n]}:void 0}function cn(e,t){let n=typeof e.result?.durationMs==`number`?String(e.result.durationMs):un(e.positionals??[]);return{...e,positionals:n?[t,n]:[t]}}function ln(e,t){let n=e.positionals?.[0];return n===`text`||n===`attrs`?{...e,positionals:[n,t]}:void 0}function un(e){let t=e.at(-1);if(!(e.length<=1||t===void 0||t.trim()===``))return Number.isFinite(Number(t))?t:void 0}function dn(e,t){if(!T(t.command))return;let n=t.result?.refLabel;if(typeof n!=`string`||n.trim().length===0)return;let r=n.trim();return{ts:t.ts,command:`snapshot`,positionals:[],flags:{platform:e.device.platform,snapshotInteractiveOnly:!0,snapshotScope:r},result:{scope:r}}}function fn(e,t,n){let r=[],i=e.device.kind?` kind=${e.device.kind}`:``;r.push(`context platform=${o(e.device)} device=${ge(e.device.name)}${i} theme=unknown`);for(let e of t)e.flags?.noRecord||(r.push(...ht(e)),r.push(pn(e)));return n&&r.push(`# agent-device:heal-complete`),`${r.join(`
|
|
2
|
+
`)}\n`}function pn(e){return mn([e.command],e)||mt(e)}function mn(e,t){if(pe(t.command))return hn(e,t);if(t.command===`fill`)return gn(e,t);if(t.command===`get`)return _n(e,t)}function hn(e,t){let n=t.positionals?.[0];if(n){if(n.startsWith(`@`))return e.push(f(d(n))),E(e,t),p(e,t),e.join(` `);if(t.positionals.length===1)return e.push(f(n)),p(e,t),e.join(` `)}}function gn(e,t){let n=t.positionals?.[0];if(!n?.startsWith(`@`))return;e.push(f(d(n))),E(e,t);let r=t.positionals.slice(1).join(` `);return t.positionals.length>1&&e.push(f(r)),p(e,t),e.join(` `)}function _n(e,t){let n=t.positionals?.[0],r=t.positionals?.[1];if(!(!n||!r))return e.push(f(n)),e.push(f(d(r))),r.startsWith(`@`)&&E(e,t),e.join(` `)}function E(e,t){let n=t.result?.refLabel;typeof n==`string`&&n.trim().length>0&&e.push(f(n))}const vn=[`id`,`deviceId`,`device_id`,`serial`,`udid`,`device_udid`,`identifier`],yn={ios:`iOS`,ipados:`iPadOS`,tvos:`tvOS`,watchos:`watchOS`,visionos:`visionOS`,macos:`macOS`,apple:`Apple`,android:`Android`,linux:`Linux`,web:`Web`};function bn(e,t){let n=t??{};switch(e.command){case h.devices:return xn(n.devices);case h.apps:return Sn(n.apps,e.flags?.appsFilter);case h.boot:return Cn(`Booted`,n,!0);case h.shutdown:return Cn(`Shut down`,n,!1);case h.install:return wn(`Installed`,n);case h.reinstall:return wn(`Reinstalled`,n);case h.screenshot:return Tn(e,n);default:return{}}}function xn(e){if(!Array.isArray(e))return{};let t=e.flatMap(e=>{let t=Dn(e);return t?[t]:[]}),n=t.slice(0,5),r=Math.max(0,t.length-n.length),i=t.slice(0,3);return{summary:Fn(`Found ${t.length} ${In(`device`,t.length)}`,i.map(e=>D(e,!0)),Math.max(0,t.length-i.length)),details:{deviceCount:t.length,devices:n,...r>0?{omittedDeviceCount:r}:{}}}}function Sn(e,t){if(!Array.isArray(e))return{};let n=e.flatMap(e=>{let t=A(e);return t?[t]:[]}),r=n.slice(0,5),i=Math.max(0,n.length-r.length),a=n.slice(0,3);return{summary:Fn(`Found ${n.length} ${In(`app`,n.length)}`,a,Math.max(0,n.length-a.length)),details:{appCount:n.length,apps:r,...i>0?{omittedAppCount:i}:{},...t===`all`||t===`user-installed`?{filter:t}:{}}}}function Cn(e,t,n){let r=On(t);if(!r)return{};let i={device:r,...Nn(t),booted:n};return{summary:`${e} ${D(i,!1)}`,details:i}}function wn(e,t){let n=A(t.appName),r=A(t.bundleId),i=O(t,[`packageName`,`package`]),a=A(t.platform),o=A(t.launchTarget),s=O(t,[`bundleId`,`packageName`,`package`,`appId`,`launchTarget`]),c=Pn(n,s);if(!c)return{};let l={};return k(l,`appName`,n),k(l,`bundleId`,r),k(l,`packageName`,i),k(l,`platform`,a),o!==s&&k(l,`launchTarget`,o),{summary:`${e} ${c}`,details:l}}function Tn(e,t){let n=En(e,t);return n?{details:{requestedFileName:n}}:{}}function En(e,t){let n=I(e.meta?.clientArtifactPaths?.path)??I(t.path);if(n)return F(n)}function Dn(e){if(!n(e))return;let t=On(e);if(t)return{name:t,...Nn(e)}}function On(e){let t=O(e,[`name`,`deviceName`,`device`]);return!t||!kn(e,t)?t:jn(e)}function kn(e,t){let n=An(t);return vn.some(t=>{let r=A(e[t]);return r!==void 0&&An(r)===n})}function An(e){return e.toLowerCase()}function jn(e){let t=A(e.appleOs),n=A(e.platform),r=A(e.kind),i=Mn(t,n);return i&&(r===`simulator`||r===`emulator`)?`${i} ${r}`:i?`${i} device`:r===`simulator`?`Simulator`:r===`emulator`?`Emulator`:`Unnamed device`}function Mn(e,t){let n=e??t;if(!(!n||!Object.hasOwn(yn,n)))return yn[n]}function Nn(e){let t=A(e.platform),n=A(e.appleOs),r=A(e.kind),i=A(e.target);return{...t?{platform:t}:{},...n?{appleOs:n}:{},...r?{kind:r}:{},...i?{target:i}:{},...typeof e.booted==`boolean`?{booted:e.booted}:{}}}function D(e,t){let n=A(e.name)??A(e.device)??`device`,r=A(e.platform),i=A(e.appleOs),a=[r,i===r?void 0:i,A(e.kind),A(e.target),t&&typeof e.booted==`boolean`?e.booted?`booted`:`stopped`:void 0].filter(e=>!!e);return a.length>0?`${n} (${a.join(`, `)})`:n}function Pn(e,t){return e&&t&&e!==t?`${e} (${t})`:e??t}function O(e,t){for(let n of t){let t=A(e[n]);if(t)return t}}function k(e,t,n){n&&(e[t]=n)}function Fn(e,t,n){let r=[...t,...n>0?[`+${n} more`]:[]];return r.length>0?`${e}: ${r.join(`, `)}`:e}function In(e,t){return t===1?e:`${e}s`}function A(e){let t=I(e);if(!t)return;let n=t.trim(),r=Array.from(n);return r.length<=120?n:`${r.slice(0,119).join(``)}…`}function j(e){return A(e)}function M(e){return typeof e==`boolean`?e:void 0}function N(e,t){let n=j(e);return n&&t.includes(n)?n:void 0}function P(e){return Object.fromEntries(Object.entries(e).filter(([,e])=>e!==void 0))}function F(e){let t=I(e);return t?A(t.split(/[\\/]/).at(-1)):void 0}function I(e){if(typeof e==`string`)return e.trim().length>0?e:void 0}function L(e){return typeof e==`number`&&Number.isFinite(e)?e:void 0}const Ln=[`up`,`down`,`left`,`right`],Rn=[`top`,`bottom`];function zn(e){return`${e.command===h.reinstall?`Reinstalled`:`Installed`} ${Un(e.result??{})??`app`}`}function Bn(e){let t=e.result??{};switch(e.command){case h.scroll:return Gn(t);case h.screenshot:return Jn(t);case h.home:return`Went home`;case h.back:return Xn(t);case h.appSwitcher:return`Opened app switcher`;case h.actionButton:return`Pressed Action Button`;case h.orientation:return Qn(t);case h.fold:return Zn(t);case h.viewport:return $n(t);case h.clipboard:return er(t);case h.keyboard:return tr(t);case h.tvRemote:return ir(t);case h.gesture:return ar(t);case h.swipe:return or(t);case h.trace:return cr(`trace`,e);case h.record:return cr(`recording`,e);default:return}}function Vn(e){let t=e.result??{};switch(e.command){case h.scroll:return P({direction:N(t.direction,Ln),edge:N(t.edge,Rn),passes:L(t.passes),amount:L(t.amount),pixels:L(t.pixels),durationMs:L(t.durationMs),x1:L(t.x1),y1:L(t.y1),x2:L(t.x2),y2:L(t.y2)});case h.screenshot:return P({requestedFileName:Yn(t)});case h.back:return P({mode:N(t.mode,g)});case h.orientation:return P({orientation:N(t.orientation,qe)});case h.fold:return P({pose:N(t.pose,_)});case h.viewport:return P({width:L(t.width),height:L(t.height)});case h.clipboard:return P({action:N(t.action,[`read`,`write`])});case h.keyboard:return rr(t);case h.tvRemote:return P({button:N(t.button,Ye),durationMs:L(t.durationMs)});case h.gesture:case h.swipe:return sr(t);case h.trace:case h.record:return P({action:N(t.action,[`start`,`stop`]),fileName:ur(e),showTouches:M(t.showTouches)});default:return{}}}function Hn(e,t){if(e.command!==h.screenshot)return t;let n=En(e,t);return n?{...t,requestedFileName:n}:t}function Un(e){let t=j(e.appName),n=dr(e,[`bundleId`,`packageName`,`appBundleId`,`launchTarget`]);return t&&n&&t!==n?`${t} (${n})`:t??n??Wn(e)}function Wn(e){let t=j(e.app);return t&&!t.includes(`/`)&&!t.includes(`\\`)?t:void 0}function Gn(e){let t=N(e.direction,Ln),n=N(e.edge,Rn),r=L(e.passes);return n?Kn(n,r):t?qn(t,e):`Scrolled`}function Kn(e,t){return t===0?`Already at ${e}`:t===void 0?`Scrolled to ${e}`:`Scrolled to ${e} in ${t} ${t===1?`pass`:`passes`}`}function qn(e,t){let n=L(t.pixels);if(n!==void 0)return`Scrolled ${e} by ${n}px`;let r=L(t.amount);return r===void 0?`Scrolled ${e}`:`Scrolled ${e} by ${r}`}function Jn(e){let t=Yn(e);return t?`Captured screenshot ${t}`:`Captured screenshot`}function Yn(e){return F(e.requestedFileName)??F(e.path)}function Xn(e){return N(e.mode,g)===`system`?`Went back using system navigation`:`Went back`}function Zn(e){let t=N(e.pose,_);return t?`Folded to ${t}`:`Changed fold pose`}function Qn(e){let t=N(e.orientation,qe);return t?M(e.confirmed)===!1?`Requested ${t} (unconfirmed)`:`Rotated to ${t}`:`Changed orientation`}function $n(e){let t=L(e.width),n=L(e.height);return t!==void 0&&n!==void 0?`Set viewport to ${t}×${n}`:`Changed viewport`}function er(e){let t=N(e.action,[`read`,`write`]);return t===`read`?`Read clipboard`:t===`write`?`Updated clipboard`:`Used clipboard`}function tr(e){let t=I(e.action);if(!t||!at(t))return`Used keyboard`;if(t===`dismiss`)return nr(e);if(t===`enter`||t===`return`)return`Pressed keyboard return`;let n=M(e.visible);return n===void 0?`Inspected keyboard`:n?`Keyboard is visible`:`Keyboard is hidden`}function nr(e){return M(e.dismissed)===!1?`Keyboard was already hidden`:`Dismissed keyboard`}function rr(e){let t=I(e.action);return P({action:t&&at(t)?t:void 0,platform:N(e.platform,[`ios`,`android`]),visible:M(e.visible),wasVisible:M(e.wasVisible),dismissed:M(e.dismissed),attempts:L(e.attempts),mechanism:N(e.mechanism,[`dismissKey`])})}function ir(e){let t=N(e.button,Ye);return t?`Pressed TV remote ${t}`:`Used TV remote`}function ar(e){let t=N(e.kind,[`fling`,`pan`,`pinch`,`rotate`,`transform`]);return t?`Ran ${t} gesture`:`Ran gesture`}function or(e){let t=L(e.count);return t!==void 0&&t>1?`Swiped ${t} times`:`Swiped`}function sr(e){return P({kind:N(e.kind,[`fling`,`pan`,`pinch`,`rotate`,`transform`]),durationMs:L(e.durationMs),pointerCount:L(e.pointerCount),x1:L(e.x1),y1:L(e.y1),x2:L(e.x2),y2:L(e.y2),count:L(e.count),pauseMs:L(e.pauseMs),pattern:N(e.pattern,[`one-way`,`ping-pong`]),scale:L(e.scale)})}function cr(e,t){let n=lr(e,N(t.result?.action,[`start`,`stop`])),r=ur(t);return r?`${n} ${r}`:n}function lr(e,t){return t===`start`?e===`trace`?`Started trace`:`Started recording`:t===`stop`?e===`trace`?`Stopped trace`:`Stopped recording`:e===`trace`?`Updated trace`:`Updated recording`}function ur(e){let t=e.result??{};return F(t.requestedFileName)??F(t.outPath)??F(t.path)??F(e.positionals[1])}function dr(e,t){for(let n of t){let t=j(e[n]);if(t)return t}}function fr(e){switch(e.command){case h.open:return`Opened ${R(e)??`session`}`;case h.close:return`Closed ${j(e.result?.session)??`session`}`;case h.click:case h.press:return`Tapped ${R(e)??`target`}`;case h.longPress:return`Long pressed ${R(e)??`target`}`;case h.hover:return`Hovered ${R(e)??`target`}`;case h.fill:return`Filled ${R(e)??`target`}`;case h.type:return`Typed text`;case h.install:case h.reinstall:case He.installSource:return zn(e);default:return Bn(e)??`Ran ${e.command}`}}function pr(e){return P({command:e.command,positionals:Sr(e),flags:Pr(e),...mr(e),...hr(e),...gr(e),...Vn(e)})}function mr(e){if(!_r(e.command))return{};let t=e.result??{};return P({ref:U(t),targetLabel:R(e),selectorChainLength:Ar(t.selectorChain)?.length,x:L(t.x),y:L(t.y),x2:L(t.x2),y2:L(t.y2),durationMs:L(t.durationMs)})}function hr(e){if(!vr(e.command))return{};let t=e.result??{};return P({platform:N(t.platform,c),target:N(t.target,te),appName:j(t.appName),appBundleId:j(t.appBundleId),bundleId:j(t.bundleId),packageName:j(t.packageName),launchTarget:j(t.launchTarget)})}function gr(e){let t=e.result??{};return e.command===h.snapshot?Array.isArray(t.nodes)?{nodeCount:t.nodes.length}:{}:e.command!==h.wait&&e.command!==h.find&&e.command!==h.get&&e.command!==h.is?{}:P({waitedMs:L(t.waitedMs),found:M(t.found)})}function _r(e){return e===h.click||e===h.press||e===h.longPress||e===h.hover||e===h.focus||e===h.fill}function vr(e){return e===h.open||e===h.install||e===h.reinstall||e===He.installSource}function R(e){let t=e.result??{};return yr(t)??br(t)??xr(t)??Or(e.positionals[0])}function yr(e){let t=U(e);if(t)return t.startsWith(`@`)?t:`@${t}`}function br(e){let t=L(e.x),n=L(e.y);if(t!==void 0&&n!==void 0)return`(${t}, ${n})`}function xr(e){return j(e.appName)??j(e.appBundleId)??j(e.bundleId)??j(e.packageName)}function Sr(e){if(e.positionals.length!==0)return e.command===h.type?[B(`text`)]:e.command===h.fill?Cr(e):e.command===h.find?wr(e):e.command===h.clipboard?Tr(e):e.command===h.push?Er(e,`app`,`payload`):e.command===h.triggerAppEvent?Er(e,`event`,`payload`):e.positionals.map(z)}function Cr(e){let t=B(`text`),n=e.result??{},r=U(n);if(r)return[`@${r}`,t];if(j(n.selector))return[B(`target`),t];let i=L(n.x),a=L(n.y);return i!==void 0&&a!==void 0?[String(i),String(a),t]:[t]}function wr(e){let t=+!!kr(e.positionals[0]);if(e.positionals[t]===void 0)return;let n=t+1,r=[...t===1?[String(e.positionals[0])]:[],B(`query`)],i=e.positionals[n];return i?i===`fill`||i===`type`?[...r,i,B(`text`)]:[...r,...e.positionals.slice(n).map(Dr)]:r}function Tr(e){let t=e.positionals[0]?.toLowerCase();return t===`read`?[`read`]:t===`write`?[`write`,B(`text`)]:e.positionals.map(z)}function Er(e,t,n){let[r,i,...a]=e.positionals;return[...r?[B(t)]:[],...i?[B(n)]:[],...a.map(z)]}function Dr(e){return e===`click`||e===`focus`||e===`exists`||e===`get`||e===`text`||e===`attrs`||e===`wait`?e:z(e)}function z(e){return Or(e)??B(`arg`)}function Or(e){if(!e)return;let t=e.trim();if(/^@[a-zA-Z0-9:_-]+$/.test(t))return t}function B(e){return`<${e}>`}function kr(e){return e===`text`||e===`label`||e===`value`||e===`role`||e===`id`}function Ar(e){return Array.isArray(e)&&e.every(e=>typeof e==`string`)?e:void 0}const jr={enums:[{source:`platform`,values:ee},{source:`target`,values:te}]},Mr={booleans:[{source:`settle`}],numbers:[{source:`settleQuietMs`}]},Nr={[h.open]:{booleans:[{source:`relaunch`},{source:`testIme`}],enums:[{source:`surface`,values:We}]},[h.click]:V(),[h.press]:V(),[h.longPress]:V(),[h.hover]:V(),[h.fill]:Ir(),[h.type]:Ir(),[h.scroll]:{numbers:[{source:`pixels`},{source:`durationMs`}]},[h.gesture]:Lr(),[h.swipe]:Lr(),[h.screenshot]:{booleans:[{source:`overlayRefs`},{source:`screenshotFullscreen`,output:`fullscreen`},{source:`screenshotNoStabilize`,output:`noStabilize`},{source:`screenshotNormalizeStatusBar`,output:`normalizeStatusBar`}],numbers:[{source:`screenshotPixelDensity`,output:`pixelDensity`},{source:`screenshotScale`,output:`scale`}]},[h.snapshot]:{booleans:[{source:`snapshotInteractiveOnly`,output:`interactiveOnly`},{source:`snapshotDiff`,output:`diff`},{source:`snapshotRaw`,output:`raw`},{source:`snapshotCustomActions`,output:`actions`},{source:`snapshotForceFull`,output:`forceFull`}],numbers:[{source:`snapshotDepth`,output:`depth`}]},[h.back]:{enums:[{source:`backMode`,output:`mode`,values:g}]},[h.record]:{booleans:[{source:`hideTouches`}],numbers:[{source:`fps`}],enums:[{source:`recordingScope`,output:`scope`,values:ce}]},[h.apps]:{enums:[{source:`appsFilter`,output:`filter`,values:[`user-installed`,`all`]}]},[h.boot]:{booleans:[{source:`headless`}]},[h.close]:{booleans:[{source:`shutdown`}]}};function Pr(e){let t=e.flags??{},n={},r=Object.hasOwn(Nr,e.command)?Nr[e.command]:void 0;return H(n,t,jr),H(n,t,r),H(n,t,Fr(e.command)),Object.keys(n).length>0?n:void 0}function Fr(e){return oe(e)?Mr:void 0}function V(){return{booleans:[{source:`doubleTap`}],numbers:[{source:`count`},{source:`intervalMs`},{source:`holdMs`},{source:`jitterPx`}],enums:[{source:`clickButton`,values:Ke}]}}function Ir(){return{numbers:[{source:`delayMs`}]}}function Lr(){return{numbers:[{source:`pointerCount`},{source:`count`},{source:`pauseMs`}],enums:[{source:`pattern`,values:le}]}}function H(e,t,n){n&&(Rr(e,t,n.booleans??[]),zr(e,t,n.numbers??[]),Br(e,t,n.enums??[]))}function Rr(e,t,n){for(let r of n)Vr(e,r.output??r.source,t[r.source])}function zr(e,t,n){for(let r of n)Hr(e,r.output??r.source,t[r.source])}function Br(e,t,n){for(let r of n)Ur(e,r.output??r.source,t[r.source],r.values)}function U(e){let t=j(e.ref);if(!t)return;let n=t.startsWith(`@`)?t.slice(1):t;return/^[a-zA-Z0-9:_-]+$/.test(n)?n:void 0}function Vr(e,t,n){typeof n==`boolean`&&(e[t]=n)}function Hr(e,t,n){let r=L(n);r!==void 0&&(e[t]=r)}function Ur(e,t,n,r){let i=N(n,r);i!==void 0&&(e[t]=i)}const Wr=65536;function Gr(e){return ft(`sha256`).update(e,`utf8`).digest(`hex`).slice(0,32)}function W(e,t){let n=Yr(e);if(n===void 0)return!1;try{let e=qr(t),r=Buffer.allocUnsafe(Wr),i=0;do if(i=v.readSync(n,r,0,r.length,null),!e.push(r.subarray(0,i)))return!0;while(i>0);return e.end(),!0}finally{v.closeSync(n)}}async function Kr(e){let t=await Xr(e);if(t===void 0)return{lineCount:0,firstLineDigest:void 0};let n={lineCount:0,firstLineDigest:void 0};try{let e=qr(e=>{n.lineCount===0&&(n.firstLineDigest=Gr(e)),n.lineCount+=1}),r=Buffer.allocUnsafe(Wr);for(;;){let{bytesRead:n}=await t.read(r,0,r.length,null);if(e.push(r.subarray(0,n)),n===0)break}return e.end(),n}finally{await t.close()}}function G(e){let t;return W(e,e=>(t=Gr(e),!1)),t}function qr(e){let t=new pt(`utf8`),n=``,r=!1;return{push(i){if(r)return!1;let a=`${n}${t.write(i)}`,o=0;for(let t=a.indexOf(`
|
|
3
3
|
`);t!==-1;t=a.indexOf(`
|
|
4
|
-
`,o)){if(Yr(a.slice(o,t),e)===!1)return r=!0,!1;o=t+1}return n=a.slice(o),!0},end(){r||Yr(`${n}${t.end()}`,e)}}}function Yr(e,t){let n=e.endsWith(`\r`)?e.slice(0,-1):e;if(n.trim().length!==0)return t(n)}function Xr(e){try{return y.openSync(e,`r`)}catch(e){if(e.code===`ENOENT`)return;throw e}}async function Zr(e){try{return await y.promises.open(e,`r`)}catch(e){if(e.code===`ENOENT`)return;throw e}}const Qr=5242880;function $r(e=process.env){let t=e.AGENT_DEVICE_EVENT_LOG_MAX_BYTES?.trim();if(t===void 0||!/^\d+$/.test(t))return Qr;let n=Number(t);return Number.isSafeInteger(n)&&n>0?n:Qr}function G(e){return`${e}.1`}function K(e){return`${e}.window.json`}function ei(e){let t;for(let n=0;n<3;n+=1){let n=J(e);try{let t=ti(e);if(J(e)===n)return t}catch(r){if(t=r,J(e)===n)throw r}}throw t??q(e,`the window did not settle while reading`)}function ti(e){let t=G(e),n=X(e);if(n===`unverifiable`)throw q(e,`window file is invalid`);if(n===void 0)return ni(e,t);let r=n.at(-1);if(!r)throw q(e,`window file records no generation`);let i=ui(e),a=ri(e,r),o=[],s=ii({eventLogPath:e,rotatedPath:t,sidecar:n,activeStart:a,activeExists:i});return s!==void 0&&o.push({path:t,firstLineIndex:s}),i&&o.push({path:e,firstLineIndex:a}),{files:o,earliestCursor:o[0]?.firstLineIndex??a}}function ni(e,t){if(W(t)!==void 0)throw q(e,`a rotated event log exists with no window record`);return{files:ui(e)?[{path:e,firstLineIndex:0}]:[],earliestCursor:0}}function ri(e,t){let n=W(e);return n!==void 0&&n===t.firstLineDigest?t.firstLineIndex:t.firstLineIndex+t.lineCount}function ii(e){let{eventLogPath:t,rotatedPath:n,sidecar:r,activeStart:i,activeExists:a}=e,o=W(n);if(o===void 0)return;let s=r.find(e=>e.firstLineDigest===o);if(!s)throw q(t,`the rotated event log matches no window record`);let c=si(n);if(c!==s.lineCount)throw q(t,`the rotated event log holds ${c} lines, the window recorded ${s.lineCount}`);if(a&&s.firstLineIndex+s.lineCount!==i)throw q(t,`retained event log generations are not contiguous`);return s.firstLineIndex}async function ai(e,t){let n=di(e);if(!n||n.size<t)return!1;let r=X(e);if(r===`unverifiable`)return await y.promises.rename(e,G(e)),!0;let i=await qr(e);if(i.firstLineDigest!==void 0){let t=r??[],n=t.at(-1),a=n&&n.firstLineDigest===i.firstLineDigest?n:{firstLineIndex:n?n.firstLineIndex+n.lineCount:0,lineCount:i.lineCount,firstLineDigest:i.firstLineDigest};await li(e,(a===n?t:[...t,a]).slice(-2))}return await y.promises.rename(e,G(e)),!0}function oi(t,n){if(!(t>=n))throw new e(`COMMAND_FAILED`,`events cursor ${t} precedes the retained event log window; events before cursor ${n} were rotated out.`,{reason:`EVENT_LOG_CURSOR_EXPIRED`,cursor:t,earliestCursor:n,hint:`Resume with cursor ${n}, the oldest retained event; earlier events are no longer available.`})}function q(t,n){return new e(`COMMAND_FAILED`,`Session event log window cannot be verified: ${n}.`,{reason:`EVENT_LOG_WINDOW_UNVERIFIED`,path:t,hint:`Cursor positions for this session cannot be resolved. Delete ${t}, ${G(t)}, and ${K(t)} to restart the timeline, or read the files directly.`})}function si(e){let t=0;return U(e,()=>{t+=1}),t}function J(e){return[Y(K(e)),Y(e),Y(G(e))].join(`|`)}function Y(e){try{let t=y.lstatSync(e);return`${t.ino}:${t.size}:${t.mtimeMs}`}catch{return`absent`}}function X(e){let t;try{t=y.readFileSync(K(e),`utf8`)}catch(e){return e.code===`ENOENT`?void 0:`unverifiable`}try{let e=JSON.parse(t);if(!n(e)||e.version!==2)return`unverifiable`;let{generations:r}=e;if(!Array.isArray(r)||r.length===0)return`unverifiable`;let i=r.map(ci);return i.every(e=>e!==void 0)?i:`unverifiable`}catch{return`unverifiable`}}function ci(e){if(!n(e))return;let{firstLineIndex:t,lineCount:r,firstLineDigest:i}=e;if(!(!Number.isSafeInteger(t)||t<0)&&!(!Number.isSafeInteger(r)||r<0)&&typeof i==`string`&&i.length!==0)return{firstLineIndex:t,lineCount:r,firstLineDigest:i}}async function li(e,t){let n=K(e),r=`${n}.${process.pid}.tmp`;await y.promises.writeFile(r,JSON.stringify({version:2,generations:t}),`utf8`),await y.promises.rename(r,n)}function ui(e){return di(e)!==void 0}function di(t){try{let n=y.lstatSync(t);if(n.isSymbolicLink())throw new e(`COMMAND_FAILED`,`Session event log must not be a symbolic link: ${t}`);return n}catch(e){if(e.code===`ENOENT`)return;throw e}}const Z=new Map,fi=new Set;function pi(e){return b.join(e,`events.ndjson`)}function mi(e){return e.command!==g.events}function hi(e,n,r){let i=t({version:1,ts:r.ts??new Date().toISOString(),session:n,...r});_i(e,`${JSON.stringify(i)}\n`)}async function gi(e){await(e?Z.get(e):Promise.all(Z.values()))}function _i(e,t){let n=(Z.get(e)??Promise.resolve()).catch(()=>void 0).then(async()=>{await vi(e),await ai(e,$r()),await y.promises.appendFile(e,t,`utf8`)}).catch(t=>{a({level:`warn`,phase:`session_event_log_write_failed`,data:{path:e,error:t instanceof Error?t.message:String(t)}})}).finally(()=>{Z.get(e)===n&&Z.delete(e)});Z.set(e,n)}async function vi(e){let t=b.dirname(e);if(!fi.has(t))try{await y.promises.mkdir(t,{recursive:!0}),fi.add(t)}catch(t){throw a({level:`warn`,phase:`session_event_log_dir_failed`,data:{path:e,error:t instanceof Error?t.message:String(t)}}),t}}function yi(e,t,n){hi(e,t,{kind:`action.recorded`,requestId:r().requestId,command:n.command,summary:pr(n),details:mr(n)})}function bi(e){let{req:t}=e;return{kind:`request.started`,requestId:t.meta?.requestId??r().requestId,command:t.command,summary:`Started ${t.command}`}}function xi(e){let{req:t,response:n,durationMs:i}=e;if(n.ok){let e=bn(t,n.data);return{kind:`request.finished`,requestId:t.meta?.requestId??r().requestId,command:t.command,status:`ok`,summary:e.summary??`Finished ${t.command}`,details:{durationMs:i,...e.details}}}return{kind:`request.finished`,requestId:t.meta?.requestId??r().requestId,command:t.command,status:`error`,summary:`Failed ${t.command}: ${n.error.code}`,details:{durationMs:i,code:n.error.code,diagnosticId:n.error.diagnosticId}}}function Si(e,t={}){let n=wi(t.cursor),r=Ti(t.limit),i=ei(e);oi(n,i.earliestCursor);let a=Ci(i.files,n,r),o=a.lines.flatMap(e=>{let t=Ei(e);return t?[t]:[]});return{path:e,cursor:String(n),limit:r,events:o,...a.nextCursor===void 0?{}:{nextCursor:String(a.nextCursor)}}}function Ci(e,t,n){let r=[],i;for(let a of e){let e=a.firstLineIndex;if(U(a.path,a=>{if(e>=t+n)return i=t+n,!1;e>=t&&r.push(a),e+=1}),i!==void 0)break}return{lines:r,...i===void 0?{}:{nextCursor:i}}}function wi(t){if(t===void 0||t.trim()===``)return 0;let n=Number(t);if(Number.isInteger(n)&&n>=0)return n;throw new e(`INVALID_ARGS`,`events cursor must be a non-negative integer string.`)}function Ti(t){if(t===void 0||typeof t==`string`&&t.trim()===``)return 100;let n=typeof t==`string`?Number(t):t;if(Number.isInteger(n)&&n>=1&&n<=500)return n;throw new e(`INVALID_ARGS`,`events limit must be between 1 and 500.`)}function Ei(e){try{let t=Di(JSON.parse(e));return t?Oi(t):void 0}catch{return}}function Di(e){if(n(e)&&e.version===1&&typeof e.ts==`string`&&typeof e.session==`string`&&ki(e.kind))return e}function Oi(e){let t=n(e.details)?e.details:void 0;return{version:1,ts:e.ts,session:e.session,kind:e.kind,...typeof e.requestId==`string`?{requestId:e.requestId}:{},...typeof e.command==`string`?{command:e.command}:{},...Ai(e.status)?{status:e.status}:{},...typeof e.summary==`string`?{summary:e.summary}:{},...t?{details:t}:{}}}function ki(e){return e===`request.started`||e===`request.finished`||e===`action.recorded`}function Ai(e){return e===`ok`||e===`error`}const ji=36e5;var Mi=class{sessions=new Map;acceptingSessions=!0;runtimeHints=new Map;sessionsDir;scriptWriter;constructor(e){this.sessionsDir=e,this.scriptWriter=new Xt(e)}get(e){return this.sessions.get(e)?.current}closeAdmission(){this.acceptingSessions=!1}assertAdmissionOpen(t){if(!this.acceptingSessions)throw new e(`COMMAND_FAILED`,`Daemon is shutting down`,{reason:`daemon_shutting_down`,session:t})}assertPublishable(t){if(this.assertAdmissionOpen(t),this.sessions.has(t))throw new e(`COMMAND_FAILED`,`Session address is already occupied`,{reason:`session_address_occupied`,session:t})}publish(e,t){this.assertPublishable(e);let n={current:t};return this.sessions.set(e,n),this.clearIdleExpiryTombstone(e),this.captureRef(e,n)}resolveCurrent(e){let t=this.sessions.get(e.address);return t===e.lifetime?t.current:void 0}refresh(e){let t=this.sessions.get(e.address);return t===e.lifetime?this.captureRef(e.address,t):e}requireCurrent(t){let n=this.resolveCurrent(t);if(!n)throw new e(`COMMAND_FAILED`,`Session lifetime has ended`,{reason:`session_lifetime_ended`,session:t.address,hint:`Open a new session before retrying the command.`});return n}update(e,t){let n=this.requireCurrent(e),r=this.sessions.get(e.address),i=typeof t==`function`?t(n):t,a={...n,...i};return r.current=a,a}retire(e){return this.resolveCurrent(e)?(this.runtimeHints.delete(e.address),this.sessions.delete(e.address)):!1}captureRef(e,t){return Object.freeze({address:e,session:t.current,lifetime:t})}*values(){for(let e of this.sessions.values())yield e.current}toArray(){return Array.from(this.values())}lookup(e){let t=this.sessions.get(e);return t?this.captureRef(e,t):void 0}findByDevice(e){for(let[t,n]of this.sessions)if(n.current.device.id===e)return this.captureRef(t,n)}listRefs(){return Array.from(this.sessions,([e,t])=>this.captureRef(e,t))}getRuntimeHints(e){return this.runtimeHints.get(e)}setRuntimeHints(e,t){t?this.runtimeHints.set(e,t):this.runtimeHints.delete(e)}clearRuntimeHints(e){return this.requireCurrent(e),this.runtimeHints.delete(e.address)}recordAction(e,t){let n=wt(this.requireCurrent(e),t);n&&yi(this.resolveEventLogPath(e.address),e.address,n)}recordEvent(e,t){hi(this.resolveEventLogPath(e),e,t)}readEvents(e,t={}){return Si(this.resolveEventLogPath(e),t)}async flushEvents(e){await gi(e?this.resolveEventLogPath(e):void 0)}writeSessionLog(e,t){let n=this.requireCurrent(e),r=this.scriptWriter.write(n,t);return r.written&&a({level:`info`,phase:`session_script_written`,data:{session:n.name,path:r.path}}),r}finalizeRepairTeardown(e){let t=this.resolveCurrent(e);if(!t)return;this.recordRepairFinalizeCloseIfCommitting(e);let n=this.writeSessionLog(e,{force:je(t,void 0)});St(t)&&(!n.written&&n.error?this.writeRepairTombstone(e,ji,{code:String(n.error.code),message:n.error.message}):this.writeRepairTombstone(e))}recordRepairFinalizeCloseIfCommitting(e){let t=this.requireCurrent(e),n=t.scriptPublication??m;h(n)&&this.recordAction(e,{command:`close`,positionals:[],flags:{},result:{session:t.name,...Ue(`Closed: ${t.name}`)}})}writeRepairTombstone(e,t=ji,n){let r=this.resolveCurrent(e);if(r)try{let i=this.resolveSessionDir(e.address);y.mkdirSync(i,{recursive:!0});let a={owner:e.address,reapedAt:Date.now(),expiresAt:Date.now()+t,...Ct(r)?{sourcePath:Ct(r)}:{},...n?{commitFailure:n}:{}};y.writeFileSync(this.repairTombstonePath(e.address),`${JSON.stringify(a)}\n`)}catch(t){a({level:`warn`,phase:`repair_tombstone_write_failed`,data:{session:e.address,error:t instanceof Error?t.message:String(t)}})}}readRepairTombstone(e){return nt(this.repairTombstonePath(e),e)}clearRepairTombstone(e){rt(this.repairTombstonePath(e),e)}noteSessionActivity(e,t=Date.now()){let n=this.get(e);n&&(n.lastActivityAtMs=t)}writeIdleExpiryTombstone(e,t){try{y.mkdirSync(this.resolveSessionDir(e),{recursive:!0}),y.writeFileSync(w(this.resolveSessionDir(e)),`${JSON.stringify(t)}\n`)}catch(t){a({level:`warn`,phase:`idle_expiry_tombstone_write_failed`,data:{session:e,error:t instanceof Error?t.message:String(t)}})}}readIdleExpiryTombstone(e){if(!Ye(e))return;let t=Lt(w(this.resolveSessionDir(e)));return t?.owner===e?t:void 0}clearIdleExpiryTombstone(e){try{y.rmSync(w(this.resolveSessionDir(e)),{force:!0})}catch(t){a({level:`warn`,phase:`idle_expiry_tombstone_clear_failed`,data:{session:e,error:t instanceof Error?t.message:String(t)}})}}repairTombstonePath(e){return tt(this.resolveSessionDir(e))}defaultTracePath(e){let t=Xe(e.name),n=new Date().toISOString().replaceAll(/[:.]/g,`-`);return b.join(this.sessionsDir,`${t}-${n}.trace.log`)}resolveSessionDir(e){return Qe(this.sessionsDir,e)}resolveDaemonStateDir(){return b.dirname(this.sessionsDir)}ensureSessionDir(e){let t=this.resolveSessionDir(e);return y.mkdirSync(t,{recursive:!0}),t}resolveAppLogPath(e){return $e(this.sessionsDir,e)}resolveAppLogPidPath(e){return et(this.sessionsDir,e)}resolveEventLogPath(e){return pi(this.resolveSessionDir(e))}};async function Q(e){let{resolveInventoryDeviceSelection:t}=await import(`./device-selection-resolver.js`).then(e=>e.t);return await t(e)}const $=new ut;function Ni(t,n){return!ee(n)&&t instanceof e&&t.code===`DEVICE_NOT_FOUND`}function Pi(e,t){return!ee(e)&&(!e.platform||e.platform===`apple`||e.platform===`ios`)&&e.target!==`desktop`&&(!t||t.kind===`device`)}async function Fi(e,t={}){return(await Ii(e,t)).device}async function Ii(e,t={}){let n={...zi(e),androidAvdSelection:t.androidAvdSelection??`running-only`},{iosSimulatorSetPath:r,...a}=n,o=Ui(n,t),s={platform:n.platform,target:e.target,cacheHit:!1};return await i(`resolve_target_device`,async()=>{let e=Vi(o);if(e)return s.cacheHit=!0,e;let i=await ct(n),l=[...i.devices];if(c(a.platform)&&i.source===`local`){let e=await Li(l,a,{simulatorSetPath:r,appleSimulatorAppTarget:t.appleSimulatorAppTarget});return Hi(o,e)}return Hi(o,await Q({devices:l,selector:a,source:i.source}))},s)}async function Li(t,n,r){let i;try{i=await Q({devices:t,selector:n,source:`local`,appleSimulatorAppTarget:r.appleSimulatorAppTarget})}catch(e){if(!Ni(e,n))throw e}let a=await Ri(n,r,i?.device);if(a)return a;if(i)return i;throw new e(`DEVICE_NOT_FOUND`,`No devices found`,{selector:n})}async function Ri(e,t,n){if(Pi(e,n))try{return await Q({devices:await lt({platform:e.platform??`ios`,target:e.target,iosSimulatorSetPath:t.simulatorSetPath,kind:`simulator`}),selector:e,source:`local`})}catch(e){if(st(e))throw e;return}}function zi(t){let n=t.platform;if(t.target&&!n)throw new e(`INVALID_ARGS`,`Device target selector requires --platform. Use --platform ios|macos|android|vega|linux|apple with --target mobile|tv|desktop.`);let r=o({simulatorSetPath:ot(t.iosSimulatorDeviceSet),platform:n,target:t.target}),i=at(t.androidDeviceAllowlist);return{platform:n,target:t.target,deviceName:t.device,udid:t.udid,serial:t.serial,leaseId:t.leaseId,leaseProvider:t.leaseProvider,deviceKey:t.deviceKey,clientId:t.clientId,iosSimulatorSetPath:r,androidSerialAllowlist:i?Array.from(i).sort():void 0}}async function Bi(e){return $.getStore()?await e():await $.run(new Map,e)}function Vi(e){let t=$.getStore()?.get(e);if(t)return{...t,device:{...t.device}}}function Hi(e,t){return $.getStore()?.set(e,{...t,device:{...t.device}}),t}function Ui(e,t){let{appleSimulatorAppTarget:n,...r}=t;return JSON.stringify({request:e,options:r})}export{St as _,Mi as a,S as b,mi as c,Nt as d,Tt as f,xt as g,bt as h,Bi as i,Cr as l,ht as m,Fi as n,xi as o,yt as p,Ii as r,bi as s,zi as t,Un as u,_t as v,gt as x,vt as y};
|
|
4
|
+
`,o)){if(Jr(a.slice(o,t),e)===!1)return r=!0,!1;o=t+1}return n=a.slice(o),!0},end(){r||Jr(`${n}${t.end()}`,e)}}}function Jr(e,t){let n=e.endsWith(`\r`)?e.slice(0,-1):e;if(n.trim().length!==0)return t(n)}function Yr(e){try{return v.openSync(e,`r`)}catch(e){if(e.code===`ENOENT`)return;throw e}}async function Xr(e){try{return await v.promises.open(e,`r`)}catch(e){if(e.code===`ENOENT`)return;throw e}}const Zr=5242880;function Qr(e=process.env){let t=e.AGENT_DEVICE_EVENT_LOG_MAX_BYTES?.trim();if(t===void 0||!/^\d+$/.test(t))return Zr;let n=Number(t);return Number.isSafeInteger(n)&&n>0?n:Zr}function K(e){return`${e}.1`}function q(e){return`${e}.window.json`}function $r(e){let t;for(let n=0;n<3;n+=1){let n=Y(e);try{let t=ei(e);if(Y(e)===n)return t}catch(r){if(t=r,Y(e)===n)throw r}}throw t??J(e,`the window did not settle while reading`)}function ei(e){let t=K(e),n=si(e);if(n===`unverifiable`)throw J(e,`window file is invalid`);if(n===void 0)return ti(e,t);let r=n.at(-1);if(!r)throw J(e,`window file records no generation`);let i=ui(e),a=ni(e,r),o=[],s=ri({eventLogPath:e,rotatedPath:t,sidecar:n,activeStart:a,activeExists:i});return s!==void 0&&o.push({path:t,firstLineIndex:s}),i&&o.push({path:e,firstLineIndex:a}),{files:o,earliestCursor:o[0]?.firstLineIndex??a}}function ti(e,t){if(G(t)!==void 0)throw J(e,`a rotated event log exists with no window record`);return{files:ui(e)?[{path:e,firstLineIndex:0}]:[],earliestCursor:0}}function ni(e,t){let n=G(e);return n!==void 0&&n===t.firstLineDigest?t.firstLineIndex:t.firstLineIndex+t.lineCount}function ri(e){let{eventLogPath:t,rotatedPath:n,sidecar:r,activeStart:i,activeExists:a}=e,o=G(n);if(o===void 0)return;let s=r.find(e=>e.firstLineDigest===o);if(!s)throw J(t,`the rotated event log matches no window record`);let c=oi(n);if(c!==s.lineCount)throw J(t,`the rotated event log holds ${c} lines, the window recorded ${s.lineCount}`);if(a&&s.firstLineIndex+s.lineCount!==i)throw J(t,`retained event log generations are not contiguous`);return s.firstLineIndex}async function ii(e,t){let n=di(e);if(!n||n.size<t)return!1;let r=si(e);if(r===`unverifiable`)return await v.promises.rename(e,K(e)),!0;let i=await Kr(e);if(i.firstLineDigest!==void 0){let t=r??[],n=t.at(-1),a=n&&n.firstLineDigest===i.firstLineDigest?n:{firstLineIndex:n?n.firstLineIndex+n.lineCount:0,lineCount:i.lineCount,firstLineDigest:i.firstLineDigest};await li(e,(a===n?t:[...t,a]).slice(-2))}return await v.promises.rename(e,K(e)),!0}function ai(t,n){if(!(t>=n))throw new e(`COMMAND_FAILED`,`events cursor ${t} precedes the retained event log window; events before cursor ${n} were rotated out.`,{reason:`EVENT_LOG_CURSOR_EXPIRED`,cursor:t,earliestCursor:n,hint:`Resume with cursor ${n}, the oldest retained event; earlier events are no longer available.`})}function J(t,n){return new e(`COMMAND_FAILED`,`Session event log window cannot be verified: ${n}.`,{reason:`EVENT_LOG_WINDOW_UNVERIFIED`,path:t,hint:`Cursor positions for this session cannot be resolved. Delete ${t}, ${K(t)}, and ${q(t)} to restart the timeline, or read the files directly.`})}function oi(e){let t=0;return W(e,()=>{t+=1}),t}function Y(e){return[X(q(e)),X(e),X(K(e))].join(`|`)}function X(e){try{let t=v.lstatSync(e);return`${t.ino}:${t.size}:${t.mtimeMs}`}catch{return`absent`}}function si(e){let t;try{t=v.readFileSync(q(e),`utf8`)}catch(e){return e.code===`ENOENT`?void 0:`unverifiable`}try{let e=JSON.parse(t);if(!n(e)||e.version!==2)return`unverifiable`;let{generations:r}=e;if(!Array.isArray(r)||r.length===0)return`unverifiable`;let i=r.map(ci);return i.every(e=>e!==void 0)?i:`unverifiable`}catch{return`unverifiable`}}function ci(e){if(!n(e))return;let{firstLineIndex:t,lineCount:r,firstLineDigest:i}=e;if(!(!Number.isSafeInteger(t)||t<0)&&!(!Number.isSafeInteger(r)||r<0)&&typeof i==`string`&&i.length!==0)return{firstLineIndex:t,lineCount:r,firstLineDigest:i}}async function li(e,t){let n=q(e),r=`${n}.${process.pid}.tmp`;await v.promises.writeFile(r,JSON.stringify({version:2,generations:t}),`utf8`),await v.promises.rename(r,n)}function ui(e){return di(e)!==void 0}function di(t){try{let n=v.lstatSync(t);if(n.isSymbolicLink())throw new e(`COMMAND_FAILED`,`Session event log must not be a symbolic link: ${t}`);return n}catch(e){if(e.code===`ENOENT`)return;throw e}}const Z=new Map,fi=new Set;function pi(e){return y.join(e,`events.ndjson`)}function mi(e){return e.command!==h.events}function hi(e,n,r){let i=t({version:1,ts:r.ts??new Date().toISOString(),session:n,...r});_i(e,`${JSON.stringify(i)}\n`)}async function gi(e){await(e?Z.get(e):Promise.all(Z.values()))}function _i(e,t){let n=(Z.get(e)??Promise.resolve()).catch(()=>void 0).then(async()=>{await vi(e),await ii(e,Qr()),await v.promises.appendFile(e,t,`utf8`)}).catch(t=>{a({level:`warn`,phase:`session_event_log_write_failed`,data:{path:e,error:t instanceof Error?t.message:String(t)}})}).finally(()=>{Z.get(e)===n&&Z.delete(e)});Z.set(e,n)}async function vi(e){let t=y.dirname(e);if(!fi.has(t))try{await v.promises.mkdir(t,{recursive:!0}),fi.add(t)}catch(t){throw a({level:`warn`,phase:`session_event_log_dir_failed`,data:{path:e,error:t instanceof Error?t.message:String(t)}}),t}}function yi(e,t,n){hi(e,t,{kind:`action.recorded`,requestId:r().requestId,command:n.command,summary:fr(n),details:pr(n)})}function bi(e){let{req:t}=e;return{kind:`request.started`,requestId:t.meta?.requestId??r().requestId,command:t.command,summary:`Started ${t.command}`}}function xi(e){let{req:t,response:n,durationMs:i}=e;if(n.ok){let e=bn(t,n.data);return{kind:`request.finished`,requestId:t.meta?.requestId??r().requestId,command:t.command,status:`ok`,summary:e.summary??`Finished ${t.command}`,details:{durationMs:i,...e.details}}}return{kind:`request.finished`,requestId:t.meta?.requestId??r().requestId,command:t.command,status:`error`,summary:`Failed ${t.command}: ${n.error.code}`,details:{durationMs:i,code:n.error.code,diagnosticId:n.error.diagnosticId}}}function Si(e,t={}){let n=wi(t.cursor),r=Ti(t.limit),i=$r(e);ai(n,i.earliestCursor);let a=Ci(i.files,n,r),o=a.lines.flatMap(e=>{let t=Ei(e);return t?[t]:[]});return{path:e,cursor:String(n),limit:r,events:o,...a.nextCursor===void 0?{}:{nextCursor:String(a.nextCursor)}}}function Ci(e,t,n){let r=[],i;for(let a of e){let e=a.firstLineIndex;if(W(a.path,a=>{if(e>=t+n)return i=t+n,!1;e>=t&&r.push(a),e+=1}),i!==void 0)break}return{lines:r,...i===void 0?{}:{nextCursor:i}}}function wi(t){if(t===void 0||t.trim()===``)return 0;let n=Number(t);if(Number.isInteger(n)&&n>=0)return n;throw new e(`INVALID_ARGS`,`events cursor must be a non-negative integer string.`)}function Ti(t){if(t===void 0||typeof t==`string`&&t.trim()===``)return 100;let n=typeof t==`string`?Number(t):t;if(Number.isInteger(n)&&n>=1&&n<=500)return n;throw new e(`INVALID_ARGS`,`events limit must be between 1 and 500.`)}function Ei(e){try{let t=Di(JSON.parse(e));return t?Oi(t):void 0}catch{return}}function Di(e){if(n(e)&&e.version===1&&typeof e.ts==`string`&&typeof e.session==`string`&&ki(e.kind))return e}function Oi(e){let t=n(e.details)?e.details:void 0;return{version:1,ts:e.ts,session:e.session,kind:e.kind,...typeof e.requestId==`string`?{requestId:e.requestId}:{},...typeof e.command==`string`?{command:e.command}:{},...Ai(e.status)?{status:e.status}:{},...typeof e.summary==`string`?{summary:e.summary}:{},...t?{details:t}:{}}}function ki(e){return e===`request.started`||e===`request.finished`||e===`action.recorded`}function Ai(e){return e===`ok`||e===`error`}const ji=36e5;var Mi=class{sessions=new Map;acceptingSessions=!0;runtimeHints=new Map;sessionsDir;scriptWriter;constructor(e){this.sessionsDir=e,this.scriptWriter=new Xt(e)}get(e){return this.sessions.get(e)?.current}closeAdmission(){this.acceptingSessions=!1}assertAdmissionOpen(t){if(!this.acceptingSessions)throw new e(`COMMAND_FAILED`,`Daemon is shutting down`,{reason:`daemon_shutting_down`,session:t})}assertPublishable(t){if(this.assertAdmissionOpen(t),this.sessions.has(t))throw new e(`COMMAND_FAILED`,`Session address is already occupied`,{reason:`session_address_occupied`,session:t})}publish(e,t){this.assertPublishable(e);let n={current:t};return this.sessions.set(e,n),this.clearIdleExpiryTombstone(e),this.captureRef(e,n)}resolveCurrent(e){let t=this.sessions.get(e.address);return t===e.lifetime?t.current:void 0}refresh(e){let t=this.sessions.get(e.address);return t===e.lifetime?this.captureRef(e.address,t):e}requireCurrent(t){let n=this.resolveCurrent(t);if(!n)throw new e(`COMMAND_FAILED`,`Session lifetime has ended`,{reason:`session_lifetime_ended`,session:t.address,hint:`Open a new session before retrying the command.`});return n}update(e,t){let n=this.requireCurrent(e),r=this.sessions.get(e.address),i=typeof t==`function`?t(n):t,a={...n,...i};return r.current=a,a}retire(e){return this.resolveCurrent(e)?(this.runtimeHints.delete(e.address),this.sessions.delete(e.address)):!1}captureRef(e,t){return Object.freeze({address:e,session:t.current,lifetime:t})}*values(){for(let e of this.sessions.values())yield e.current}toArray(){return Array.from(this.values())}lookup(e){let t=this.sessions.get(e);return t?this.captureRef(e,t):void 0}findByDevice(e){for(let[t,n]of this.sessions)if(n.current.device.id===e)return this.captureRef(t,n)}listRefs(){return Array.from(this.sessions,([e,t])=>this.captureRef(e,t))}getRuntimeHints(e){return this.runtimeHints.get(e)}setRuntimeHints(e,t){t?this.runtimeHints.set(e,t):this.runtimeHints.delete(e)}clearRuntimeHints(e){return this.requireCurrent(e),this.runtimeHints.delete(e.address)}recordAction(e,t){let n=Tt(this.requireCurrent(e),t);n&&yi(this.resolveEventLogPath(e.address),e.address,n)}recordEvent(e,t){hi(this.resolveEventLogPath(e),e,t)}readEvents(e,t={}){return Si(this.resolveEventLogPath(e),t)}async flushEvents(e){await gi(e?this.resolveEventLogPath(e):void 0)}writeSessionLog(e,t){let n=this.requireCurrent(e),r=this.scriptWriter.write(n,t);return r.written&&a({level:`info`,phase:`session_script_written`,data:{session:n.name,path:r.path}}),r}finalizeRepairTeardown(e){let t=this.resolveCurrent(e);if(!t)return;this.recordRepairFinalizeCloseIfCommitting(e);let n=this.writeSessionLog(e,{force:je(t,void 0)});Ct(t)&&(!n.written&&n.error?this.writeRepairTombstone(e,ji,{code:String(n.error.code),message:n.error.message}):this.writeRepairTombstone(e))}recordRepairFinalizeCloseIfCommitting(e){let t=this.requireCurrent(e),n=t.scriptPublication??m;ze(n)&&this.recordAction(e,{command:`close`,positionals:[],flags:{},result:{session:t.name,...Ge(`Closed: ${t.name}`)}})}writeRepairTombstone(e,t=ji,n){let r=this.resolveCurrent(e);if(r)try{let i=this.resolveSessionDir(e.address);v.mkdirSync(i,{recursive:!0});let a={owner:e.address,reapedAt:Date.now(),expiresAt:Date.now()+t,...wt(r)?{sourcePath:wt(r)}:{},...n?{commitFailure:n}:{}};v.writeFileSync(this.repairTombstonePath(e.address),`${JSON.stringify(a)}\n`)}catch(t){a({level:`warn`,phase:`repair_tombstone_write_failed`,data:{session:e.address,error:t instanceof Error?t.message:String(t)}})}}readRepairTombstone(e){return rt(this.repairTombstonePath(e),e)}clearRepairTombstone(e){it(this.repairTombstonePath(e),e)}noteSessionActivity(e,t=Date.now()){let n=this.get(e);n&&(n.lastActivityAtMs=t)}writeIdleExpiryTombstone(e,t){try{v.mkdirSync(this.resolveSessionDir(e),{recursive:!0}),v.writeFileSync(C(this.resolveSessionDir(e)),`${JSON.stringify(t)}\n`)}catch(t){a({level:`warn`,phase:`idle_expiry_tombstone_write_failed`,data:{session:e,error:t instanceof Error?t.message:String(t)}})}}readIdleExpiryTombstone(e){if(!Xe(e))return;let t=Rt(C(this.resolveSessionDir(e)));return t?.owner===e?t:void 0}clearIdleExpiryTombstone(e){try{v.rmSync(C(this.resolveSessionDir(e)),{force:!0})}catch(t){a({level:`warn`,phase:`idle_expiry_tombstone_clear_failed`,data:{session:e,error:t instanceof Error?t.message:String(t)}})}}repairTombstonePath(e){return nt(this.resolveSessionDir(e))}defaultTracePath(e){let t=Ze(e.name),n=new Date().toISOString().replaceAll(/[:.]/g,`-`);return y.join(this.sessionsDir,`${t}-${n}.trace.log`)}resolveSessionDir(e){return $e(this.sessionsDir,e)}resolveDaemonStateDir(){return y.dirname(this.sessionsDir)}ensureSessionDir(e){let t=this.resolveSessionDir(e);return v.mkdirSync(t,{recursive:!0}),t}resolveAppLogPath(e){return et(this.sessionsDir,e)}resolveAppLogPidPath(e){return tt(this.sessionsDir,e)}resolveEventLogPath(e){return pi(this.resolveSessionDir(e))}};async function Q(e){let{resolveInventoryDeviceSelection:t}=await import(`./device-selection-resolver.js`).then(e=>e.t);return await t(e)}const $=new dt;function Ni(t,n){return!ne(n)&&t instanceof e&&t.code===`DEVICE_NOT_FOUND`}function Pi(e,t){return!ne(e)&&(!e.platform||e.platform===`apple`||e.platform===`ios`)&&e.target!==`desktop`&&(!t||t.kind===`device`)}async function Fi(e,t={}){return(await Ii(e,t)).device}async function Ii(e,t={}){let n={...zi(e),androidAvdSelection:t.androidAvdSelection??`running-only`},{iosSimulatorSetPath:r,...a}=n,o=Ui(n,t),s={platform:n.platform,target:e.target,cacheHit:!1};return await i(`resolve_target_device`,async()=>{let e=Vi(o);if(e)return s.cacheHit=!0,e;let i=await lt(n),c=[...i.devices];if(l(a.platform)&&i.source===`local`){let e=await Li(c,a,{simulatorSetPath:r,appleSimulatorAppTarget:t.appleSimulatorAppTarget});return Hi(o,e)}return Hi(o,await Q({devices:c,selector:a,source:i.source}))},s)}async function Li(t,n,r){let i;try{i=await Q({devices:t,selector:n,source:`local`,appleSimulatorAppTarget:r.appleSimulatorAppTarget})}catch(e){if(!Ni(e,n))throw e}let a=await Ri(n,r,i?.device);if(a)return a;if(i)return i;throw new e(`DEVICE_NOT_FOUND`,`No devices found`,{selector:n})}async function Ri(e,t,n){if(Pi(e,n))try{return await Q({devices:await ut({platform:e.platform??`ios`,target:e.target,iosSimulatorSetPath:t.simulatorSetPath,kind:`simulator`}),selector:e,source:`local`})}catch(e){if(ct(e))throw e;return}}function zi(t){let n=t.platform;if(t.target&&!n)throw new e(`INVALID_ARGS`,`Device target selector requires --platform. Use --platform ios|macos|android|vega|linux|apple with --target mobile|tv|desktop.`);let r=s({simulatorSetPath:st(t.iosSimulatorDeviceSet),platform:n,target:t.target}),i=ot(t.androidDeviceAllowlist);return{platform:n,target:t.target,deviceName:t.device,udid:t.udid,serial:t.serial,leaseId:t.leaseId,leaseProvider:t.leaseProvider,deviceKey:t.deviceKey,clientId:t.clientId,iosSimulatorSetPath:r,androidSerialAllowlist:i?Array.from(i).sort():void 0}}async function Bi(e){return $.getStore()?await e():await $.run(new Map,e)}function Vi(e){let t=$.getStore()?.get(e);if(t)return{...t,device:{...t.device}}}function Hi(e,t){return $.getStore()?.set(e,{...t,device:{...t.device}}),t}function Ui(e,t){let{appleSimulatorAppTarget:n,...r}=t;return JSON.stringify({request:e,options:r})}export{Ct as _,Mi as a,x as b,mi as c,Pt as d,Et as f,St as g,xt as h,Bi as i,Sr as l,gt as m,Fi as n,xi as o,bt as p,Ii as r,bi as s,zi as t,Hn as u,vt as v,_t as x,yt as y};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{h as e}from"./sdk-device.js";import{f as t}from"./owner-identity.js";import"./process.js";import{n}from"./toolchain-probe.js";import{a as r}from"./runner-client.js";import{_ as i}from"./runner-disposal.js";async function a(){let e=await n(`xcodebuild`,[`-version`]);return e?s({selectedPath:await n(`xcode-select`,[`-p`]),versionLine:e}):u()}async function o(n,a){if(!(!e(n)||n.kind!==`simulator`)&&!(t()!==`darwin`||a.isProviderDevice(n)))return a.emitProgress(`Checking iOS runner build cache (${n.name})...`),await i(n)?{id:`ios-runner-cache`,status:`pass`,summary:`iOS runner artifact cached; first open skips the runner build`}:(r(n,{}),a.emitProgress(`Warming iOS runner build cache in the background (${n.name})...`),{id:`ios-runner-cache`,status:`pass`,summary:`iOS runner build started in the background; the first open gets faster once it completes`,hint:"Run `agent-device prepare ios-runner` to wait for a fully warmed runner instead."})}function s(e){return{id:`toolchain`,status:c(e),summary:l(e),evidence:{selectedPath:e.selectedPath??null,xcodeVersion:e.versionLine??null}}}function c(e){return e.versionLine?`pass`:`info`}function l(e){return e.versionLine?e.selectedPath?`Apple toolchain: ${e.versionLine}; xcode-select ${e.selectedPath}.`:`Apple toolchain: ${e.versionLine}; xcode-select path unavailable.`:`Apple toolchain: xcodebuild version check failed.`}function u(){return{id:`toolchain`,status:`info`,summary:`Apple toolchain: xcodebuild version check failed.`,hint:`Install/select Xcode and complete first launch/license setup if xcodebuild reports it.`,command:`xcodebuild -version`}}export{o as appleRunnerWarmupCheck,a as appleToolchainCheck};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{P as e}from"./sdk-contracts.js";import{r as t}from"./diagnostics.js";import"./diagnostics2.js";import{M as n,P as r,j as i}from"./sdk-device.js";import{en as a}from"./sdk-batch.js";import{k as o}from"./owner-identity.js";import{i as s}from"./verified-file.js";import"./file.js";import{r as c}from"./session-paths.js";import{i as l,n as u,t as d}from"./durable-resource.js";import f from"node:crypto";import p from"node:fs";import m from"node:path";function h(t){let n=t.read(t.resolveCurrent()??t.initialSession),r=()=>{if(t.assertAdmissionOpen(),t.read(t.requireCurrent()))throw new e(`COMMAND_FAILED`,`Session capture resource has changed`,{reason:`session_resource_changed`,session:t.address})};return Object.freeze({address:t.address,sessionDir:t.sessionDir,read:()=>{let e=t.resolveCurrent();return e!==void 0&&(n=t.read(e)),n},assertAdoptable:r,canPersist:()=>{let e=t.resolveCurrent();return e!==void 0&&t.read(e)===void 0},adopt:e=>{r(),t.write(e),n=e},clear:e=>{let r=t.resolveCurrent();if(r===void 0)return`retired`;let i=t.read(r);return n=i,i?.handle!==e.handle||i.envelope.fence.token!==e.envelope.fence.token||i.envelope.fence.generation!==e.envelope.fence.generation?`resource-changed`:(t.write(void 0),n=void 0,`cleared`)}})}function g(e,t,n){return h({address:t.address,sessionDir:e.resolveSessionDir(t.address),initialSession:t.session,resolveCurrent:()=>e.resolveCurrent(t),requireCurrent:()=>e.requireCurrent(t),assertAdmissionOpen:()=>e.assertAdmissionOpen(t.address),...n})}function ee(e,t){return g(e,t,{read:e=>e.audioProbe,write:n=>{e.update(t,{audioProbe:n})}})}function te(e,t){return g(e,t,{read:e=>e.perfCapture,write:n=>{e.update(t,{perfCapture:n})}})}function _(e,t){return g(e,t,{read:e=>e.screenRecording,write:n=>{e.update(t,{screenRecording:n})}})}function v(t,n,r){let i,a=()=>{if(i)throw t.requireCurrent(i.ref),new e(`COMMAND_FAILED`,`Recording draft has already been published`,{reason:`session_resource_changed`,session:n});t.assertPublishable(n)},o=Object.freeze({address:n,sessionDir:t.resolveSessionDir(n),read:()=>i?.binding.read(),assertAdoptable:a,canPersist:()=>!i&&t.lookup(n)===void 0,adopt:o=>{if(a(),r.screenRecording)throw new e(`COMMAND_FAILED`,`Recording draft already owns a resource`,{reason:`session_resource_changed`,session:n});let s=t.publish(n,r),c=_(t,s);c.adopt(o),i=Object.freeze({ref:s,binding:c})},clear:e=>i?.binding.clear(e)??`retired`});return Object.freeze({binding:o,requireRef:()=>{if(!i)throw TypeError(`Screen recording did not publish its session`);return i.ref}})}function y(e){return e.length===0?e:e[0].toUpperCase()+e.slice(1)}function b(e){return e.replaceAll(`-`,`_`)}async function x(e,t,n){let r={kind:`pending`};try{t.binding.assertAdoptable();let i=T(w(e,t),`active`);e.store.write(n,i),r={kind:`persisted`},t.throwIfCanceled();let a=t.pendingHandle.transfer();r={kind:`transferred`,handle:a},t.binding.adopt({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=t.binding.canPersist(),o=r.kind!==`pending`||a&&ie(e,t,n),s=re(e,t,n,await S(t,r));t.reportUndurableCleanup(t.device,!o&&s.cleanupError===void 0||s.confirmed?{confirmed:!0}:{confirmed:!1,reason:s.cleanupError instanceof Error?s.cleanupError.message:`The durable cleanup transition could not be confirmed`}),s.cleanupError!==void 0&&ce(e,t,i,s.cleanupError)}function re(e,n,r,i){try{return{confirmed:se(e,r,n.fence,i),cleanupError:i}}catch(r){return t({level:`error`,phase:`${b(e.resourceKind)}_pending_adoption_transition_failed`,data:{session:n.binding.address,transitionError:r instanceof Error?r.message:String(r)}}),{confirmed:!1,cleanupError:i??r}}}async function S(e,t){try{t.kind===`transferred`?await t.handle[Symbol.asyncDispose]():await e.pendingHandle[Symbol.asyncDispose]();return}catch(e){return e}}function ie(e,n,r){try{return e.store.write(r,ae(e,n)),!0}catch(i){try{return e.store.write(r,C(e,n,{version:0,body:{reason:`runtime-contract-invalid`}})),!0}catch(r){return t({level:`error`,phase:`${b(e.resourceKind)}_runtime_contract_tombstone_failed`,data:{session:n.binding.address,descriptorError:i instanceof Error?i.message:String(i),persistenceError:r instanceof Error?r.message:String(r)}}),!1}}}function ae(e,t){try{return T(w(e,t),`active`)}catch{return C(e,t,t.envelope.descriptor)}}function C(e,t,n){return u({resourceKind:e.resourceKind,sessionId:t.binding.address,device:i(t.device),owner:t.owner,fence:t.fence,lifecycle:`open`,descriptor:n,metadata:{phase:`runtime-contract-invalid`,runtimeContractInvalid:!0}})}function w(t,n){let r=l(n.envelope);if(r.status===`decoded`&&oe(r.envelope,n,t.resourceKind))return r.envelope;throw new e(`COMMAND_FAILED`,`${y(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 oe(e,t,n){return e.resourceKind===n&&e.sessionId===t.binding.address&&r(e.device,i(t.device))&&a(e.owner)===a(t.owner)&&e.fence.token===t.fence.token&&e.fence.generation===t.fence.generation&&e.lifecycle===`open`}function se(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 ce(e,n,r,i){t({level:`error`,phase:`${b(e.resourceKind)}_pending_adoption_cleanup_failed`,data:{session:n.binding.address,primaryError:r instanceof Error?r.message:String(r),cleanupError:i instanceof Error?i.message:String(i)}})}function T(e,t){return Object.freeze({...e,lifecycle:`open`,metadata:{...e.metadata??{},phase:t}})}async function E(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 k(e.displayName,e.deadlineMs);t.abort(n),r(n)},e.deadlineMs);s.unref?.();let c=le(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=>D(e,n,t),()=>{}).catch(()=>{})}else c.catch(()=>{})}}async function D(e,t,n){try{t.reattached.status===`active`&&await O(e,t.reattached.handle,`late_handle_cleanup_failed`,n)}finally{await O(e,t.control,`late_control_cleanup_failed`,n)}}async function le(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 O(e,r.handle,`late_handle_cleanup_failed`,t)}finally{n&&await O(e,n,`late_control_cleanup_failed`,t)}throw t}}async function O(e,t,n,r){try{await t[Symbol.asyncDispose]()}catch(t){e.onLateCleanupFailure(n,t,r)}}var k=class extends Error{deadlineMs;constructor(e,t){super(`${y(e)} recovery exceeded its ${t}ms deadline`),this.name=`DurableCaptureRecoveryDeadlineError`,this.deadlineMs=t}};const A=new Map;async function j(e){return await de(e.resourcePath,async()=>{let t=e.store.read(e.resourcePath);if(t.status!==`decoded`)throw M(e.store,t.status===`missing`?`${e.store.displayName} resource record is missing`:`${e.store.displayName} resource record is unreattachable: ${t.message}`);if(!ue(t.envelope.fence,e.expected))throw M(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 ue(e,t){return e.token===t.token&&e.generation===t.generation}async function de(e,t){let n=A.get(e)??Promise.resolve(),r,i=new Promise(e=>{r=e}),a=n.catch(()=>{}).then(()=>i);A.set(e,a),await n.catch(()=>{});try{return await t()}finally{r(),A.get(e)===a&&A.delete(e)}}function M(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 fe(t,n,r){let i=n.binding.read();if(!i)throw new e(`INVALID_ARGS`,t.messages.noActive);try{let e=await N(t,{handle:i.handle,fence:i.envelope.fence,resourcePath:r,intent:n.intent});return n.binding.clear(i),e}catch(e){let a=t.store.read(r);throw a.status===`decoded`&&a.envelope.lifecycle===`completed`&&n.binding.clear(i),e}}async function N(e,t){return await j({store:e.store,resourcePath:t.resourcePath,expected:t.fence,run:async n=>{W(n);let r=pe(n),i;try{i=await t.handle.finish(r)}catch(r){throw await P(e,n,t,r,t.intent),r}if(i.status===`completed`)return U(e,n,i),i.result;U(e,n,i);let a=H(e,i);throw await P(e,n,t,a,t.intent),a}})}async function P(e,t,n,r,i){if(i===`capture`&&e.failedFinishPolicy===`preserve-retry-material`){I(e,n,r);return}let a;try{a=await n.handle.forceCleanup()}catch(i){L(e,n,r,i,F(t,i));return}try{B(t,a)}catch(t){L(e,n,r,a.status===`cleanup-pending`?a.message??a.reason:`cleanup returned ${a.status}`,t);return}d(a)||L(e,n,r,a.message)}function F(e,t){try{B(e,{status:`cleanup-pending`,reason:`cleanup-unconfirmed`,message:R(t)});return}catch(e){return e}}function I(e,n,r){t({level:`error`,phase:`${b(e.resourceKind)}_finish_evidence_preserved`,data:{resourcePath:n.resourcePath,finishError:R(r),failedFinishPolicy:e.failedFinishPolicy}})}function L(e,n,r,i,a){t({level:`error`,phase:`${b(e.resourceKind)}_finish_cleanup_failed`,data:{resourcePath:n.resourcePath,finishError:R(r),cleanupError:i===void 0?`cleanup could not be confirmed`:R(i),...a===void 0?{}:{transitionError:R(a)}}})}function R(e){return e instanceof Error?e.message:String(e)}async function z(e,t){let n=t.binding.read();n&&(V(e,await j({store:e.store,resourcePath:t.resourcePath,expected:n.envelope.fence,run:async e=>{W(e);let t=await n.handle.forceCleanup();return B(e,t),t}})),t.binding.clear(n))}function B(e,t){e.transition(d(t)?`completed`:`open`,{metadata:{...e.envelope.metadata??{},phase:d(t)?`completed`:`cleanup-pending`,cleanupStatus:t.status,...t.status===`cleanup-pending`?{cleanupPendingReason:t.reason,...t.message?{cleanupPendingMessage:t.message}:{}}:{}}})}function V(e,t){if(!d(t))throw H(e,t)}function H(t,n){return new e(`COMMAND_FAILED`,n.message??`${y(t.displayName)} cleanup could not be confirmed`,{reason:n.reason,retriable:n.reason!==`ownership-fence-lost`,hint:t.messages.cleanupPendingHint})}function U(e,t,n){if(n.status===`completed`){t.transition(`completed`,{metadata:{...t.envelope.metadata??{},...e.completionMetadata(n.result),phase:`completed`}});return}B(t,n)}function pe(e){return Object.freeze({learned:e.envelope.metadata,record:t=>{e.transition(`open`,{metadata:{...e.envelope.metadata??{},...t}})}})}function W(e){e.transition(`open`,{metadata:{...e.envelope.metadata??{},phase:`completing`}})}async function me(e){let t=e.definition.store.list(e.sessionsDir),n=[];for(let r of t)n.push(await G(e,r));return{scanned:t.length,recovered:n.filter(e=>e===`recovered`).length,retained:n.filter(e=>e===`retained`).length}}async function G(e,t){let n=K(e,t);if(n.status!==`recoverable`)return n.status;try{return await he(e,t,n.envelope,e.perRecordDeadlineMs??5e3)?`recovered`:`retained`}catch(n){return Y(e,n instanceof k?`timed_out`:`failed`,t,{error:n instanceof Error?n.message:String(n),...n instanceof k?{deadlineMs:n.deadlineMs}:{}}),`retained`}}function K(e,t){let n=e.definition.store.read(t);if(n.status===`unreattachable`)return Y(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 m.resolve(t)===m.resolve(r)?{status:`recoverable`,envelope:n.envelope}:(Y(e,`session_path_mismatch`,t,{envelopeSessionId:n.envelope.sessionId,canonicalPath:r}),{status:`retained`})}async function he(e,t,n,r){return await ge(e,t,n,await E({displayName:e.definition.displayName,envelope:n,scope:e.scope,deadlineMs:r,acquireControl:e.acquireControl,onLateCleanupFailure:(n,r,i)=>Y(e,n,t,{error:r instanceof Error?r.message:String(r),primaryError:i instanceof Error?i.message:String(i)})}))}async function ge(e,t,n,r){try{switch(r.reattached.status){case`active`:{let i=r.reattached.handle,a=await j({store:e.definition.store,resourcePath:t,expected:n.fence,run:async e=>{_e(e);let t=await i.forceCleanup();return B(e,t),t}});return d(a)}case`completed`:return await q(e,t,n,{...e.definition.completionMetadata(r.reattached.result)}),!0;case`missing`:return await q(e,t,n,{recoveryStatus:`already-missing`}),!0;case`unreattachable`:{if(!J(r.reattached.reason))return Y(e,`retained`,t,{reason:r.reattached.reason,message:r.reattached.message}),!1;let i=await r.control.cleanup(n);return await j({store:e.definition.store,resourcePath:t,expected:n.fence,run:async e=>B(e,i)}),d(i)}}}finally{await r.control[Symbol.asyncDispose]()}}async function q(e,t,n,r){await j({store:e.definition.store,resourcePath:t,expected:n.fence,run:async e=>{e.transition(`completed`,{metadata:{...e.envelope.metadata??{},phase:`completed`,...r}})}})}function _e(e){e.transition(`open`,{metadata:{...e.envelope.metadata??{},phase:`completing`}})}function J(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 Y(e,n,r,i){let a={phase:`${b(e.definition.resourceKind)}_recovery_${n}`,resourcePath:r,data:i};e.onDiagnostic?e.onDiagnostic(a):t({level:`warn`,phase:a.phase,data:{resourcePath:r,...i}})}async function ve(t,n){let r=t.store.read(n.resourcePath);if(r.status!==`decoded`||r.envelope.lifecycle!==`open`)throw ye(t,r.status);let i=r.envelope,a=await E({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:`${b(t.resourceKind)}_recovery_${e}`,data:{resourcePath:n.resourcePath,error:X(r),primaryError:X(i)}})});try{switch(a.reattached.status){case`active`:return await N(t,{handle:a.reattached.handle,fence:i.fence,resourcePath:n.resourcePath,intent:`capture`});case`completed`:{let e=a.reattached.result;return await j({store:t.store,resourcePath:n.resourcePath,expected:i.fence,run:async n=>{U(t,n,{status:`completed`,result:e,alreadyCompleted:!0})}}),e}case`missing`:throw new e(`COMMAND_FAILED`,`${y(t.displayName)} is missing`,{reason:`resource-missing`,hint:t.messages.cleanupPendingHint});case`unreattachable`:if(J(a.reattached.reason)){let e=await a.control.cleanup(i);await j({store:t.store,resourcePath:n.resourcePath,expected:i.fence,run:async t=>B(t,e)}),V(t,e)}throw new e(`COMMAND_FAILED`,a.reattached.message??`${y(t.displayName)} cannot be reattached`,{reason:a.reattached.reason,hint:t.messages.cleanupPendingHint})}}finally{await a.control[Symbol.asyncDispose]()}}function ye(t,n){return new e(`INVALID_ARGS`,n===`missing`?t.messages.noActive:`${y(t.displayName)} recovery record is not open`)}function X(e){return e instanceof Error?e.message:String(e)}function be(e){Se(e.fileName);let t=t=>m.join(t,e.fileName);return Object.freeze({resourceKind:e.resourceKind,displayName:e.displayName,resolvePath:t,read(t){let n,r;try{if(n=s(t),n===void 0)return{status:`missing`};r=JSON.parse(p.readFileSync(n,`utf8`))}catch(t){return Q(t)?{status:`missing`}:Z(we(t,e.displayName))}finally{n!==void 0&&p.closeSync(n)}return xe(l(r),e.resourceKind)},write(e,t){let n=m.dirname(e);p.mkdirSync(n,{recursive:!0}),o({destination:e,contents:`${JSON.stringify(t)}\n`})},list(e){let n;try{n=p.readdirSync(e,{withFileTypes:!0})}catch{return[]}return n.filter(e=>e.isDirectory()).map(n=>t(m.join(e,n.name))).filter(Ce).sort()}})}function xe(e,t){return e.status===`decoded`?e.envelope.resourceKind===t?{status:`decoded`,envelope:e.envelope}:Z(`Expected ${t} resource record, received ${e.envelope.resourceKind}`):e}function Se(e){if(e.length===0||m.basename(e)!==e)throw TypeError(`Durable capture resource fileName must be one file name`)}function Ce(e){try{return p.lstatSync(e),!0}catch(e){return!Q(e)}}function Z(e){return{status:`unreattachable`,reason:`descriptor-invalid`,message:e}}function Q(e){return typeof e==`object`&&!!e&&`code`in e&&e.code===`ENOENT`}function we(e,t){return e instanceof Error?e.message:`${t} resource record is invalid`}function Te(e,t){t.admissionLedger.assertStartAllowed(t.device),Ee(e,t.resourcePath,t.device);let n=e.store.read(t.resourcePath);return Object.freeze({token:f.randomUUID(),generation:n.status===`decoded`?n.envelope.fence.generation+1:1})}function Ee(t,r,a){let o=n(i(a));for(let i of t.store.list(m.dirname(m.dirname(r)))){let a=t.store.read(i);if(a.status===`unreattachable`)throw new e(`COMMAND_FAILED`,`${y($(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`&&(i===r||n(a.envelope.device)===o))throw new e(`COMMAND_FAILED`,`${y($(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 $(e){return/^[aeiou]/i.test(e)?`an`:`a`}function De(e){let t=(t,n)=>e.store.resolvePath(t.resolveSessionDir(n)),n=t=>({definition:e,resolveSessionDir:e=>m.join(t.sessionsDir,c(e)),...t});return Object.freeze({store:e.store,resourcePath:t,createNextFence(t){return Te(e,t)},adoptStarted(t){return x(e,{...t,reportUndurableCleanup:(e,n)=>{n.confirmed?t.admissionLedger.clearUndurableCleanup(e):t.admissionLedger.blockUndurableCleanup(e,n.reason)}},e.store.resolvePath(t.binding.sessionDir))},finishLive(t){return fe(e,t,e.store.resolvePath(t.binding.sessionDir))},finishRecovered(t){return ve(e,t)},forceCleanupLive(t){return z(e,{...t,resourcePath:e.store.resolvePath(t.binding.sessionDir)})},recoverAll(e){return me(n(e))},recoverOne(e,t){return G(n(e),t)}})}export{g as a,ee as i,be as n,te as o,v as r,_ as s,De as t};
|
|
1
|
+
import{H as e,P as t}from"./sdk-contracts.js";import{r as n}from"./diagnostics.js";import"./diagnostics2.js";import{I as r,N as i,P as a}from"./sdk-device.js";import{en as o}from"./sdk-batch.js";import{A as s}from"./owner-identity.js";import{i as c}from"./verified-file.js";import"./file.js";import{r as l}from"./session-paths.js";import{i as u,n as d,t as f}from"./durable-resource.js";import p from"node:crypto";import m from"node:fs";import h from"node:path";function g(e){let n=e.read(e.resolveCurrent()??e.initialSession),r=()=>{if(e.assertAdmissionOpen(),e.read(e.requireCurrent()))throw new t(`COMMAND_FAILED`,`Session capture resource has changed`,{reason:`session_resource_changed`,session:e.address})};return Object.freeze({address:e.address,sessionDir:e.sessionDir,read:()=>{let t=e.resolveCurrent();return t!==void 0&&(n=e.read(t)),n},assertAdoptable:r,canPersist:()=>{let t=e.resolveCurrent();return t!==void 0&&e.read(t)===void 0},adopt:t=>{r(),e.write(t),n=t},clear:t=>{let r=e.resolveCurrent();if(r===void 0)return`retired`;let i=e.read(r);return n=i,i?.handle!==t.handle||i.envelope.fence.token!==t.envelope.fence.token||i.envelope.fence.generation!==t.envelope.fence.generation?`resource-changed`:(e.write(void 0),n=void 0,`cleared`)}})}function _(e,t,n){return g({address:t.address,sessionDir:e.resolveSessionDir(t.address),initialSession:t.session,resolveCurrent:()=>e.resolveCurrent(t),requireCurrent:()=>e.requireCurrent(t),assertAdmissionOpen:()=>e.assertAdmissionOpen(t.address),...n})}function ee(e,t){return _(e,t,{read:e=>e.audioProbe,write:n=>{e.update(t,{audioProbe:n})}})}function te(e,t){return _(e,t,{read:e=>e.perfCapture,write:n=>{e.update(t,{perfCapture:n})}})}function v(e,t){return _(e,t,{read:e=>e.screenRecording,write:n=>{e.update(t,{screenRecording:n})}})}function y(e,n,r){let i,a=()=>{if(i)throw e.requireCurrent(i.ref),new t(`COMMAND_FAILED`,`Recording draft has already been published`,{reason:`session_resource_changed`,session:n});e.assertPublishable(n)},o=Object.freeze({address:n,sessionDir:e.resolveSessionDir(n),read:()=>i?.binding.read(),assertAdoptable:a,canPersist:()=>!i&&e.lookup(n)===void 0,adopt:o=>{if(a(),r.screenRecording)throw new t(`COMMAND_FAILED`,`Recording draft already owns a resource`,{reason:`session_resource_changed`,session:n});let s=e.publish(n,r),c=v(e,s);c.adopt(o),i=Object.freeze({ref:s,binding:c})},clear:e=>i?.binding.clear(e)??`retired`});return Object.freeze({binding:o,requireRef:()=>{if(!i)throw TypeError(`Screen recording did not publish its session`);return i.ref}})}function b(e){return e.length===0?e:e[0].toUpperCase()+e.slice(1)}function x(e){return e.replaceAll(`-`,`_`)}async function ne(e,t,n){let r={kind:`pending`};try{t.binding.assertAdoptable();let i=O(E(e,t),`active`);e.store.write(n,i),r={kind:`persisted`},t.throwIfCanceled();let a=t.pendingHandle.transfer();r={kind:`transferred`,handle:a},t.binding.adopt({handle:a,envelope:i})}catch(i){throw await re(e,t,n,r,i),i}}async function re(e,t,n,r,i){let a=t.binding.canPersist(),o=r.kind!==`pending`||a&&C(e,t,n),s=S(e,t,n,await ie(t,r));t.reportUndurableCleanup(t.device,!o&&s.cleanupError===void 0||s.confirmed?{confirmed:!0}:{confirmed:!1,reason:s.cleanupError instanceof Error?s.cleanupError.message:`The durable cleanup transition could not be confirmed`}),s.cleanupError!==void 0&&D(e,t,i,s.cleanupError)}function S(e,t,r,i){try{return{confirmed:oe(e,r,t.fence,i),cleanupError:i}}catch(r){return n({level:`error`,phase:`${x(e.resourceKind)}_pending_adoption_transition_failed`,data:{session:t.binding.address,transitionError:r instanceof Error?r.message:String(r)}}),{confirmed:!1,cleanupError:i??r}}}async function ie(e,t){try{t.kind===`transferred`?await t.handle[Symbol.asyncDispose]():await e.pendingHandle[Symbol.asyncDispose]();return}catch(e){return e}}function C(e,t,r){try{return e.store.write(r,w(e,t)),!0}catch(i){try{return e.store.write(r,T(e,t,{version:0,body:{reason:`runtime-contract-invalid`}})),!0}catch(r){return n({level:`error`,phase:`${x(e.resourceKind)}_runtime_contract_tombstone_failed`,data:{session:t.binding.address,descriptorError:i instanceof Error?i.message:String(i),persistenceError:r instanceof Error?r.message:String(r)}}),!1}}}function w(e,t){try{return O(E(e,t),`active`)}catch{return T(e,t,t.envelope.descriptor)}}function T(e,t,n){return d({resourceKind:e.resourceKind,sessionId:t.binding.address,device:i(t.device),owner:t.owner,fence:t.fence,lifecycle:`open`,descriptor:n,metadata:{phase:`runtime-contract-invalid`,runtimeContractInvalid:!0}})}function E(e,n){let r=u(n.envelope);if(r.status===`decoded`&&ae(r.envelope,n,e.resourceKind))return r.envelope;throw new t(`COMMAND_FAILED`,`${b(e.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,n){return e.resourceKind===n&&e.sessionId===t.binding.address&&r(e.device,i(t.device))&&o(e.owner)===o(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 D(e,t,r,i){n({level:`error`,phase:`${x(e.resourceKind)}_pending_adoption_cleanup_failed`,data:{session:t.binding.address,primaryError:r instanceof Error?r.message:String(r),cleanupError:i instanceof Error?i.message:String(i)}})}function O(e,t){return Object.freeze({...e,lifecycle:`open`,metadata:{...e.metadata??{},phase:t}})}async function k(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 j(e.displayName,e.deadlineMs);t.abort(n),r(n)},e.deadlineMs);s.unref?.();let c=ce(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=>se(e,n,t),()=>{}).catch(()=>{})}else c.catch(()=>{})}}async function se(e,t,n){try{t.reattached.status===`active`&&await A(e,t.reattached.handle,`late_handle_cleanup_failed`,n)}finally{await A(e,t.control,`late_control_cleanup_failed`,n)}}async function ce(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 A(e,r.handle,`late_handle_cleanup_failed`,t)}finally{n&&await A(e,n,`late_control_cleanup_failed`,t)}throw t}}async function A(e,t,n,r){try{await t[Symbol.asyncDispose]()}catch(t){e.onLateCleanupFailure(n,t,r)}}var j=class extends Error{deadlineMs;constructor(e,t){super(`${b(e)} recovery exceeded its ${t}ms deadline`),this.name=`DurableCaptureRecoveryDeadlineError`,this.deadlineMs=t}};const M=new Map;async function N(e){return await ue(e.resourcePath,async()=>{let t=e.store.read(e.resourcePath);if(t.status!==`decoded`)throw P(e.store,t.status===`missing`?`${e.store.displayName} resource record is missing`:`${e.store.displayName} resource record is unreattachable: ${t.message}`);if(!le(t.envelope.fence,e.expected))throw P(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 le(e,t){return e.token===t.token&&e.generation===t.generation}async function ue(e,t){let n=M.get(e)??Promise.resolve(),r,i=new Promise(e=>{r=e}),a=n.catch(()=>{}).then(()=>i);M.set(e,a),await n.catch(()=>{});try{return await t()}finally{r(),M.get(e)===a&&M.delete(e)}}function P(e,n){return new t(`COMMAND_FAILED`,n,{reason:`ownership-fence-lost`,retriable:!1,hint:`Use the current ${e.displayName.toLowerCase()} resource owner or retain the recovery record for manual recovery.`})}async function F(e,n,r){let i=n.binding.read();if(!i)throw new t(`INVALID_ARGS`,e.messages.noActive);try{let t=await I(e,{handle:i.handle,fence:i.envelope.fence,resourcePath:r,intent:n.intent});return n.binding.clear(i),t}catch(t){let a=e.store.read(r);throw a.status===`decoded`&&a.envelope.lifecycle===`completed`&&n.binding.clear(i),t}}async function I(e,t){return await N({store:e.store,resourcePath:t.resourcePath,expected:t.fence,run:async n=>{K(n);let r=de(n),i;try{i=await t.handle.finish(r)}catch(r){throw await L(e,n,t,r,t.intent),r}if(i.status===`completed`)return G(e,n,i),i.result;G(e,n,i);let a=W(e,i);throw await L(e,n,t,a,t.intent),a}})}async function L(e,t,n,r,i){if(i===`capture`&&e.failedFinishPolicy===`preserve-retry-material`){z(e,n,r);return}let a;try{a=await n.handle.forceCleanup()}catch(i){B(e,n,r,i,R(t,i));return}try{H(t,a)}catch(t){B(e,n,r,a.status===`cleanup-pending`?a.message??a.reason:`cleanup returned ${a.status}`,t);return}f(a)||B(e,n,r,a.message)}function R(t,n){try{H(t,{status:`cleanup-pending`,reason:`cleanup-unconfirmed`,message:e(n)});return}catch(e){return e}}function z(t,r,i){n({level:`error`,phase:`${x(t.resourceKind)}_finish_evidence_preserved`,data:{resourcePath:r.resourcePath,finishError:e(i),failedFinishPolicy:t.failedFinishPolicy}})}function B(t,r,i,a,o){n({level:`error`,phase:`${x(t.resourceKind)}_finish_cleanup_failed`,data:{resourcePath:r.resourcePath,finishError:e(i),cleanupError:a===void 0?`cleanup could not be confirmed`:e(a),...o===void 0?{}:{transitionError:e(o)}}})}async function V(e,t){let n=t.binding.read();n&&(U(e,await N({store:e.store,resourcePath:t.resourcePath,expected:n.envelope.fence,run:async e=>{K(e);let t=await n.handle.forceCleanup();return H(e,t),t}})),t.binding.clear(n))}function H(e,t){e.transition(f(t)?`completed`:`open`,{metadata:{...e.envelope.metadata??{},phase:f(t)?`completed`:`cleanup-pending`,cleanupStatus:t.status,...t.status===`cleanup-pending`?{cleanupPendingReason:t.reason,...t.message?{cleanupPendingMessage:t.message}:{}}:{}}})}function U(e,t){if(!f(t))throw W(e,t)}function W(e,n){return new t(`COMMAND_FAILED`,n.message??`${b(e.displayName)} cleanup could not be confirmed`,{reason:n.reason,retriable:n.reason!==`ownership-fence-lost`,hint:e.messages.cleanupPendingHint})}function G(e,t,n){if(n.status===`completed`){t.transition(`completed`,{metadata:{...t.envelope.metadata??{},...e.completionMetadata(n.result),phase:`completed`}});return}H(t,n)}function de(e){return Object.freeze({learned:e.envelope.metadata,record:t=>{e.transition(`open`,{metadata:{...e.envelope.metadata??{},...t}})}})}function K(e){e.transition(`open`,{metadata:{...e.envelope.metadata??{},phase:`completing`}})}async function fe(e){let t=e.definition.store.list(e.sessionsDir),n=[];for(let r of t)n.push(await q(e,r));return{scanned:t.length,recovered:n.filter(e=>e===`recovered`).length,retained:n.filter(e=>e===`retained`).length}}async function q(e,t){let n=pe(e,t);if(n.status!==`recoverable`)return n.status;try{return await me(e,t,n.envelope,e.perRecordDeadlineMs??5e3)?`recovered`:`retained`}catch(n){return X(e,n instanceof j?`timed_out`:`failed`,t,{error:n instanceof Error?n.message:String(n),...n instanceof j?{deadlineMs:n.deadlineMs}:{}}),`retained`}}function pe(e,t){let n=e.definition.store.read(t);if(n.status===`unreattachable`)return X(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}:(X(e,`session_path_mismatch`,t,{envelopeSessionId:n.envelope.sessionId,canonicalPath:r}),{status:`retained`})}async function me(e,t,n,r){return await he(e,t,n,await k({displayName:e.definition.displayName,envelope:n,scope:e.scope,deadlineMs:r,acquireControl:e.acquireControl,onLateCleanupFailure:(n,r,i)=>X(e,n,t,{error:r instanceof Error?r.message:String(r),primaryError:i instanceof Error?i.message:String(i)})}))}async function he(e,t,n,r){try{switch(r.reattached.status){case`active`:{let i=r.reattached.handle,a=await N({store:e.definition.store,resourcePath:t,expected:n.fence,run:async e=>{ge(e);let t=await i.forceCleanup();return H(e,t),t}});return f(a)}case`completed`:return await J(e,t,n,{...e.definition.completionMetadata(r.reattached.result)}),!0;case`missing`:return await J(e,t,n,{recoveryStatus:`already-missing`}),!0;case`unreattachable`:{if(!Y(r.reattached.reason))return X(e,`retained`,t,{reason:r.reattached.reason,message:r.reattached.message}),!1;let i=await r.control.cleanup(n);return await N({store:e.definition.store,resourcePath:t,expected:n.fence,run:async e=>H(e,i)}),f(i)}}}finally{await r.control[Symbol.asyncDispose]()}}async function J(e,t,n,r){await N({store:e.definition.store,resourcePath:t,expected:n.fence,run:async e=>{e.transition(`completed`,{metadata:{...e.envelope.metadata??{},phase:`completed`,...r}})}})}function ge(e){e.transition(`open`,{metadata:{...e.envelope.metadata??{},phase:`completing`}})}function Y(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 X(e,t,r,i){let a={phase:`${x(e.definition.resourceKind)}_recovery_${t}`,resourcePath:r,data:i};e.onDiagnostic?e.onDiagnostic(a):n({level:`warn`,phase:a.phase,data:{resourcePath:r,...i}})}async function _e(n,r){let i=n.store.read(r.resourcePath);if(i.status!==`decoded`||i.envelope.lifecycle!==`open`)throw ve(n,i.status);let a=i.envelope,o=await k({displayName:n.displayName,envelope:a,scope:r.scope,deadlineMs:r.deadlineMs??5e3,acquireControl:r.acquireControl,onLateCleanupFailure:(t,i,a)=>r.scope.diagnostics.emit({level:`error`,phase:`${x(n.resourceKind)}_recovery_${t}`,data:{resourcePath:r.resourcePath,error:e(i),primaryError:e(a)}})});try{switch(o.reattached.status){case`active`:return await I(n,{handle:o.reattached.handle,fence:a.fence,resourcePath:r.resourcePath,intent:`capture`});case`completed`:{let e=o.reattached.result;return await N({store:n.store,resourcePath:r.resourcePath,expected:a.fence,run:async t=>{G(n,t,{status:`completed`,result:e,alreadyCompleted:!0})}}),e}case`missing`:throw new t(`COMMAND_FAILED`,`${b(n.displayName)} is missing`,{reason:`resource-missing`,hint:n.messages.cleanupPendingHint});case`unreattachable`:if(Y(o.reattached.reason)){let e=await o.control.cleanup(a);await N({store:n.store,resourcePath:r.resourcePath,expected:a.fence,run:async t=>H(t,e)}),U(n,e)}throw new t(`COMMAND_FAILED`,o.reattached.message??`${b(n.displayName)} cannot be reattached`,{reason:o.reattached.reason,hint:n.messages.cleanupPendingHint})}}finally{await o.control[Symbol.asyncDispose]()}}function ve(e,n){return new t(`INVALID_ARGS`,n===`missing`?e.messages.noActive:`${b(e.displayName)} recovery record is not open`)}function ye(e){xe(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=c(t),n===void 0)return{status:`missing`};r=JSON.parse(m.readFileSync(n,`utf8`))}catch(t){return Q(t)?{status:`missing`}:Z(Ce(t,e.displayName))}finally{n!==void 0&&m.closeSync(n)}return be(u(r),e.resourceKind)},write(e,t){let n=h.dirname(e);m.mkdirSync(n,{recursive:!0}),s({destination:e,contents:`${JSON.stringify(t)}\n`})},list(e){let n;try{n=m.readdirSync(e,{withFileTypes:!0})}catch{return[]}return n.filter(e=>e.isDirectory()).map(n=>t(h.join(e,n.name))).filter(Se).sort()}})}function be(e,t){return e.status===`decoded`?e.envelope.resourceKind===t?{status:`decoded`,envelope:e.envelope}:Z(`Expected ${t} resource record, received ${e.envelope.resourceKind}`):e}function xe(e){if(e.length===0||h.basename(e)!==e)throw TypeError(`Durable capture resource fileName must be one file name`)}function Se(e){try{return m.lstatSync(e),!0}catch(e){return!Q(e)}}function Z(e){return{status:`unreattachable`,reason:`descriptor-invalid`,message:e}}function Q(e){return typeof e==`object`&&!!e&&`code`in e&&e.code===`ENOENT`}function Ce(e,t){return e instanceof Error?e.message:`${t} resource record is invalid`}function we(e,t){t.admissionLedger.assertStartAllowed(t.device),Te(e,t.resourcePath,t.device);let n=e.store.read(t.resourcePath);return Object.freeze({token:p.randomUUID(),generation:n.status===`decoded`?n.envelope.fence.generation+1:1})}function Te(e,n,r){let o=a(i(r));for(let r of e.store.list(h.dirname(h.dirname(n)))){let i=e.store.read(r);if(i.status===`unreattachable`)throw new t(`COMMAND_FAILED`,`${b($(e.displayName))} ${e.displayName} recovery record is unreattachable: ${i.message}`,{reason:i.reason,retriable:!1,hint:`Retain the corrupt or future-version ${e.displayName} manifest for manual recovery; no replacement capture is safe.`});if(i.status===`decoded`&&i.envelope.lifecycle!==`completed`&&(r===n||a(i.envelope.device)===o))throw new t(`COMMAND_FAILED`,`${b($(e.displayName))} ${e.displayName} resource for this device has not reached a confirmed terminal state`,{reason:`cleanup-unconfirmed`,hint:`Retry exact-owner cleanup using the existing ${e.displayName} manifest before starting a replacement.`})}}function $(e){return/^[aeiou]/i.test(e)?`an`:`a`}function Ee(e){let t=(t,n)=>e.store.resolvePath(t.resolveSessionDir(n)),n=t=>({definition:e,resolveSessionDir:e=>h.join(t.sessionsDir,l(e)),...t});return Object.freeze({store:e.store,resourcePath:t,createNextFence(t){return we(e,t)},adoptStarted(t){return ne(e,{...t,reportUndurableCleanup:(e,n)=>{n.confirmed?t.admissionLedger.clearUndurableCleanup(e):t.admissionLedger.blockUndurableCleanup(e,n.reason)}},e.store.resolvePath(t.binding.sessionDir))},finishLive(t){return F(e,t,e.store.resolvePath(t.binding.sessionDir))},finishRecovered(t){return _e(e,t)},forceCleanupLive(t){return V(e,{...t,resourcePath:e.store.resolvePath(t.binding.sessionDir)})},recoverAll(e){return fe(n(e))},recoverOne(e,t){return q(n(e),t)}})}export{_ as a,ee as i,ye as n,te as o,y as r,v as s,Ee as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{d as e,v as t}from"./sdk-device.js";import{$t as n,Xt as r,Zt as i}from"./sdk-batch.js";const a=4096;function o(e){return c(e,{seen:new WeakSet,nodes:0},0)}function s(e){return Object.freeze(Object.fromEntries(Object.entries(e).map(([e,t])=>[e,p(t)])))}function c(e,t,n){if(!d(e)||n>32||t.seen.has(e))return!1;t.seen.add(e),t.nodes+=1;let r=t.nodes<=a&&Object.values(e).every(e=>l(e,t,n+1));return t.seen.delete(e),r}function l(e,t,n){return f(e)?!0:n>32?!1:Array.isArray(e)?u(e,t,n):c(e,t,n)}function u(e,t,n){if(t.seen.has(e))return!1;t.seen.add(e),t.nodes+=1;let r=t.nodes<=a&&e.every(e=>l(e,t,n+1));return t.seen.delete(e),r}function d(e){if(typeof e!=`object`||!e||Array.isArray(e))return!1;let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}function f(e){return e===null?!0:typeof e==`number`?Number.isFinite(e):typeof e==`string`||typeof e==`boolean`}function p(e){return Array.isArray(e)?Object.freeze(e.map(p)):typeof e==`object`&&e?s(e):e}function m(e){if(!P(e))return _(`Durable resource envelope must be an object`);let t=e.envelopeVersion;if(!N(t))return _(`Durable resource envelopeVersion must be a non-negative integer`);if(t!==1)return{status:`unreattachable`,reason:`descriptor-version-unsupported`,message:`Unsupported durable resource envelope version: ${t}`,version:t};if(!M(e.resourceKind))return _(`Durable resource resourceKind must be a non-empty string`);if(!M(e.sessionId))return _(`Durable resource sessionId must be a non-empty string`);let n=y(e.device);if(!n)return _(`Durable resource device identity is invalid`);let r=v(e.owner);if(!r)return _(`Durable resource owner reference is invalid`);if(r.kind===`local-family`&&r.family!==n.family)return _(`Durable resource local owner does not match the device family`);let i=D(e.fence);if(!i)return _(`Durable resource ownership fence is invalid`);if(!k(e.lifecycle))return _(`Durable resource lifecycle state is invalid`);let a=O(e.descriptor);return a?e.metadata!==void 0&&!o(e.metadata)?_(`Durable resource metadata must be a JSON object`):{status:`decoded`,envelope:Object.freeze({envelopeVersion:1,resourceKind:e.resourceKind,sessionId:e.sessionId,device:n,owner:r,fence:i,lifecycle:e.lifecycle,descriptor:a,...e.metadata===void 0?{}:{metadata:s(e.metadata)}})}:_(`Durable resource descriptor is invalid`)}function h(e,t){return Object.freeze({version:e.version,body:s(e.encode(t))})}function g(e){let t=m({envelopeVersion:1,...e});if(t.status!==`decoded`)throw TypeError(t.message);return t.envelope}function _(e){return{status:`unreattachable`,reason:`descriptor-invalid`,message:e}}function v(e){return P(e)?e.kind===`local-family`&&t(e.family)?r(e.family):e.kind===`managed-local`&&M(e.instance)?i(e.instance):e.kind===`provider-runtime`&&M(e.provider)&&M(e.instance)?n(e.provider,e.instance):null:null}function y(e){if(!P(e))return null;let t=x(e.id),n=S(e.family),r=C(e.kind),i=w(e.target);return!t||!n||!r||i===null||!T(e,n,r)?null:b(e,t,n,r,i)}function b(e,t,n,r,i){return Object.freeze({id:t,family:n,...e.appleOs===void 0?{}:{appleOs:e.appleOs},kind:r,...i===void 0?{}:{target:i},...e.iosPhysicalDeviceBackend===void 0?{}:{iosPhysicalDeviceBackend:e.iosPhysicalDeviceBackend}})}function x(e){return M(e)?e:null}function S(e){return t(e)?e:null}function C(e){return A(e)?e:null}function w(e){if(e!==void 0)return j(e)?e:null}function T(t,n,r){if(n===`apple`){if(!e(t.appleOs))return!1}else if(t.appleOs!==void 0||t.iosPhysicalDeviceBackend!==void 0)return!1;return E(t.iosPhysicalDeviceBackend,r)}function E(e,t){return e===void 0?!0:t===`device`?e===`coredevice`||e===`xctest`:!1}function D(e){return!P(e)||!M(e.token)||!N(e.generation)?null:Object.freeze({token:e.token,generation:e.generation})}function O(e){return!P(e)||!N(e.version)||!o(e.body)?null:Object.freeze({version:e.version,body:s(e.body)})}function k(e){return e===`open`||e===`completed`}function A(e){return e===`simulator`||e===`emulator`||e===`device`}function j(e){return e===`mobile`||e===`tv`||e===`desktop`}function M(e){return typeof e==`string`&&e.trim().length>0}function N(e){return typeof e==`number`&&Number.isInteger(e)&&e>=0}function P(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function F(e){return e.status===`cleaned`||e.status===`already-missing`}export{h as a,m as i,g as n,y as r,F as t};
|
package/dist/src/exec.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{I as e,P as t}from"./sdk-contracts.js";import{a as n,r,s as i}from"./diagnostics.js";import{o as a}from"./sdk-remote-config.js";import{AsyncLocalStorage as o}from"node:async_hooks";import{constants as s}from"node:fs";import c from"node:path";import{access as l,stat as u}from"node:fs/promises";import{spawn as d,spawnSync as f}from"node:child_process";import{Readable as p}from"node:stream";import{pipeline as m}from"node:stream/promises";const h=/^[A-Za-z0-9][A-Za-z0-9._+-]*$/,g=[`.com`,`.exe`,`.bat`,`.cmd`],_=new o;async function v(e,t){return e?await _.run(e,t):await t()}async function y(e){return await _.run(void 0,e)}const b=new o;async function
|
|
1
|
+
import{I as e,P as t}from"./sdk-contracts.js";import{a as n,r,s as i}from"./diagnostics.js";import{o as a}from"./sdk-remote-config.js";import{AsyncLocalStorage as o}from"node:async_hooks";import{constants as s}from"node:fs";import c from"node:path";import{access as l,stat as u}from"node:fs/promises";import{spawn as d,spawnSync as f}from"node:child_process";import{Readable as p}from"node:stream";import{pipeline as m}from"node:stream/promises";const h=/^[A-Za-z0-9][A-Za-z0-9._+-]*$/,g=[`.com`,`.exe`,`.bat`,`.cmd`],_=new o;async function v(e,t){return e?await _.run(e,t):await t()}async function y(e){return await _.run(void 0,e)}const b=new o;async function x(e,t){return e?await b.run(e,t):await t()}function S(){let e=b.getStore();return e&&Object.hasOwn(e,`DEVELOPER_DIR`)?e.DEVELOPER_DIR||void 0:process.env.DEVELOPER_DIR||void 0}function C(e){let t=b.getStore();return t?{...e??process.env,...t}:e}async function w(e,t,n={}){let r=_.getStore()?.(e,t,n);return r?E(await r):await D(e,t,n)}async function T(e,t,n={}){let r=_.getStore()?.(e,t,n);return r?E(await r):await D(e,t,n)}function E(e){let t=typeof e.stdout==`string`?e.stdout:String(e.stdout??``),n=typeof e.stderr==`string`?e.stderr:String(e.stderr??``),r=typeof e.exitCode==`number`?e.exitCode:1;return t===e.stdout&&n===e.stderr&&r===e.exitCode?e:{...e,stdout:t,stderr:n,exitCode:r}}function D(e,t,n={}){let r=N(e),i=j();return new Promise((a,o)=>{let s=d(r,t,{cwd:n.cwd,env:C(n.env),stdio:[`pipe`,`pipe`,`pipe`],detached:n.detached,windowsHide:!0,shell:!1});n.onSpawn?.(s);let c=``,l=n.binaryStdout?[]:void 0,u=``,f=!1,p=q(n.timeoutMs),m=null,h=!1;function g(){return!h&&(h=!0,m&&clearTimeout(m),b.dispose(),$(s),i.emitForegroundCompletion(e,t),!0)}function _(e){g()&&o(e)}function v(i){if(!g())return;let s=i??1;if(!b.didAbort&&f&&p){o(ce(r,e,t,p,s,c,u));return}let d=H(b,r,e,t,s,n.allowFailure,c,u);if(d){o(d);return}a({stdout:c,stderr:u,exitCode:s,stdoutBuffer:l?Buffer.concat(l):void 0})}let y=J({killProcessTree:()=>Z(s,n),settle:v}),b=Y(n,y.requestKill);m=p?setTimeout(()=>{f=!0,y.requestKill()},p):null,n.binaryStdout||s.stdout.setEncoding(`utf8`),s.stderr.setEncoding(`utf8`),fe(s,n.stdin).catch(i=>{b.didAbort||f||pe(i)||(_(se(r,e,t,i)),Z(s,n))}),s.stdout.on(`data`,e=>{if(n.binaryStdout){l?.push(Buffer.isBuffer(e)?e:Buffer.from(e));return}let t=String(e);c+=t,n.onStdoutChunk?.(t)}),s.stderr.on(`data`,e=>{let t=String(e);u+=t,n.onStderrChunk?.(t)}),s.on(`error`,n=>{_(V(b,r,e,t,n))}),s.once(`exit`,y.recordExit),s.once(`close`,v)})}async function ee(e){let t=W(e);if(!t)return!1;if(c.isAbsolute(t))return G(t);let n=process.env.PATH;if(!n)return!1;let r=ue();for(let e of n.split(c.delimiter)){let n=e.trim();if(n){for(let e of de(t,r))if(await G(c.join(n,e)))return!0}}return!1}async function te(e,t){return await O(e,t,`executable`,G)}async function ne(e,t){return await O(e,t,`file`,K)}async function O(e,n,r,i){let a=U(e,n,r);if(a){if(!await i(a))throw new t(`TOOL_MISSING`,`${n} points to a missing or non-${r} ${r===`file`?`path`:`file`}: ${a}`,{envName:n,path:a});return a}}function k(e,n,r={}){let i=N(e),a=f(i,n,{cwd:r.cwd,env:C(r.env),stdio:[`pipe`,`pipe`,`pipe`],encoding:r.binaryStdout?void 0:`utf8`,input:r.stdin,timeout:q(r.timeoutMs),windowsHide:!0,shell:!1,...r.maxBuffer===void 0?{}:{maxBuffer:r.maxBuffer}});if(a.error){let o=a.error.code;throw o===`ETIMEDOUT`?new t(`COMMAND_FAILED`,`${i} timed out after ${q(r.timeoutMs)}ms`,{cmd:e,args:n,timeoutMs:q(r.timeoutMs)},a.error):o===`ENOENT`?P(i,e,a.error):F(i,e,n,a.error)}let o=r.binaryStdout?Buffer.isBuffer(a.stdout)?a.stdout:Buffer.from(a.stdout??``):void 0,s=r.binaryStdout?``:typeof a.stdout==`string`?a.stdout:(a.stdout??``).toString(),c=typeof a.stderr==`string`?a.stderr:(a.stderr??``).toString(),l=a.status??1;if(l!==0&&!r.allowFailure)throw I(i,e,n,l,s,c);return{stdout:s,stderr:c,exitCode:l,stdoutBuffer:o}}function re(e,t,n={}){return A(e,t,n).pid}function A(e,t,n={}){let r=N(e),i=d(r,t,{cwd:n.cwd,env:C(n.env),stdio:n.stdio??`ignore`,detached:!0,windowsHide:!0,shell:!1}),a=i.pid??0,o=new Promise(e=>{i.once(`error`,t=>{e({pid:a,error:t.message})}),i.once(`exit`,(t,n)=>{e({pid:a,...typeof t==`number`?{exitCode:t}:{},...n?{signal:n}:{}})})});return i.unref(),{pid:a,exited:o}}function ie(e,t,n={}){let r=N(e),i=j(),a=d(r,t,{cwd:n.cwd,env:C(n.env),stdio:n.stdio??[`ignore`,`pipe`,`pipe`],detached:n.detached,windowsHide:!0,shell:!1});i.emitBackgroundSpawn(e,t);let o=``,s=``;return(n.captureOutput??!0)&&(a.stdout?.setEncoding(`utf8`),a.stderr?.setEncoding(`utf8`),a.stdout?.on(`data`,e=>{o+=e}),a.stderr?.on(`data`,e=>{s+=e})),{child:a,wait:new Promise((c,l)=>{let u=!1;function d(n){return!u&&(u=!0,m.dispose(),$(a),i.emitBackgroundCompletion(e,t,n),!0)}function f(i){if(!d(`exit`))return;let a=i??1,u=H(m,r,e,t,a,n.allowFailure,o,s);if(u){l(u);return}c({stdout:o,stderr:s,exitCode:a})}let p=J({killProcessTree:()=>Z(a,n),settle:f}),m=Y(n,p.requestKill);a.on(`error`,n=>{d(`error`)&&l(V(m,r,e,t,n))}),a.once(`exit`,p.recordExit),a.once(`close`,f)})}}function j(){let e=n(),t=e.debug===!0,r=a(process.env.AGENT_DEVICE_EXEC_TRACE??``)===!0;if(!t&&!r)return ae();r&&e.flushOnSuccess!==!0&&i({flushOnSuccess:!0});let o=Date.now(),s=!1;return{emitForegroundCompletion:(e,t)=>{s||(s=!0,M({cmd:e,args:t,startedAtMs:o}))},emitBackgroundSpawn:(e,t)=>{M({cmd:e,args:t,data:{event:`spawn`}})},emitBackgroundCompletion:(e,t,n)=>{s||(s=!0,M({cmd:e,args:t,startedAtMs:o,data:{event:n}}))}}}function ae(){return{emitForegroundCompletion:()=>{},emitBackgroundSpawn:()=>{},emitBackgroundCompletion:()=>{}}}function M(e){let t=e.args.slice(0,6);r({level:`debug`,phase:`exec_command`,durationMs:e.startedAtMs===void 0?void 0:Math.max(0,Date.now()-e.startedAtMs),data:{command:e.cmd,argsPrefix:t,...e.args.length>t.length?{omittedArgCount:e.args.length-t.length}:{},...e.data??{}}})}function N(e){let n=W(e);if(!n)throw new t(`INVALID_ARGS`,`Invalid executable command: ${JSON.stringify(e)}`,{cmd:e,hint:`Use a bare command name from PATH or an absolute executable path.`});return n}function oe(e,t,n,r){return r.code===`ENOENT`?P(e,t,r):F(e,t,n,r)}function P(e,n,r){return new t(`TOOL_MISSING`,`${e} not found in PATH`,{cmd:n},r)}function F(e,n,r,i){return new t(`COMMAND_FAILED`,`Failed to run ${e}`,{cmd:n,args:r},i)}function se(e,n,r,i){return new t(`COMMAND_FAILED`,`Failed to write stdin for ${e}`,{cmd:n,args:r},i instanceof Error?i:void 0)}function ce(e,n,r,i,a,o,s){return new t(`COMMAND_FAILED`,`${e} timed out after ${i}ms`,{cmd:n,args:r,stdout:o,stderr:s,exitCode:a,timeoutMs:i})}function le(e){return e instanceof t&&e.code===`COMMAND_FAILED`&&typeof e.details?.timeoutMs==`number`}function I(e,n,r,i,a,o){return new t(`COMMAND_FAILED`,`${e} exited with code ${i}`,B({stdout:a,stderr:o,exitCode:i},{cmd:n,args:r}))}const L=/xcrun: error: unable to find utility "([^"]+)"/;function R(e){let t=L.exec(e)?.[1];if(!t)return{};let n=S(),r=n?`DEVELOPER_DIR ${n}`:`the developer dir selected by xcode-select (see xcode-select -p)`;return{reason:`xcrun-tool-not-found`,developerDir:n??null,hint:`xcrun could not find ${t} in ${r}. Export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer (or your Xcode's path) before running agent-device, or run sudo xcode-select -s /Applications/Xcode.app.`}}function z(e,n,r){if(e.exitCode===0)return e;throw new t(`COMMAND_FAILED`,n,B(e,typeof r==`function`?r(e):r))}function B(e,t){return{stdout:e.stdout,stderr:e.stderr,exitCode:e.exitCode,processExitError:!0,...t,...R(e.stderr)}}function V(t,n,r,i,a){return t.didAbort?e({cmd:r,args:i,executable:n}):oe(n,r,i,a)}function H(t,n,r,i,a,o,s,c){return t.didAbort?e({cmd:r,args:i,executable:n}):a!==0&&!o?I(n,r,i,a,s,c):null}function U(e,n,r){let i=e?.trim();if(i){if(!c.isAbsolute(i)||i.includes(`\0`))throw new t(`INVALID_ARGS`,`${n} must be an absolute ${r} path, not ${JSON.stringify(e)}`,{envName:n,path:e});return i}}function W(e){let t=e.trim();return!t||t.includes(`\0`)?null:c.isAbsolute(t)?t:t.includes(`/`)||t.includes(`\\`)?null:h.test(t)?t:null}function ue(){if(process.platform!==`win32`)return[``];let e=process.env.PATHEXT;if(!e)return g;let t=e.split(`;`).map(e=>e.trim().toLowerCase()).filter(e=>e.length>0);return t.length>0?t:g}function de(e,t){if(process.platform!==`win32`)return[e];let n=e.toLowerCase();return t.some(e=>n.endsWith(e))?[e]:t.map(t=>`${e}${t}`)}async function G(e){try{return await K(e)?(await l(e,process.platform===`win32`?s.F_OK:s.X_OK),!0):!1}catch{return!1}}async function K(e){try{return(await u(e)).isFile()}catch{return!1}}function q(e){if(!Number.isFinite(e))return;let t=Math.floor(e);if(!(t<=0))return t}function J(e){let t=!1,n=!1,r=null,i=()=>{t&&n&&e.settle(r)};return{requestKill:()=>{t=!0,e.killProcessTree(),i()},recordExit:e=>{n=!0,r=e??1,i()}}}function Y(e,t){let n=!1,r=()=>{n=!0,t()};return e.signal?.aborted?r():e.signal?.addEventListener(`abort`,r,{once:!0}),{get didAbort(){return n},dispose:()=>{e.signal?.removeEventListener(`abort`,r)}}}function X(e,t){if(!Number.isInteger(e)||e<=0)return!1;try{return process.kill(-e,t),!0}catch{return!1}}function Z(e,t){if(!t.kill){Q(e,t.detached,`SIGKILL`);return}Q(e,t.detached,t.kill.signal);let n=setTimeout(()=>Q(e,t.detached,`SIGKILL`),t.kill.graceMs);n.unref(),e.once(`exit`,()=>clearTimeout(n))}function Q(e,t,n){if(t&&e.pid&&process.platform!==`win32`){X(e.pid,n);return}e.exitCode===null&&e.signalCode===null&&e.kill(n)}function $(e){e.stdin?.destroy(),e.stdout?.destroy(),e.stderr?.destroy()}async function fe(e,t){if(e.stdin){if(t===void 0){e.stdin?.end();return}await m(p.from([t]),e.stdin)}}function pe(e){return e instanceof Error&&`code`in e&&e.code===`EPIPE`}export{v as _,G as a,ne as c,re as d,A as f,ee as g,X as h,le as i,w as l,k as m,S as n,z as o,T as p,B as r,te as s,E as t,ie as u,x as v,y};
|
package/dist/src/file.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{J as e,P as t}from"./sdk-contracts.js";import{r as n}from"./diagnostics.js";import{
|
|
1
|
+
import{J as e,P as t}from"./sdk-contracts.js";import{r as n}from"./diagnostics.js";import{a as r,j as i,r as a,t as o}from"./owner-identity.js";import{i as s}from"./retry.js";import c from"node:crypto";import l from"node:fs";import u from"node:path";const d=`owner.json`,f=`.lock`;async function p(e){let t=await e.acquire();try{let n=await e.task();return await t(),n}catch(e){throw await t().catch(()=>void 0),e}}const m=new Set,h=c.randomUUID();function g(e){let t;try{t=l.lstatSync(e)}catch(t){return I(t)===`ENOENT`?{state:l.existsSync(M(e))?`publishing`:`absent`}:{state:`unproven`,reason:`owner-unreadable`}}if(!t.isDirectory())return{state:`unproven`,reason:`non-directory`};let n=L(u.join(e,d));if(n.kind===`unreadable`)return{state:`unproven`,reason:`owner-unreadable`};if(n.kind===`unwritten`)return l.existsSync(M(e))?{state:`publishing`}:{state:`unproven`,reason:`owner-unwritten`};let{pid:r,startTime:i,acquiredAtMs:a}=n.owner;return{state:`held`,owner:{pid:r,startTime:i,acquiredAtMs:a},liveness:o({owner:n.owner})}}function _(e){let{lockDirPath:t}=e;l.mkdirSync(u.dirname(t),{recursive:!0});let n=x(u.join(t,d));if(n.kind===`live`)return{status:`busy`,inspection:n.inspection};if(!N(t))return{status:`busy`,inspection:g(t)};let r=v(t,()=>y(e,n),e=>{e.status===`acquired`&&m.delete(e.claimToken)});return r.status===`acquired`?{status:`acquired`,acquisition:r.acquisition}:{status:r.status,inspection:r.inspection??g(t)}}function v(t,r,i){let a;try{a=r()}catch(r){try{F(t)}catch(r){n({level:`warn`,phase:`process_lock_guard_release_failed`,data:{lockDirPath:t,error:e(r)}})}throw r}try{F(t)}catch(e){throw i(a),e}return a}function y(e,t){let{lockDirPath:n}=e,r=u.join(n,d),i=S(n,r);if(i.kind===`unproven`)return{status:`unproven`,inspection:i.inspection};if(i.kind===`owner`){if(t.kind!==`reclaimable`||!C(i.owner,t.owner))return{status:`busy`};if(k(n,r,i.owner)!==`removed`)return{status:`unproven`}}return b(e,r)}function b(e,t){let{lockDirPath:n,owner:r}=e;try{l.mkdirSync(n)}catch(e){if(I(e)!==`EEXIST`)throw e;return{status:`unproven`}}let i=c.randomUUID(),a={...r,claimToken:i,claimIssuerId:h};try{O(t,a)}catch(e){try{l.rmdirSync(n)}catch{}throw e}return m.add(i),{status:`acquired`,claimToken:i,acquisition:E(e,a)}}function x(e){let t=L(e);if(t.kind!==`owner`)return{kind:`none`};let n=o({owner:t.owner});if(V(n)&&!H(t.owner)){let{pid:e,startTime:r,acquiredAtMs:i}=t.owner;return{kind:`live`,inspection:{state:`held`,owner:{pid:e,startTime:r,acquiredAtMs:i},liveness:n}}}return{kind:`reclaimable`,owner:t.owner}}function S(e,t){let n;try{n=l.lstatSync(e)}catch(e){return I(e)===`ENOENT`?{kind:`absent`}:{kind:`unproven`,inspection:{state:`unproven`,reason:`owner-unreadable`}}}if(!n.isDirectory())return{kind:`unproven`,inspection:{state:`unproven`,reason:`non-directory`}};let r=L(t);return r.kind===`owner`?{kind:`owner`,owner:r.owner}:{kind:`unproven`,inspection:{state:`unproven`,reason:r.kind===`unwritten`?`owner-unwritten`:`owner-unreadable`}}}function C(e,t){return e.pid===t.pid&&e.startTime===t.startTime&&e.acquiredAtMs===t.acquiredAtMs&&e.claimToken===t.claimToken&&e.claimIssuerId===t.claimIssuerId}async function w(e){return(await T(e)).release}async function T(e){let n=Date.now()+(e.timeoutMs??3e4),r=e.pollMs??100;do{let t=_(e);if(t.status===`acquired`)return t.acquisition;let i=n-Date.now();if(i<=0)break;await s(Math.min(r,i))}while(Date.now()<n);let i=L(u.join(e.lockDirPath,d));throw new t(`COMMAND_FAILED`,`Timed out waiting for ${e.description??`process lock`}`,{lockDirPath:e.lockDirPath,reason:`process_lock_timeout`,...B(e.lockDirPath,i),inspection:g(e.lockDirPath),hint:D(e.lockDirPath)})}function E(e,r){let{lockDirPath:i}=e,a=u.join(i,d),o=!0,s=!1;return Object.freeze({assertHeld(){if(!o||A(i,r)!==`owned`)throw new t(`COMMAND_FAILED`,`Process lock acquisition is no longer held`,{lockDirPath:i,ownerOwnershipLost:!0})},async release(){if(s)return;o=!1,m.delete(r.claimToken);let c=A(i,r);if(c===`absent`||c===`not-owner`){s=!0;return}let l=`unverified`;if(await P(i))try{l=k(i,a,r)}finally{F(i)}if(l!==`unverified`){s=!0;return}throw n({level:`warn`,phase:`process_lock_release_unverified`,data:{lockDirPath:i,description:e.description,ownerReleaseUnverified:!0}}),new t(`COMMAND_FAILED`,`Cannot verify ownership of ${e.description??`process lock`}`,{lockDirPath:i,ownerReleaseUnverified:!0,hint:D(i)})}})}function D(e){return`Restore process inspection or stop the verified owner, then retry. Remove ${e} and ${M(e)} only after confirming all users of this state directory have stopped.`}function O(e,t){i({destination:e,contents:JSON.stringify(t)})}function k(e,t,n){let r=A(e,n);return r===`owned`?j(e,t,n):r===`absent`?`removed`:r}function A(e,t){let n=L(u.join(e,d));return n.kind===`unreadable`?`unverified`:n.kind===`unwritten`?l.existsSync(e)?`unverified`:`absent`:r(n.owner,t)&&n.owner.claimToken===t.claimToken?`owned`:`not-owner`}function j(e,t,n){try{if(l.readdirSync(e).some(e=>e!==d))return`unverified`}catch(e){return I(e)===`ENOENT`?`removed`:`unverified`}try{l.unlinkSync(t)}catch(e){if(I(e)!==`ENOENT`)return`unverified`}try{return l.rmdirSync(e),`removed`}catch(e){if(I(e)===`ENOENT`)return`removed`;try{i({destination:t,contents:JSON.stringify(n),publish:`link-exclusive`})}catch{}return`unverified`}}function M(e){return`${e.endsWith(f)?e.slice(0,-5):e}.reclaim${f}`}function N(e){let t;try{t=l.openSync(M(e),`wx`,384)}catch(e){if(I(e)!==`EEXIST`)throw e;return!1}return l.closeSync(t),!0}async function P(e){let t=Date.now()+5e3;for(;!N(e);){if(Date.now()>=t)return!1;await s(5)}return!0}function F(e){try{l.unlinkSync(M(e))}catch(n){throw new t(`COMMAND_FAILED`,`Process lock mutation guard release could not be confirmed.`,{reason:`process_lock_guard_release_failed`,lockDirPath:e,hint:D(e)},n)}}function I(e){return e?.code}function L(e){let t;try{t=l.readFileSync(e,`utf8`)}catch(e){return e?.code===`ENOENT`?{kind:`unwritten`}:{kind:`unreadable`}}let n=R(t);return n?{kind:`owner`,owner:n}:{kind:`unreadable`}}function R(e){let t;try{t=JSON.parse(e)}catch{return null}if(typeof t!=`object`||!t)return null;let n=t;for(let[e,t]of Object.entries(z))if(!t(n[e]))return null;return{pid:n.pid,startTime:typeof n.startTime==`string`?n.startTime:null,acquiredAtMs:n.acquiredAtMs,claimToken:typeof n.claimToken==`string`?n.claimToken:null,claimIssuerId:typeof n.claimIssuerId==`string`?n.claimIssuerId:void 0}}const z={pid:a,acquiredAtMs:e=>typeof e==`number`&&Number.isFinite(e),startTime:e=>e==null||typeof e==`string`};function B(e,t){let n=Date.now(),r;try{r=Math.max(0,Math.round(n-l.statSync(e).mtimeMs))}catch{}return{...r===void 0?{}:{lockAgeMs:r},...t.kind===`owner`?{ownerPid:t.owner.pid,ownerStartTime:t.owner.startTime,ownerAgeMs:Math.max(0,Math.round(n-t.owner.acquiredAtMs)),ownerLiveness:o({owner:t.owner})}:t.kind===`unreadable`?{ownerRecordUnreadable:!0}:{}}}function V(e){return e!==`owner-process-dead`&&e!==`owner-process-reused`}function H(e){return e.pid!==process.pid||e.claimToken===null||e.claimIssuerId!==h?!1:!m.has(e.claimToken)}export{p as a,_ as i,T as n,g as r,w as t};
|
package/dist/src/find.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{b as e,f as t,s as n}from"./sdk-contracts.js";import{Fn as r,
|
|
1
|
+
import{b as e,f as t,s as n}from"./sdk-contracts.js";import{Fn as r,In as i,Pn as a,Rt as o,_t as s,zn as c}from"./sdk-batch.js";import{f as l}from"./dispatch-resolve.js";import{c as u}from"./target-evidence.js";import{f as d,m as f,p,u as m}from"./runtime.js";import{r as h,t as g}from"./success-text.js";import{m as _}from"./overlay.js";import{j as v,v as y,x as b}from"./session-snapshot.js";import{t as x}from"./selector-pipeline-policy.js";import{s as S}from"./quality-warnings.js";import{f as C}from"./internal/daemon.js";import{t as w}from"./snapshot-runtime-binding.js";import{l as T,n as E}from"./selector-runtime.js";import{t as D}from"./type-text-runtime.js";function O(t,n){let r=n[0]?.rect;if(!r)return t;let i=t.filter(t=>{if(!t.rect)return!1;let n=e(t.rect);return n.x>=r.x&&n.x<=r.x+r.width&&n.y>=r.y&&n.y<=r.y+r.height}),a=i.length>0?i:t;return a.length<2?a:k(a,n,p(n))}function k(e,t,n){return e.map((e,r)=>({node:e,index:r,score:A(e,t,n)})).sort((e,t)=>t.score===e.score?M(e.node)-M(t.node)||e.index-t.index:t.score-e.score).map(e=>e.node)}function A(e,t,n){let r=n(e);if(r.reason===`covered`)return 0;let i=j(r,t[0]);return i>0?i:e.hittable&&e.rect&&!f(e,t[0])?3:+!!e.rect}function j(e,t){return e.node.rect?e.reason===`semantic-target`||e.reason===`same-rect-descendant`?4:e.reason===`hittable-ancestor`&&!f(e.node,t)?2:0:0}function M(e){return e.rect?e.rect.width*e.rect.height:1/0}function N(e,t,r){return n(`AMBIGUOUS_MATCH`,`find matched ${e.length} elements for ${t} "${r}". Use a more specific locator or selector.`,{locator:t,query:r,..._(e)})}function P(e){if(e.ambiguity!==`reject-candidates`)throw Error(`find's resolution policy must reject candidates, got "${e.ambiguity}"`)}function F(e){let{nodes:t,locator:i,query:a,selectorExpression:o,flags:s,platform:c}=e,l=x.findAct,u=t.filter(e=>!f(e,t[0])),d=l.resolution,p;if(p=o?m(l,u,o,{platform:c}).list?.matchedNodes??[]:r(u,i,a,{requireRect:d.requireRect}).matches,p=O(p,t),p.length>1){P(d);let e=I(p,s);if(!e)return{ok:!1,response:N(p,i,a)};p=e}let h=p[0]??null;return h?{ok:!0,node:h}:{ok:!1,response:n(`COMMAND_FAILED`,`find did not match any element`)}}function I(e,t){return t?.findFirst?[e[0]]:t?.findLast?[e.at(-1)]:null}function L(e){let{device:t,req:n,logPath:r,locator:i,query:a,sessionStore:o,sessionName:s}=e,c=T({ref:e.ref,device:t,sessionStore:o,sessionName:s,req:n,logPath:r,capture:e.capture,captureProof:e.captureProof});return async()=>{let{snapshot:e}=await c.capture({flags:{...n.flags,snapshotInteractiveOnly:!0},recovery:{legacyIosSparse:{query:a,shouldScope:z(i)},sparseVerdictQueryScope:{query:a,shouldScope:z(i)}}});return e}}function R(e){return n(`COMMAND_FAILED`,`find could not read the current accessibility tree`,{reason:e.reason,hint:`The snapshot quality verdict is sparse. Use screenshot as visual truth, navigate with coordinates if needed, then retry find after reaching a readable screen.`})}function z(e){return e!==`role`}async function B(e){let{req:r,sessionName:l,logPath:f,sessionStore:p,invoke:m}=e,h=p.lookup(l),g=r.command;if(g!==`find`)return null;let _=r.positionals??[],v=a(_,r.flags);if(!v.ok)return n(v.code,v.message);let{locator:y,query:b,action:C,value:T}=v.parsed;if(r.flags?.record&&!i(C))return n(`INVALID_ARGS`,`find ${C} is a mutating action and is always recorded; --record only applies to a read-only find (exists, wait, list, get text, get attrs).`);let D=await E({req:r,sessionName:l,logPath:f,sessionStore:p,inspectFacts:e.inspectFacts,bindDevice:e.bindDevice});if(D)return D;let O=h?p.requireCurrent(h):void 0;if(!O||!h)return t();let k=O.device,A=await w({command:`find`,device:k,session:O,plan:o({hasActiveApp:O.appBundleId!==void 0,intent:s(C)}),inspectFacts:e.inspectFacts,bindDevice:e.bindDevice});if(!A.ok)return A.response;let j=c(y,b),M={},N=L({ref:h,device:k,req:r,logPath:f,locator:y,query:b,sessionStore:p,sessionName:l,capture:A.capture,captureProof:M}),P={sessionRef:h,req:r,sessionName:l,logPath:f,sessionStore:p,invoke:m,device:k,command:g,locator:y,query:b,publicFlags:X(r.flags),boundFocusPoint:A.focusPoint,boundTypeText:A.typeText},I=await N();if(S(I.snapshotQuality))return u({response:R(I.snapshotQuality),consumedTree:I,captureProof:M});let{nodes:z}=I,B=F({nodes:z,locator:y,query:b,selectorExpression:j,flags:r.flags,platform:k.platform});if(!B.ok)return u({response:B.response,consumedTree:I,captureProof:M});let H=B.node,U=await d(x.findAct,z,H),W=U.node,G=`@${W.ref}`,K={...r.flags??{},noRecord:!0},q=await V(P,{node:H,resolvedNode:W,ref:G,nodes:z,...I.iosSystemSurfaceBundleId?{iosSystemSurfaceBundleId:I.iosSystemSurfaceBundleId}:{},...I.keyboard?{keyboard:I.keyboard}:{},actionFlags:K,...U.kind===`occluded`?{occludedNode:U.node}:{}},C,T);return q&&u({response:q,consumedTree:I,captureProof:M})}async function V(e,t,n,r){let i={click:()=>U(e,t),fill:()=>W(e,t,r),focus:()=>G(e,t),type:()=>K(e,t,r)}[n];return i?await i():null}function H(e){return{ref:e.ref,node:e.resolvedNode,nodes:e.nodes,...e.iosSystemSurfaceBundleId?{iosSystemSurfaceBundleId:e.iosSystemSurfaceBundleId}:{},...e.keyboard?{keyboard:e.keyboard}:{}}}async function U(t,n){let{req:r,sessionName:i,sessionStore:a,sessionRef:o,invoke:s,command:c,locator:u,query:d,publicFlags:f}=t,p=await s({token:r.token,session:i,command:`click`,positionals:[n.ref],flags:n.actionFlags,internal:{findResolvedTarget:H(n)}});if(!p.ok)return p;let m=n.resolvedNode.rect?e(n.resolvedNode.rect):n.node.rect?e(n.node.rect):null,_={ref:n.ref,locator:u,query:d};m&&(_.x=m.x,_.y=m.y);let v=g(p.data)??`Tapped ${n.ref}${m?` (${m.x}, ${m.y})`:``}`;return Object.assign(_,h(v)),l(a,o,r,c,{ref:n.ref,action:`click`,locator:u,query:d},{flags:f}),{ok:!0,data:_}}async function W(e,t,r){let{req:i,sessionName:a,sessionStore:o,sessionRef:s,invoke:c,command:u,publicFlags:d}=e;if(r===void 0)return n(`INVALID_ARGS`,`find fill requires text (use "" to clear the field)`);let f=await c({token:i.token,session:a,command:`fill`,positionals:[t.ref,r],flags:t.actionFlags,internal:{findResolvedTarget:H(t)}});return f.ok&&l(o,s,i,u,{ref:t.ref,action:`fill`},{flags:d}),f}async function G(e,t){let n=await q(e,t);return n.ok&&Y(e,t,`focus`),n}async function K(e,t,r){let{req:i,logPath:a}=e;if(!r)return n(`INVALID_ARGS`,`find type requires text`);let o=await q(e,t);if(!o.ok)return o;let s=e.sessionStore.requireCurrent(e.sessionRef);v(s);let c=e.boundTypeText;if(!c)return n(`COMMAND_FAILED`,`find type was admitted without a text-entry operation`);let l=await D({operations:{typeText:c}},[r],y(a,i.flags,s.appBundleId,s.trace?.outPath));return Y(e,t,`type`),{ok:!0,data:l??{ref:t.ref}}}async function q(t,r){let{req:i,logPath:a}=t,o=J(r,`be focused`);if(o)return o;let s=r.resolvedNode.rect?e(r.resolvedNode.rect):null;if(!s)return n(`COMMAND_FAILED`,`matched element has no bounds`);let c=t.sessionStore.requireCurrent(t.sessionRef);v(c);let l=t.boundFocusPoint;return l?{ok:!0,data:await C({operations:{focusPoint:l}},s,y(a,i.flags,c.appBundleId,c.trace?.outPath))??{ref:r.ref}}:n(`COMMAND_FAILED`,`find focus was admitted without a focus operation`)}function J(e,t){let r=e.occludedNode;return r?n(`COMMAND_FAILED`,`Matched element ${e.ref} is covered by another visible element and cannot ${t} safely`,{ref:`@${r.ref}`,interactionBlocked:r.interactionBlocked,hint:`Use a different visible target, scroll it clear of the overlay, or inspect with snapshot/screenshot before retrying.`}):null}function Y(e,t,n){let{req:r,sessionStore:i,sessionRef:a,command:o,publicFlags:s}=e;l(i,a,r,o,{ref:t.ref,action:n},{flags:s})}function X(e){return{...b(e)??{}}}export{B as handleFindCommands};
|
package/dist/src/finders.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{Rn as e}from"./sdk-batch.js";import{t}from"./sdk-finders.js";export{t as findBestMatchesByLocator,e as parseFindArgs};
|