agent-device 0.21.17 → 0.21.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.17.apk → agent-device-android-ime-helper-0.21.19.apk} +0 -0
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.19.apk.sha256 +1 -0
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.17.manifest.json → agent-device-android-ime-helper-0.21.19.manifest.json} +4 -4
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.17.apk → agent-device-android-snapshot-helper-0.21.19.apk} +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.19.apk.sha256 +1 -0
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.17.manifest.json → agent-device-android-snapshot-helper-0.21.19.manifest.json} +6 -6
- package/dist/src/adapter.js +1 -1
- package/dist/src/adb-executor.js +2 -2
- package/dist/src/adb-failure.js +2 -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/ai-sdk.js +1 -1
- package/dist/src/alert-runtime.js +1 -1
- package/dist/src/android-input-ownership.js +1 -1
- package/dist/src/android.js +1 -1
- package/dist/src/app-log-runtime2.js +1 -1
- package/dist/src/cache.js +1 -1
- package/dist/src/catalog.js +1 -1
- package/dist/src/cli-help.js +1 -1
- package/dist/src/cli.js +4 -4
- package/dist/src/client-types.d.ts +11 -4
- package/dist/src/command-metadata.js +1 -1
- package/dist/src/command-tools.js +2 -2
- package/dist/src/contracts.js +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-policy-file.js +1 -1
- package/dist/src/device-claim-inspection.js +1 -1
- package/dist/src/device-claim-rule.js +1 -1
- package/dist/src/device-inventory-context.js +1 -1
- package/dist/src/device-session.js +1 -1
- package/dist/src/diagnostics.js +1 -1
- package/dist/src/diagnostics2.js +1 -1
- package/dist/src/durable-resource.js +1 -1
- package/dist/src/engine-eval-script.js +1 -1
- package/dist/src/error.js +1 -1
- package/dist/src/find.js +1 -1
- package/dist/src/finders.js +1 -1
- package/dist/src/generic-settle.js +1 -1
- package/dist/src/gesture-runtime.js +1 -1
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.js +1 -1
- package/dist/src/input-actions2.js +2 -2
- package/dist/src/install-source-network-transport.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/internal/bin.js +1 -1
- package/dist/src/internal/daemon.js +2 -2
- package/dist/src/internal/png-worker.js +1 -1
- package/dist/src/ios-snapshot-acquisition.js +1 -1
- package/dist/src/ios-snapshot-engine.js +1 -1
- package/dist/src/lease.js +1 -1
- package/dist/src/local-interactor-operation-set.js +1 -1
- package/dist/src/mechanics.js +16 -17
- package/dist/src/mobile-snapshot-semantics.js +1 -1
- package/dist/src/observe-until.js +1 -0
- package/dist/src/overlay.js +2 -2
- package/dist/src/parameterized-recorded-fill.js +1 -1
- package/dist/src/perf-facade.js +1 -1
- package/dist/src/perf-runtime-operation-builder.js +1 -1
- package/dist/src/perf-runtime-plan.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-managed-owner.js +1 -1
- package/dist/src/platform-runtime-operation-host.js +1 -1
- package/dist/src/platform-runtime-screen-recording-process-host.js +1 -1
- package/dist/src/platform-runtime.js +1 -1
- package/dist/src/platform-runtime2.js +1 -1
- package/dist/src/png-worker-client.js +1 -1
- package/dist/src/provider-device-admission.js +1 -0
- package/dist/src/provider-webdriver.js +1 -1
- package/dist/src/proxy.js +1 -1
- package/dist/src/react-native.js +1 -1
- package/dist/src/record-runtime.js +1 -1
- package/dist/src/registry.js +36 -36
- package/dist/src/replay-divergence.js +1 -1
- package/dist/src/replay.js +1 -1
- package/dist/src/request-admission.js +1 -1
- package/dist/src/request-runtime-binding.js +1 -1
- package/dist/src/runner-cache-metadata.js +2 -2
- package/dist/src/runner-client.js +1 -1
- package/dist/src/runner-dev-tools-security.js +1 -1
- package/dist/src/runner-disposal.js +1 -1
- package/dist/src/runner-error-classification.js +3 -3
- package/dist/src/runner-exchange.js +1 -1
- package/dist/src/runner-start-budget.js +1 -1
- package/dist/src/runner-startup-transport.js +1 -1
- package/dist/src/runner-xctestrun.js +1 -1
- package/dist/src/runner.js +1 -1
- package/dist/src/runtime-admission.js +1 -0
- package/dist/src/runtime.js +1 -1
- package/dist/src/runtime10.js +2 -2
- package/dist/src/runtime2.js +1 -1
- package/dist/src/runtime3.js +1 -1
- package/dist/src/runtime4.js +4 -4
- package/dist/src/runtime5.js +1 -1
- package/dist/src/runtime6.js +1 -1
- package/dist/src/runtime7.js +1 -1
- package/dist/src/runtime8.js +1 -1
- package/dist/src/runtime9.js +1 -1
- package/dist/src/screen-recording-resource-recovery.js +1 -1
- package/dist/src/screenshot-runtime.js +1 -1
- package/dist/src/script.js +1 -1
- package/dist/src/scroll-gesture.js +1 -1
- package/dist/src/sdk-batch-runner.js +2 -2
- package/dist/src/sdk-batch.js +1 -1
- package/dist/src/sdk-contracts.d.ts +16 -2
- package/dist/src/sdk-contracts.js +2 -2
- package/dist/src/sdk-finders.js +1 -1
- package/dist/src/sdk-selectors.d.ts +9 -0
- package/dist/src/sdk-selectors.js +1 -1
- package/dist/src/selection.js +0 -0
- package/dist/src/selector-pipeline-policy.js +1 -0
- package/dist/src/selector-runtime.js +1 -1
- package/dist/src/selectors.js +1 -1
- package/dist/src/server.js +1 -1
- package/dist/src/session-runtime-admission.js +1 -1
- package/dist/src/session-snapshot.js +1 -1
- package/dist/src/session-store.js +3 -3
- package/dist/src/session2.js +5 -5
- package/dist/src/snapshot-desktop-projection.js +1 -1
- package/dist/src/snapshot-runtime-binding.js +1 -1
- package/dist/src/snapshot-runtime.js +1 -1
- package/dist/src/snapshot-state.js +1 -1
- package/dist/src/snapshot4.js +1 -1
- package/dist/src/src.js +1 -1
- package/dist/src/src7.js +1 -1
- package/dist/src/target-evidence.js +1 -1
- package/dist/src/text-entry-focus.js +1 -1
- package/dist/src/touch-runtime.js +1 -1
- package/dist/src/touch-runtime2.js +1 -0
- 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 +1 -1
- package/server.json +2 -2
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.17.apk.sha256 +0 -1
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.17.apk.sha256 +0 -1
- package/dist/src/runner-command-traits.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{N as e,Q as t,W as n,X as r}from"./sdk-contracts.js";import{d as i,m as a,o}from"./lease-scope.js";import{w as s}from"./sdk-batch.js";import{n as c}from"./catalog.js";import{n as l,r as u}from"./diagnostics.js";import{c as d,p as f}from"./exec.js";import"./diagnostics2.js";import{r as p,t as m}from"./output-path.js";import{_ as h,f as ee,g as te,i as ne,m as g,n as _,s as re,t as v}from"./transport.js";import"./command.js";import{o as ie}from"./device-shell.js";import{a as ae}from"./version.js";import{t as oe}from"./daemon-resolution.js";import{n as se,t as y}from"./daemon-process.js";import{n as ce,o as le,t as ue}from"./request-progress-protocol.js";import{t as de}from"./session-artifact-paths.js";import b from"node:path";import x from"node:fs";import{createHash as fe,randomUUID as pe}from"node:crypto";import me from"node:os";import{Transform as he,Writable as ge}from"node:stream";import{pipeline as _e}from"node:stream/promises";import ve from"node:net";async function ye(e,t){let n=x.statSync(e),r=b.basename(e),i=n.isDirectory(),a=Se(t)??xe(e,n),o=[];try{let t=i?await be(e,o):e,n=x.statSync(t);return{payloadPath:t,fileName:r,artifactType:i?`app-bundle`:`file`,platform:a,contentType:i?`application/gzip`:`application/octet-stream`,sha256:await Ce(t),sizeBytes:n.size,cleanup:()=>S(o)}}catch(e){throw S(o),e}}async function be(e,t){let n=x.mkdtempSync(b.join(me.tmpdir(),`agent-device-upload-${pe()}-`));t.push(n);let r=b.join(n,`${b.basename(e)}.tar.gz`);return await d(`tar`,[`czf`,r,`-C`,b.dirname(e),b.basename(e)],{env:{...process.env,COPYFILE_DISABLE:`1`}}),r}function xe(e,t){let n=e.toLowerCase();if(t.isDirectory()&&n.endsWith(`.app`)||n.endsWith(`.ipa`))return`ios`;if(n.endsWith(`.apk`)||n.endsWith(`.aab`))return`android`}function Se(e){return e===`ios`||e===`android`?e:void 0}function S(e){for(let t of e)x.rmSync(t,{recursive:!0,force:!0})}async function Ce(t){let n=fe(`sha256`),r=new ge({write(e,t,r){n.update(e),r()}});return await _e(x.createReadStream(t),r).catch(t=>{throw new e(`COMMAND_FAILED`,`Failed to read local artifact`,{},t instanceof Error?t:void 0)}),n.digest(`hex`)}function we(e){let{stage:t,fileName:n,startOffset:r,totalBytes:i,onProgress:a}=e,o=r,s=De(i),c=Math.min(i,r+s);return new he({transform(e,r,l){o=Math.min(i,o+e.byteLength),o>=c&&(a?.({type:`progress`,stage:t,fileName:n,transferredBytes:o,totalBytes:i}),c=Math.min(i,o+s)),l(null,e)}})}function Te(){if(!(process.stderr.isTTY!==!0||process.env.CI))return e=>{process.stderr.write(`${Ee(e)}\n`)}}function Ee(e){switch(e.type){case`start`:return`Uploading ${e.fileName} (${w(e.totalBytes)}) via ${C(e.stage)} upload`;case`resume`:return`Resuming ${e.fileName} at ${w(e.transferredBytes)} of ${w(e.totalBytes)}`;case`progress`:return`Uploaded ${w(e.transferredBytes)} of ${w(e.totalBytes)} (${Oe(e.transferredBytes,e.totalBytes)})`;case`fallback`:return`Direct upload did not complete; retrying ${e.fileName} with ${C(e.to)} upload`}}function De(e){return Math.max(8388608,Math.ceil(e*.05))}function C(e){return e===`direct`?`direct`:`legacy`}function Oe(e,t){return t<=0?`100%`:`${Math.min(100,Math.floor(e/t*100))}%`}function w(e){if(e<1024)return`${e} B`;let t=e/1024;if(t<1024)return`${t.toFixed(1)} KiB`;let n=t/1024;return n<1024?`${n.toFixed(1)} MiB`:`${(n/1024).toFixed(1)} GiB`}const T=3e5,E=`uploadStreamRetryable`;async function D(e){return await O({...e,url:e.url,redirectCount:0,startOffset:0})}function ke(t){return t instanceof e&&t.details?.[E]===!0}async function O(t){let n=await _(t.url.protocol),r=x.statSync(t.payloadPath).size,i=je(t.headers,t.startOffset,r);return Ae(t.progress,t.startOffset,r),await new Promise((a,o)=>{let s=!1,c=n.request({protocol:t.url.protocol,host:t.url.hostname,port:t.url.port,method:t.method,path:t.url.pathname+t.url.search,headers:i,...t.signal?{signal:t.signal}:{}},n=>{s=!0,ne(n).then(i=>{clearTimeout(l);let s=n.statusCode??500,c=n.headers.location;if(c&&Me(s)){if(t.redirectCount>=5){o(new e(`COMMAND_FAILED`,`Artifact upload exceeded redirect limit`,{maxRedirects:5,url:t.url.toString()}));return}let n=new URL(c,t.url);O({...t,url:n,redirectCount:t.redirectCount+1}).then(a,o);return}let u=Ne(s)?Pe(n.headers,r):void 0;if(u!==void 0){if(u>=r){a({statusCode:200,statusMessage:`Upload already complete`,body:``});return}if(u<=t.startOffset){o(new e(`COMMAND_FAILED`,`Artifact upload resume did not advance`,{offset:u,previousOffset:t.startOffset,url:t.url.toString()}));return}O({...t,startOffset:u}).then(a,o);return}a({statusCode:s,statusMessage:n.statusMessage,body:i})}).catch(o)}),l=setTimeout(()=>{c.destroy(),o(new e(`COMMAND_FAILED`,t.timeoutMessage,{timeoutMs:T,...t.timeoutHint?{hint:t.timeoutHint}:{},...k(t)}))},T);c.on(`error`,n=>{if(!s){if(clearTimeout(l),t.signal?.aborted){o(t.signal.reason);return}o(new e(`COMMAND_FAILED`,t.errorMessage,{...t.errorHint?{hint:t.errorHint}:{},...k(t)},n))}}),c.on(`close`,()=>clearTimeout(l)),_e(x.createReadStream(t.payloadPath,{start:t.startOffset}),we({stage:t.progress?.stage??`legacy`,fileName:t.progress?.fileName??b.basename(t.payloadPath),startOffset:t.startOffset,totalBytes:r,onProgress:t.progress?.onProgress}),c).catch(t=>{if(s)return;c.destroy();let n=t instanceof Error?t:Error(String(t));o(new e(`COMMAND_FAILED`,`Failed to read local artifact`,{},n))})})}function k(e){return e.retryable===!0?{[E]:!0}:{}}function Ae(e,t,n){e?.onProgress?.({type:t>0?`resume`:`start`,stage:e.stage,fileName:e.fileName,transferredBytes:t,totalBytes:n})}function je(e,t,n){return t<=0?e:{...e,"content-length":Math.max(n-t,0),"content-range":`bytes ${t}-${n-1}/${n}`}}function Me(e){return[301,302,303,307,308].includes(e)}function Ne(e){return e===308}function Pe(e,t){let n=Fe(e[`x-upload-offset`]??e[`upload-offset`]);if(n!==void 0)return Math.min(n,t);let r=A(e.range)?.match(/^bytes=0-(\d+)$/);if(!r)return;let i=Number(r[1]);if(!(!Number.isSafeInteger(i)||i<0))return Math.min(i+1,t)}function Fe(e){let t=A(e);if(t===void 0)return;let n=Number(t);return Number.isSafeInteger(n)&&n>=0?n:void 0}function A(e){return Array.isArray(e)?e[0]:e}const j=3e4;async function M(e){let t=await ye(e.localPath,e.platform),n=e.baseUrl.endsWith(`/`)?e.baseUrl:`${e.baseUrl}/`,r=pe();try{let i=await ze({normalizedBase:n,token:e.token,artifact:t,uploadAttemptId:r,signal:e.signal});return i?.kind===`cache-hit`?i.uploadId:i?.kind===`direct-upload`?await Ie({normalizedBase:n,token:e.token,artifact:t,preflight:i,uploadAttemptId:r,onProgress:e.onProgress,signal:e.signal})||(e.onProgress?.({type:`fallback`,from:`direct`,to:`legacy`,fileName:t.fileName}),await N({normalizedBase:n,token:e.token,artifact:t,onProgress:e.onProgress,signal:e.signal})):await N({normalizedBase:n,token:e.token,artifact:t,onProgress:e.onProgress,signal:e.signal})}finally{t.cleanup()}}async function Ie(e){let t=async t=>(await Ue(e.artifact,t,e.onProgress,e.signal),await We({normalizedBase:e.normalizedBase,token:e.token,uploadId:t.uploadId,signal:e.signal}));try{return await t(e.preflight)}catch(n){if(e.signal?.aborted)throw n;return Re(n)?await Le(e,t):void 0}}async function Le(e,t){let n=await ze({normalizedBase:e.normalizedBase,token:e.token,artifact:e.artifact,uploadAttemptId:e.uploadAttemptId,signal:e.signal});if(n?.kind===`cache-hit`)return n.uploadId;if(n?.kind===`direct-upload`)try{return await t(n)}catch{return}}function Re(t){return t instanceof e?ke(t):!0}async function N(t){let{normalizedBase:n,token:r,artifact:i}=t,a=new URL(`upload`,n),o={"content-type":i.contentType,"x-artifact-type":i.artifactType,"x-artifact-filename":i.fileName,"x-artifact-hash":i.sha256,"x-artifact-hash-algorithm":`sha256`,"transfer-encoding":`chunked`};Object.assign(o,g(r));let s=await D({url:a,method:`POST`,headers:o,payloadPath:i.payloadPath,timeoutMessage:`Artifact upload timed out`,timeoutHint:`The upload to the remote daemon exceeded the 5-minute timeout.`,errorMessage:`Failed to upload artifact to remote daemon`,errorHint:`Verify the remote daemon is reachable and supports artifact uploads.`,signal:t.signal,progress:{stage:`legacy`,fileName:i.fileName,onProgress:t.onProgress}});try{let t=JSON.parse(s.body);if(!t.ok||!t.uploadId)throw new e(`COMMAND_FAILED`,`Upload failed: ${s.body}`);return t.uploadId}catch(t){throw t instanceof e?t:new e(`COMMAND_FAILED`,`Invalid upload response: ${s.body}`)}}async function ze(e){let t=new URL(`upload/preflight`,e.normalizedBase),n={"content-type":`application/json`};Object.assign(n,g(e.token));let r=await fetch(t,{method:`POST`,headers:n,signal:Be(e.signal,j),body:JSON.stringify({uploadAttemptId:e.uploadAttemptId,sha256:e.artifact.sha256,fileName:e.artifact.fileName,sizeBytes:e.artifact.sizeBytes,artifactType:e.artifact.artifactType,...e.artifact.platform?{platform:e.artifact.platform}:{},contentType:e.artifact.contentType})}).catch(t=>{if(e.signal?.aborted)throw t});if(r?.ok)return Ve(await r.json().catch(()=>void 0))}function Be(e,t){let n=AbortSignal.timeout(t);return e?AbortSignal.any([e,n]):n}function Ve(e){if(!e||typeof e!=`object`)return;let t=e;if(t.ok!==!0||typeof t.uploadId!=`string`)return;if(t.cacheHit===!0)return{kind:`cache-hit`,uploadId:t.uploadId};let n=t.upload;if(!n||typeof n.url!=`string`)return;let r=n.headers??{};if(He(r))return{kind:`direct-upload`,uploadId:t.uploadId,url:n.url,headers:r}}function He(e){return!e||typeof e!=`object`||Array.isArray(e)?!1:Object.values(e).every(e=>typeof e==`string`)}async function Ue(t,n,r,i){let a=await D({url:new URL(n.url),method:`PUT`,headers:n.headers,payloadPath:t.payloadPath,timeoutMessage:`Direct artifact upload timed out`,timeoutHint:`The direct upload ticket did not accept the artifact within the timeout.`,errorMessage:`Failed to upload artifact with direct upload ticket`,retryable:!0,signal:i,progress:{stage:`direct`,fileName:t.fileName,onProgress:r}});if(a.statusCode<200||a.statusCode>=300)throw new e(`COMMAND_FAILED`,`Direct artifact upload failed`,{statusCode:a.statusCode,statusMessage:a.statusMessage})}async function We(t){let n=new URL(`upload/finalize`,t.normalizedBase),r={"content-type":`application/json`};Object.assign(r,g(t.token));let i=await fetch(n,{method:`POST`,headers:r,signal:Be(t.signal,j),body:JSON.stringify({uploadId:t.uploadId})}).catch(n=>{throw t.signal?.aborted?n:new e(`COMMAND_FAILED`,`Failed to finalize direct artifact upload`,{},n)});if(!i.ok)throw new e(`COMMAND_FAILED`,`Direct artifact upload finalize failed`,{status:i.status,statusText:i.statusText});let a=await i.json().catch(()=>void 0);if(!a?.ok||!a.uploadId)throw new e(`COMMAND_FAILED`,`Invalid upload finalize response`);return a.uploadId}async function Ge(e,t,n){let r=[...e.positionals??[]],i=e.flags?{...e.flags}:void 0,a=e.meta?.installSource,o={},s,c=Te();if(!dt(t))return Ze({positionals:r,flags:i,installSource:a,uploadedArtifactId:s,clientArtifactPaths:o});Ke(e),i=Je(e,r,i,o);let l=await Qe(e,t,c,n);return l&&(a=l.installSource,s=l.uploadedArtifactId??s),e.command!==`install`&&e.command!==`reinstall`||(s=await qe(e,t,r,c,n)??s),Ze({positionals:r,flags:i,installSource:a,uploadedArtifactId:s,clientArtifactPaths:o})}function Ke(t){if(t.flags?.saveScript!==void 0)throw new e(`INVALID_ARGS`,`--save-script is not supported against a remote daemon: the healed script would be written on the daemon host, not on this machine.`,{hint:`Run the script against a local daemon to capture a healed .ad, or re-run without --save-script.`,command:t.command})}async function qe(e,t,n,r,i){let a=n.length===1?0:1,o=n[a];if(o===void 0)return;if(o.startsWith(`remote:`)){n[a]=o.slice(7);return}let s=Xe(o,e.meta?.cwd);if(s)return await M({localPath:s,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform,onProgress:r,signal:i})}function Je(e,t,n,r){let i=$e(e,t);if(!i)return n;i.positionalIndex!==void 0&&i.positionalPath!==void 0&&(t[i.positionalIndex]=i.positionalPath);let a=Ye(n,i.flagKey??`out`,i.flagPath);return r[i.field]=i.localPath,a}function Ye(e,t,n){return n===void 0?e:{...e??{},[t]:n}}function Xe(e,t){let n=b.isAbsolute(e)?e:b.resolve(t??process.cwd(),e);return x.existsSync(n)?n:void 0}function Ze(e){return{positionals:e.positionals,flags:e.flags,installSource:e.installSource,uploadedArtifactId:e.uploadedArtifactId,...Object.keys(e.clientArtifactPaths).length>0?{clientArtifactPaths:e.clientArtifactPaths}:{}}}async function Qe(e,t,n,r){let i=e.meta?.installSource;if(e.command!==`install_source`||!i||i.kind!==`path`)return null;let a=i.path.trim();if(!a)return{installSource:i};if(a.startsWith(`remote:`))return{installSource:{...i,path:a.slice(7)}};let o=b.isAbsolute(a)?a:b.resolve(e.meta?.cwd??process.cwd(),a);if(!x.existsSync(o))return{installSource:{...i,path:o}};let s=await M({localPath:o,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform,onProgress:n,signal:r});return{installSource:{...i,path:o},uploadedArtifactId:s}}function $e(e,t){if(e.command===`screenshot`){let n=it(e,`path`,`.png`);return t[0]?{field:`path`,localPath:n,positionalIndex:0,positionalPath:F(`screenshot`,`.png`)}:{field:`path`,localPath:n,positionalIndex:0,flagPath:F(`screenshot`,`.png`)}}if(e.command===`record`&&(t[0]??``).toLowerCase()===`start`){if(!nt(e)&&e.flags?.platform===void 0)return null;let t=tt(e),n=rt(it(e,`outPath`,t,1),e);return{field:`outPath`,localPath:n,positionalIndex:1,positionalPath:F(`recording`,b.extname(n)||t)}}return e.command===`test`?{field:`artifactsDir`,localPath:et(e),flagKey:`artifactsDir`,flagPath:ot(`test-artifacts`)}:null}function et(e){let t=e.flags?.artifactsDir;return at(P(t)?t:`.agent-device/test-artifacts`,e.meta?.cwd)}function tt(e){return p(e.flags?.platform)}function nt(e){return P(e.positionals?.[1])||P(e.flags?.out)}function rt(e,t){return t.flags?.platform===`web`?m(e,tt(t)):e}function it(e,t,n,r=0){let i=e.positionals?.[r]??e.flags?.out,a=`${t===`path`?`screenshot`:`recording`}-${Date.now()}${n}`;return at(P(i)?i:a,e.meta?.cwd)}function at(e,t){return b.isAbsolute(e)?e:b.resolve(t??process.cwd(),e)}function P(e){return typeof e==`string`&&e.trim().length>0}function F(e,t){let n=t.startsWith(`.`)?t:`.${t}`;return b.posix.join(`/tmp`,`agent-device-${e}-${Date.now()}-${Math.random().toString(36).slice(2,8)}${n}`)}function ot(e){return b.posix.join(`/tmp`,`agent-device-${e}-${Date.now()}-${Math.random().toString(36).slice(2,8)}`)}async function st(e,t,n){let r=Array.isArray(n.data?.artifacts)?n.data.artifacts:[];if(r.length===0||!e.baseUrl)return n;let i=n.data?{...n.data}:{},a=[];for(let n of r){if(!n||typeof n!=`object`||typeof n.artifactId!=`string`){a.push(n);continue}let r=ct(n,t),o=await lt({baseUrl:e.baseUrl,token:e.token,artifactId:n.artifactId,destinationPath:r,requestScope:t.meta,isDirectory:n.artifactType===`test-artifacts`});i[n.field]=o,a.push({...n,localPath:o})}return i.artifacts=a,{ok:!0,data:i}}function ct(e,t){if(e.localPath&&e.localPath.trim().length>0)return e.localPath;let n=t.meta?.clientArtifactPaths?.[e.field];if(n&&n.trim().length>0)return n;let r=e.fileName?.trim()||`${e.field}-${Date.now()}`;return b.resolve(t.meta?.cwd??process.cwd(),r)}async function lt(e){let{downloadRemoteArtifactFromUrl:t}=await import(`./artifact-download.js`);return await t({artifactUrl:new URL(ut(e.baseUrl,e.artifactId)),token:e.token,artifactId:e.artifactId,destinationPath:e.destinationPath,requestScope:e.requestScope,...e.timeoutMs===void 0?{}:{timeoutMs:e.timeoutMs},...e.isDirectory===void 0?{}:{isDirectory:e.isDirectory}})}function ut(e,t){let n=e.endsWith(`/`)?e:`${e}/`;return new URL(`artifacts/${encodeURIComponent(t)}`,n).toString()}function dt(e){return typeof e.baseUrl==`string`&&e.baseUrl.length>0}const ft=3e3,pt=1e3;function mt(e){let t=Et(e);if(!t||typeof t!=`object`)return null;let n=t,r=ht(n);if(!r)return null;let i=gt(n);return i?{token:r,...i,transport:vt(n.transport),pid:L(n.pid)??0,version:I(n.version),codeOrigin:_t(n.codeOrigin),codeSignature:I(n.codeSignature),processStartTime:I(n.processStartTime),policyDigest:I(n.policyDigest)}:null}function ht(e){return typeof e.token==`string`&&e.token.length>0?e.token:null}function gt(e){let t=L(e.port),n=L(e.httpPort);return t===void 0&&n===void 0?null:{port:t,httpPort:n}}function _t(e){return e===`installed`||e===`checkout`?e:void 0}function vt(e){return e===`socket`||e===`http`||e===`dual`?e:void 0}function I(e){return typeof e==`string`?e:void 0}function L(e){return Number.isInteger(e)&&Number(e)>0?Number(e):void 0}function R(e){let t=Et(e);if(!t||typeof t!=`object`)return null;let n=t;return Number.isInteger(n.pid)&&Number(n.pid)>0?{pid:Number(n.pid),processStartTime:typeof n.processStartTime==`string`?n.processStartTime:void 0,startedAt:typeof n.startedAt==`number`?n.startedAt:void 0}:null}function yt(e,t){let n=R(e.lockPath);return n!==null&&n.pid!==t&&y(n.pid,n.processStartTime)}function z(e){Dt(e)}function B(e){Dt(e)}function bt(e){let t=V(e);if(!t.hasLock||t.hasInfo)return;let n=R(e.lockPath);if(!n){B(e.lockPath);return}y(n.pid,n.processStartTime)||B(e.lockPath)}async function xt(e,t,n={}){let r=n.stopLiveProcesses??!0,i={reason:t,removedInfo:!1,removedLock:!1,stoppedInfoProcess:!1,stoppedLockProcess:!1};try{let t=x.existsSync(e.infoPath),n=mt(e.infoPath);if(n){let t=y(n.pid,n.processStartTime);t&&!r?i.retainedInfoProcess=!0:(t&&(await H(n),i.stoppedInfoProcess=!0),z(e.infoPath),i.removedInfo=!0)}else t&&(z(e.infoPath),i.removedInfo=!0);let a=x.existsSync(e.lockPath),o=R(e.lockPath);if(o){let t=y(o.pid,o.processStartTime);t&&!r?i.retainedLockProcess=!0:(t&&(await se(o.pid,{termTimeoutMs:ft,killTimeoutMs:pt,expectedStartTime:o.processStartTime}),i.stoppedLockProcess=!0),B(e.lockPath),i.removedLock=!0)}else a&&(B(e.lockPath),i.removedLock=!0)}catch(e){i.error=e instanceof Error?e.message:String(e)}return u({level:i.error?`warn`:`info`,phase:`daemon_startup_metadata_cleanup`,data:i}),i}function V(e){return{hasInfo:x.existsSync(e.infoPath),hasLock:x.existsSync(e.lockPath)}}async function St(e){let t=V(e);if(!t.hasLock||t.hasInfo)return!1;let n=R(e.lockPath);return!n||!y(n.pid,n.processStartTime)?(B(e.lockPath),!0):!1}async function H(e){await se(e.pid,{termTimeoutMs:ft,killTimeoutMs:pt,expectedStartTime:e.processStartTime})}function Ct(e){return typeof e.baseUrl==`string`&&e.baseUrl.length>0}function wt(e,t=oe(process.env.AGENT_DEVICE_STATE_DIR)){let n=Tt(t);return e.hasLock&&!e.hasInfo?`agent-device attempted to clean stale daemon metadata automatically, but ${t.lockPath} still exists without ${t.infoPath}. Retry with --debug; if this persists after confirming no agent-device daemon process is running, run: ${n}`:e.hasLock&&e.hasInfo?`agent-device attempted to clean stale daemon metadata automatically, but ${t.infoPath} and ${t.lockPath} still remain. Retry with --debug; if this persists after confirming no agent-device daemon process is running, run: ${n}`:e.hasInfo?`agent-device did not observe reachable daemon metadata after retrying, and ${t.infoPath} still remains. Stale metadata was cleaned automatically when safe; retry with --debug. If this persists after confirming no agent-device daemon process is running, run: ${n}`:`agent-device did not observe reachable daemon metadata after retrying. Stale metadata was cleaned automatically when safe; retry with --debug and check daemon diagnostics logs. If stale metadata returns after confirming no agent-device daemon process is running, run: ${n}`}function Tt(e){return`rm -f ${ie(e.infoPath)} ${ie(e.lockPath)}`}function Et(e){if(!x.existsSync(e))return null;try{return JSON.parse(x.readFileSync(e,`utf8`))}catch{return null}}function Dt(e){try{x.existsSync(e)&&x.unlinkSync(e)}catch{}}function U(t,n,r){return new e(`COMMAND_FAILED`,`Invalid daemon response`,{requestId:t.meta?.requestId,line:n},r instanceof Error?r:void 0)}function Ot(e){let t=t=>(e.onError(t),!0);return{handleLine(n){let r;try{r=JSON.parse(n)}catch(r){return t(U(e.req,n,r))}if(ue(r))try{return e.onProgress?.(r.event),!1}catch(e){return t(e)}return ce(r)?(e.onResponse(r.response),!0):e.responseFormat===`socket-legacy`?(e.onResponse(r),!0):t(U(e.req,n,Error(`Missing daemon progress response envelope`)))}}}function kt(e,t){return le(e)&&String(Array.isArray(t)?t.join(`,`):t??``).includes(`application/x-ndjson`)}function At(e,t){let{req:n,isSettled:r,resolve:i,reject:a,clearTimeout:o}=t,s=``,c=Ot({req:n,onProgress:t.onProgress,responseFormat:`socket-legacy`,onResponse(t){o(),i(t),e.end()},onError(e){o(),a(e)}});e.setEncoding(`utf8`),e.on(`data`,e=>{if(r())return;let t=v(s,e);s=t.buffer;for(let e of t.lines)if(c.handleLine(e))return}),e.on(`end`,()=>{if(r())return;let e=s.trim();e&&c.handleLine(e)||(o(),a(U(n,e)))})}function jt(t,n){let{req:r,handleResponseBody:i,reject:a,clearTimeout:o}=n,s=``,c=!1,l=Ot({req:r,onProgress:n.onProgress,responseFormat:`ndjson-envelope`,onResponse(e){c=!0,o(),i(JSON.stringify(e))},onError(e){c=!0,o(),a(e)}});t.setEncoding(`utf8`),t.on(`data`,e=>{if(c)return;let t=v(s,e);s=t.buffer;for(let e of t.lines)if(e&&l.handleLine(e))return}),t.on(`end`,()=>{if(c)return;let e=s.trim();e&&l.handleLine(e)||(c=!0,o(),a(U(r,e)))}),t.on(`error`,t=>{c||(c=!0,o(),a(new e(`COMMAND_FAILED`,`Failed to read daemon response`,{requestId:r.meta?.requestId},t instanceof Error?t:void 0)))})}const Mt=1e4,Nt=8388608;function Pt(e,t){return h(e,`sessions/${encodeURIComponent(t.session)}/requests/${encodeURIComponent(t.requestId)}/diagnostics`)}function Ft(e){let{logPath:t,...n}=e;return n}async function It(e,t){let n=Ft(e),r=e.diagnosticsRecord,i=r?.requestId??t.requestId;if(!r)return W(n,t.endpoint,i,`the daemon named no diagnostics record`);try{let e=de(t.stateDir,r),a=await Lt({endpoint:t.endpoint,ref:r,destinationPath:e});return a?W(n,t.endpoint,i,a):{...n,logPath:e}}catch(e){return W(n,t.endpoint,i,e instanceof Error?e.message:String(e))}}function W(e,t,n,r){return{...e,logPathUnavailable:`remote daemon ${t.baseUrl}, request ${n??`unknown`}: ${r}`}}async function Lt(e){let{endpoint:t,ref:n,destinationPath:r}=e,i;try{i=new URL(Pt(t.baseUrl,n))}catch{return`daemon base URL is not a valid URL`}try{let e=await _(i.protocol);return await x.promises.mkdir(b.dirname(r),{recursive:!0}),await new Promise(n=>{let a=!1,o=e=>{if(!a){if(a=!0,clearTimeout(c),e===void 0){n(void 0);return}x.promises.rm(r,{force:!0}).finally(()=>{n(e)})}},s=e.request({protocol:i.protocol,host:i.hostname,port:i.port,method:`GET`,path:i.pathname+i.search,headers:{...g(t.token),...te(t.tenantId)}},e=>{let t=e.statusCode??500;if(t!==200){e.resume(),o(`HTTP ${t}`);return}let n=x.createWriteStream(r),i=0;e.on(`data`,e=>{i+=e.length,i>Nt&&(s.destroy(),n.destroy(),o(`record exceeds ${Nt} bytes`))}),e.on(`error`,e=>{n.destroy(),o(e.message)}),n.on(`error`,e=>{o(e.message)}),n.on(`finish`,()=>{o(void 0)}),e.pipe(n)}),c=setTimeout(()=>{o(`fetch timed out after ${Mt}ms`),s.destroy()},Mt);s.on(`error`,e=>{o(e.message)}),s.end()})}catch(e){return e instanceof Error?e.message:String(e)}}function Rt(t,n){let{info:r,req:i,stateDir:a,resolve:o,reject:s}=n;try{let n=zt(t);if(n.error){Bt(n.error,{info:r,req:i,stateDir:a,reject:s});return}if(!n.result||typeof n.result!=`object`){s(new e(`COMMAND_FAILED`,`Invalid daemon RPC response`,{requestId:i.meta?.requestId}));return}Wt(r,i,n.result,o,s)}catch(n){s(new e(`COMMAND_FAILED`,`Invalid daemon response`,{requestId:i.meta?.requestId,line:t},n instanceof Error?n:void 0))}}function zt(e){return JSON.parse(e)}async function Bt(e,t){let{info:n,req:r,stateDir:i,reject:a}=t,o=r.meta?.requestId,s=Vt(e);if(!n.baseUrl){a(Ut(s,o));return}a(Ut(await It(s,{endpoint:{baseUrl:n.baseUrl,token:n.token,tenantId:r.meta?.tenantId},stateDir:i,requestId:o}),o))}function Vt(e){let t=e.data??{},i=Ht(t.cause);return{code:r(t.code==null?void 0:String(t.code),`COMMAND_FAILED`),message:String(t.message??e.message??`Daemon RPC request failed`),cause:i,details:typeof t.details==`object`&&t.details?t.details:void 0,hint:typeof t.hint==`string`?t.hint:void 0,diagnosticId:typeof t.diagnosticId==`string`?t.diagnosticId:void 0,logPath:typeof t.logPath==`string`?t.logPath:void 0,diagnosticsRecord:n(t.diagnosticsRecord),retriable:typeof t.retriable==`boolean`?t.retriable:void 0,supportedOn:typeof t.supportedOn==`string`?t.supportedOn:void 0}}function Ht(e){return t(e)}function Ut(t,n){return new e(r(t.code,`COMMAND_FAILED`),t.message,{...t.details??{},hint:t.hint,diagnosticId:t.diagnosticId,logPath:t.logPath,logPathUnavailable:t.logPathUnavailable,diagnosticsRecord:t.diagnosticsRecord,retriable:t.retriable,supportedOn:t.supportedOn,requestId:n},t.cause)}async function Wt(e,t,n,r,i){try{r(e.baseUrl&&n.ok?await st(e,t,n):n)}catch(e){i(e)}}function Gt(e,t){let n=e.meta?.requestId??l();return Kt(e.command)?{jsonrpc:`2.0`,id:n,method:qt(e.command),params:{...Jt(e,e.command,t),...e.command===`lease_allocate`?a(e.flags):{}}}:{jsonrpc:`2.0`,id:n,method:`agent_device.command`,params:e}}function Kt(e){return e===`lease_allocate`||e===`lease_heartbeat`||e===`lease_release`}function qt(e){switch(e){case`lease_allocate`:return`agent_device.lease.allocate`;case`lease_heartbeat`:return`agent_device.lease.heartbeat`;case`lease_release`:return`agent_device.lease.release`}}function Jt(e,t,n){return i(o(e),t,{includeTokenParam:n.includeTokenParam,token:e.token,session:e.session})}const Yt=[`xcodebuild .*AgentDeviceRunnerUITests/RunnerTests/testCommand`,String.raw`xcodebuild .*AgentDeviceRunner\.env\.session-`,String.raw`xcodebuild build-for-testing .*apple/runner/AgentDeviceRunner/AgentDeviceRunner\.xcodeproj`],Xt=new Set([`apple`,`ios`,`macos`]);function Zt(e){return e!==void 0&&Xt.has(e)}function G(t){let{info:n,statePaths:r,remote:i,timeoutMs:a,requestId:o,command:s,platform:c,session:l,action:d}=t,f=i?{terminated:0}:en(),p=!i&&Qt(s),m=p?tn(n,r):{forcedKill:!1},h=Zt(c)||f.terminated>0;return u({level:`error`,phase:`daemon_request_timeout`,data:{timeoutMs:a,requestId:o,command:s,timedOutRunnerPidsTerminated:f.terminated,timedOutRunnerCleanupError:f.error,daemonPidReset:p?n.pid:void 0,daemonPidForceKilled:p?m.forcedKill:void 0,daemonPreservedAfterTimeout:!i&&!p,daemonBaseUrl:n.baseUrl}}),new e(`COMMAND_FAILED`,`Daemon request timed out`,{timeoutMs:a,requestId:o,reason:`daemon_transport_timeout`,hint:$t({remote:i,resetDaemon:p,command:s,appleCleanupEvidence:h,session:l,action:d})})}function Qt(e){return s(e).onTimeout===`reset-daemon`}function $t(e){let{remote:t,resetDaemon:n,command:r,appleCleanupEvidence:i,session:a,action:o}=e;if(t)return r===c.record&&o===`stop`?`The remote daemon is still exporting the recording. Run agent-device record stop${a?` --session ${a}`:``} again to wait for that export and receive the completed recording.`:`Retry with --debug and verify the remote daemon URL, auth token, and remote host logs.`;if(!n){let e=i&&r===c.snapshot?` If this was the first Apple-platform snapshot on the device, run agent-device prepare ios-runner with the same --platform before snapshot/test so runner startup is handled explicitly.`:``;return`Retry with --debug and check daemon diagnostics logs. The timed-out ${r??`request`} request was canceled${i?` and Apple runner work was aborted when detected`:``}; the daemon was kept alive so the session can still be closed or inspected.${e}`}return i?`Retry with --debug and check daemon diagnostics logs. Timed-out Apple runner xcodebuild processes were terminated when detected.`:`Retry with --debug and check daemon diagnostics logs. The daemon was reset after the timeout.`}function en(){let e=0;try{for(let t of Yt)f(`pkill`,[`-f`,t],{allowFailure:!0}).exitCode===0&&(e+=1);return{terminated:e}}catch(t){return{terminated:e,error:t instanceof Error?t.message:String(t)}}}function tn(e,t){let n=!1;try{y(e.pid,e.processStartTime)&&(process.kill(e.pid,`SIGKILL`),n=!0)}catch{H(e)}finally{z(t.infoPath),B(t.lockPath)}return{forcedKill:n}}const nn=3e3,K=`Daemon HTTP endpoint is unavailable`,q=`Daemon socket endpoint is unavailable`;async function rn(e,t){let n=gn(e,t);if(await an(e,n))return!0;let r=_n(e,t,n);return r?await an(e,r):!1}async function an(e,t){return t===`http`?await sn(e):await on(e.port)}function on(e){return e?new Promise(t=>{let n=!1,r=ve.createConnection({host:`127.0.0.1`,port:e},()=>{i(!0)}),i=e=>{n||(n=!0,r.destroy(),t(e))};r.setTimeout(500),r.on(`timeout`,()=>{i(!1)}),r.on(`error`,()=>{i(!1)})}):Promise.resolve(!1)}function sn(e){return ln(e).then(e=>e.reachable)}async function cn(t,n){let r=await ln(t,n);if(!t.baseUrl||!r.reachable)return r;let i=[r,r.upstream].find(e=>typeof e?.rpcProtocolVersion==`number`&&e.rpcProtocolVersion!==2);if(i)throw new e(`COMMAND_FAILED`,`Remote daemon RPC protocol is incompatible`,{daemonBaseUrl:t.baseUrl,clientVersion:ae(),remoteVersion:i.version,remoteService:i.service,supportedRpcProtocolVersion:2,remoteRpcProtocolVersion:i.rpcProtocolVersion,hint:`Upgrade agent-device on the client or remote host so both support the same daemon RPC protocol.`});return r}async function ln(e,t){let n=e.baseUrl?h(e.baseUrl,`health`):e.httpPort?`http://127.0.0.1:${e.httpPort}/health`:null;if(!n)return{reachable:!1};let r=new URL(n),i=await _(r.protocol),a=Math.min(e.baseUrl?nn:500,t??1/0);if(a<=0)return{reachable:!1,timedOut:!0};let o=AbortSignal.timeout(Math.ceil(a));return await new Promise(t=>{let n=e.baseUrl?g(e.token):{},s=()=>o.aborted?{reachable:!1,timedOut:!0}:{reachable:!1},c=i.request({protocol:r.protocol,host:r.hostname,port:r.port,path:r.pathname+r.search,method:`GET`,timeout:a,signal:o,headers:n},e=>{let n=``;e.setEncoding(`utf8`),e.on(`data`,e=>{n+=e}),e.on(`end`,()=>{let r=e.statusCode??500;t({reachable:r<500,statusCode:r,...un(n)})}),e.on(`error`,()=>t(s())),e.on(`aborted`,()=>t(s()))});c.on(`timeout`,()=>{c.destroy(),t({reachable:!1,timedOut:!0})}),c.on(`error`,()=>{t(s())}),c.end()})}function un(e){try{let t=JSON.parse(e),n=t.upstream&&typeof t.upstream==`object`?dn(t.upstream):void 0;return{...dn(t),...n?{upstream:n}:{}}}catch{return{}}}function dn(e){return{service:typeof e.service==`string`?e.service:void 0,version:typeof e.version==`string`?e.version:void 0,rpcProtocolVersion:typeof e.rpcProtocolVersion==`number`?e.rpcProtocolVersion:void 0,...typeof e.instanceId==`string`?{instanceId:e.instanceId}:{},...typeof e.hostArch==`string`?{hostArch:e.hostArch}:{}}}async function fn(e,t,n,r,i,a={}){let o=gn(e,n),s=typeof i==`number`?performance.now()+i:void 0;try{return await Y(e,t,r,i,o,a)}catch(c){if(e.baseUrl&&mn(c))return await pn(e,t,r,i,s,o,a);hn(c)&&$(e);let l=_n(e,n,o);if(!l||!vn(c,o))throw c;return await Y(e,t,r,i,l,a)}}async function pn(t,n,r,i,a,o,s){$(t);let c=J(t,n,r,i,a),l=await cn(t,c);if(l.timedOut&&i!==void 0&&c!==void 0&&c<=nn)throw G({info:t,statePaths:r,...Z(n,!0,i)});let u=J(t,n,r,i,a);if(!l.reachable)throw new e(`COMMAND_FAILED`,`Remote daemon is unavailable`,{daemonBaseUrl:t.baseUrl});t.remoteInstanceId=l.instanceId,t.remoteUpstreamInstanceId=l.upstream?.instanceId,En(t,l);try{return await Y(t,n,r,u,o,s)}catch(e){throw hn(e)&&$(t),e}}function J(e,t,n,r,i){if(i===void 0||r===void 0)return;let a=i-performance.now();if(a>0)return a;throw G({info:e,statePaths:n,...Z(t,!0,r)})}function mn(t){return t instanceof e&&t.details?.reason===`remote_instance_mismatch`}function hn(t){return t instanceof e&&(t.details?.reason===`daemon_transport_failure`||t.details?.reason===`daemon_transport_timeout`||t.details?.reason===`daemon_response_read_failure`)}async function Y(e,t,n,r,i,a){return i===`http`?await wn(e,t,n,r,a):await xn(e,t,n,r,a)}function gn(t,n){if(t.baseUrl){if(n===`socket`)throw new e(`COMMAND_FAILED`,`Remote daemon endpoint only supports HTTP transport`,{daemonBaseUrl:t.baseUrl});return`http`}if(n===`http`||n===`socket`)return yn(t,n);let r=(t.transport===`socket`||t.transport===`dual`?[`socket`,`http`]:[`http`,`socket`]).find(e=>X(t,e));if(r)return r;throw new e(`COMMAND_FAILED`,`Daemon metadata has no reachable transport`)}function X(e,t){return t===`http`?!!e.httpPort:!!e.port}function _n(e,t,n){if(t!==`auto`||e.baseUrl)return null;let r=n===`socket`?`http`:`socket`;return X(e,r)?r:null}function vn(t,n){return n===`socket`&&t instanceof e&&t.code===`COMMAND_FAILED`&&t.message===`Failed to communicate with daemon`&&t.details?.daemonSocketRequestWritten===!1}function yn(t,n){if(X(t,n))return n;throw new e(`COMMAND_FAILED`,n===`http`?K:q)}function bn(t,n,r,i={}){return u({level:`error`,phase:`daemon_request_socket_error`,data:{requestId:n,message:t instanceof Error?t.message:String(t)}}),new e(`COMMAND_FAILED`,`Failed to communicate with daemon`,{...i,reason:`daemon_transport_failure`,requestId:n,hint:r?`Retry command. If this persists, verify the remote daemon URL, auth token, and remote host reachability.`:`Retry command. If this persists, clean stale daemon metadata and start a fresh session.`},t instanceof Error?t:void 0)}async function xn(t,n,r,i,a){let o=t.port;if(!o)throw new e(`COMMAND_FAILED`,q);return new Promise((e,s)=>{let c=!1,l=ve.createConnection({host:`127.0.0.1`,port:o},()=>{c=!0,l.write(`${JSON.stringify(n)}\n`)}),u=!1,d=typeof i==`number`?setTimeout(()=>{u=!0,l.destroy(),s(G({info:t,statePaths:r,...Z(n,!1,i)}))},i):void 0;At(l,{req:n,onProgress:a.onProgress,isSettled:()=>u,clearTimeout:()=>{d&&clearTimeout(d)},resolve:t=>{u=!0,e(t)},reject:e=>{u=!0,s(e)}}),l.on(`error`,e=>{u||(u=!0,d&&clearTimeout(d),s(bn(e,n.meta?.requestId,!1,{daemonSocketRequestWritten:c})))})})}function Z(e,t,n){return{remote:t,timeoutMs:n,requestId:e.meta?.requestId,command:e.command,platform:e.flags?.platform,session:e.session,action:e.positionals?.[0]}}function Sn(e){return{...e.remoteInstanceId?{[re]:e.remoteInstanceId}:{},...e.remoteUpstreamInstanceId?{[ee]:e.remoteUpstreamInstanceId}:{}}}function Cn(e,t){return e===409&&t[`x-agent-device-instance-mismatch`]===`true`}async function wn(t,n,r,i,a){let o=t.baseUrl?new URL(h(t.baseUrl,`rpc`)):t.httpPort?new URL(`http://127.0.0.1:${t.httpPort}/rpc`):null;if(!o)throw new e(`COMMAND_FAILED`,K);let s=JSON.stringify(Gt(n,{includeTokenParam:!t.baseUrl})),c={"content-type":`application/json`,"content-length":Buffer.byteLength(s)};t.baseUrl&&(Object.assign(c,g(t.token)),Object.assign(c,Sn(t)));let l=await _(o.protocol);return await new Promise((u,d)=>{let f=l.request({protocol:o.protocol,host:o.hostname,port:o.port,method:`POST`,path:o.pathname+o.search,headers:c},i=>{if(Cn(i.statusCode,i.headers??{})){i.resume(),m&&clearTimeout(m),d(new e(`COMMAND_FAILED`,`Remote daemon instance changed`,{reason:`remote_instance_mismatch`,daemonBaseUrl:t.baseUrl}));return}if(kt(n,i.headers?.[`content-type`])){jt(i,{req:n,onProgress:a.onProgress,reject:d,clearTimeout:()=>{m&&clearTimeout(m)},handleResponseBody:e=>{Rt(e,{info:t,req:n,stateDir:r.baseDir,resolve:u,reject:d})}});return}ne(i).catch(t=>{throw new e(`COMMAND_FAILED`,`Failed to read daemon response`,{requestId:n.meta?.requestId,reason:`daemon_response_read_failure`},t instanceof Error?t:void 0)}).then(e=>{m&&clearTimeout(m),Rt(e,{info:t,req:n,stateDir:r.baseDir,resolve:u,reject:d})}).catch(e=>{m&&clearTimeout(m),d(e)})}),p=Ct(t),m=typeof i==`number`?setTimeout(()=>{f.destroy(),d(G({info:t,statePaths:r,...Z(n,p,i)}))},i):void 0;f.on(`error`,e=>{m&&clearTimeout(m),d(bn(e,n.meta?.requestId,p))}),f.write(s),f.end()})}let Q;function Tn(e,t){return e.baseUrl===t.baseUrl&&e.token===t.token&&e.pid===t.pid}function En(e,t){!t.instanceId||t.upstream&&!t.upstream.instanceId||(Q={baseUrl:e.baseUrl??``,token:e.token,pid:e.pid,health:Promise.resolve(t)})}function $(e){Q&&Tn(Q,e)&&(Q=void 0)}async function Dn(e){if(Q&&Tn(Q,e))return await Q.health;let t={baseUrl:e.baseUrl??``,token:e.token,pid:e.pid,health:cn(e)};Q=t;try{let e=await t.health;return(!e.reachable||!e.instanceId||e.upstream&&!e.upstream.instanceId)&&Q===t&&(Q=void 0),e}catch(e){throw Q===t&&(Q=void 0),e}}export{Ge as _,fn as a,V as c,mt as d,St as f,H as g,wt as h,rn as i,yt as l,B as m,q as n,xt as o,z as p,Dn as r,bt as s,K as t,Ct as u};
|
|
1
|
+
import{J as e,N as t,et as n,nt as r}from"./sdk-contracts.js";import{d as i,m as a,o}from"./lease-scope.js";import{T as s}from"./sdk-batch.js";import{n as c}from"./catalog.js";import{n as l,r as u}from"./diagnostics.js";import{c as d,p as f}from"./exec.js";import"./diagnostics2.js";import{r as p,t as m}from"./output-path.js";import{_ as h,f as ee,g as te,i as ne,m as g,n as _,s as re,t as v}from"./transport.js";import"./command.js";import{o as ie}from"./device-shell.js";import{a as ae}from"./version.js";import{t as oe}from"./daemon-resolution.js";import{n as se,t as y}from"./daemon-process.js";import{n as ce,o as le,t as ue}from"./request-progress-protocol.js";import{t as de}from"./session-artifact-paths.js";import b from"node:path";import x from"node:fs";import{createHash as fe,randomUUID as pe}from"node:crypto";import me from"node:os";import{Transform as he,Writable as ge}from"node:stream";import{pipeline as _e}from"node:stream/promises";import ve from"node:net";async function ye(e,t){let n=x.statSync(e),r=b.basename(e),i=n.isDirectory(),a=Se(t)??xe(e,n),o=[];try{let t=i?await be(e,o):e,n=x.statSync(t);return{payloadPath:t,fileName:r,artifactType:i?`app-bundle`:`file`,platform:a,contentType:i?`application/gzip`:`application/octet-stream`,sha256:await Ce(t),sizeBytes:n.size,cleanup:()=>S(o)}}catch(e){throw S(o),e}}async function be(e,t){let n=x.mkdtempSync(b.join(me.tmpdir(),`agent-device-upload-${pe()}-`));t.push(n);let r=b.join(n,`${b.basename(e)}.tar.gz`);return await d(`tar`,[`czf`,r,`-C`,b.dirname(e),b.basename(e)],{env:{...process.env,COPYFILE_DISABLE:`1`}}),r}function xe(e,t){let n=e.toLowerCase();if(t.isDirectory()&&n.endsWith(`.app`)||n.endsWith(`.ipa`))return`ios`;if(n.endsWith(`.apk`)||n.endsWith(`.aab`))return`android`}function Se(e){return e===`ios`||e===`android`?e:void 0}function S(e){for(let t of e)x.rmSync(t,{recursive:!0,force:!0})}async function Ce(e){let n=fe(`sha256`),r=new ge({write(e,t,r){n.update(e),r()}});return await _e(x.createReadStream(e),r).catch(e=>{throw new t(`COMMAND_FAILED`,`Failed to read local artifact`,{},e instanceof Error?e:void 0)}),n.digest(`hex`)}function we(e){let{stage:t,fileName:n,startOffset:r,totalBytes:i,onProgress:a}=e,o=r,s=De(i),c=Math.min(i,r+s);return new he({transform(e,r,l){o=Math.min(i,o+e.byteLength),o>=c&&(a?.({type:`progress`,stage:t,fileName:n,transferredBytes:o,totalBytes:i}),c=Math.min(i,o+s)),l(null,e)}})}function Te(){if(!(process.stderr.isTTY!==!0||process.env.CI))return e=>{process.stderr.write(`${Ee(e)}\n`)}}function Ee(e){switch(e.type){case`start`:return`Uploading ${e.fileName} (${w(e.totalBytes)}) via ${C(e.stage)} upload`;case`resume`:return`Resuming ${e.fileName} at ${w(e.transferredBytes)} of ${w(e.totalBytes)}`;case`progress`:return`Uploaded ${w(e.transferredBytes)} of ${w(e.totalBytes)} (${Oe(e.transferredBytes,e.totalBytes)})`;case`fallback`:return`Direct upload did not complete; retrying ${e.fileName} with ${C(e.to)} upload`}}function De(e){return Math.max(8388608,Math.ceil(e*.05))}function C(e){return e===`direct`?`direct`:`legacy`}function Oe(e,t){return t<=0?`100%`:`${Math.min(100,Math.floor(e/t*100))}%`}function w(e){if(e<1024)return`${e} B`;let t=e/1024;if(t<1024)return`${t.toFixed(1)} KiB`;let n=t/1024;return n<1024?`${n.toFixed(1)} MiB`:`${(n/1024).toFixed(1)} GiB`}const T=3e5,E=`uploadStreamRetryable`;async function D(e){return await O({...e,url:e.url,redirectCount:0,startOffset:0})}function ke(e){return e instanceof t&&e.details?.[E]===!0}async function O(e){let n=await _(e.url.protocol),r=x.statSync(e.payloadPath).size,i=je(e.headers,e.startOffset,r);return Ae(e.progress,e.startOffset,r),await new Promise((a,o)=>{let s=!1,c=n.request({protocol:e.url.protocol,host:e.url.hostname,port:e.url.port,method:e.method,path:e.url.pathname+e.url.search,headers:i,...e.signal?{signal:e.signal}:{}},n=>{s=!0,ne(n).then(i=>{clearTimeout(l);let s=n.statusCode??500,c=n.headers.location;if(c&&Me(s)){if(e.redirectCount>=5){o(new t(`COMMAND_FAILED`,`Artifact upload exceeded redirect limit`,{maxRedirects:5,url:e.url.toString()}));return}let n=new URL(c,e.url);O({...e,url:n,redirectCount:e.redirectCount+1}).then(a,o);return}let u=Ne(s)?Pe(n.headers,r):void 0;if(u!==void 0){if(u>=r){a({statusCode:200,statusMessage:`Upload already complete`,body:``});return}if(u<=e.startOffset){o(new t(`COMMAND_FAILED`,`Artifact upload resume did not advance`,{offset:u,previousOffset:e.startOffset,url:e.url.toString()}));return}O({...e,startOffset:u}).then(a,o);return}a({statusCode:s,statusMessage:n.statusMessage,body:i})}).catch(o)}),l=setTimeout(()=>{c.destroy(),o(new t(`COMMAND_FAILED`,e.timeoutMessage,{timeoutMs:T,...e.timeoutHint?{hint:e.timeoutHint}:{},...k(e)}))},T);c.on(`error`,n=>{if(!s){if(clearTimeout(l),e.signal?.aborted){o(e.signal.reason);return}o(new t(`COMMAND_FAILED`,e.errorMessage,{...e.errorHint?{hint:e.errorHint}:{},...k(e)},n))}}),c.on(`close`,()=>clearTimeout(l)),_e(x.createReadStream(e.payloadPath,{start:e.startOffset}),we({stage:e.progress?.stage??`legacy`,fileName:e.progress?.fileName??b.basename(e.payloadPath),startOffset:e.startOffset,totalBytes:r,onProgress:e.progress?.onProgress}),c).catch(e=>{if(s)return;c.destroy();let n=e instanceof Error?e:Error(String(e));o(new t(`COMMAND_FAILED`,`Failed to read local artifact`,{},n))})})}function k(e){return e.retryable===!0?{[E]:!0}:{}}function Ae(e,t,n){e?.onProgress?.({type:t>0?`resume`:`start`,stage:e.stage,fileName:e.fileName,transferredBytes:t,totalBytes:n})}function je(e,t,n){return t<=0?e:{...e,"content-length":Math.max(n-t,0),"content-range":`bytes ${t}-${n-1}/${n}`}}function Me(e){return[301,302,303,307,308].includes(e)}function Ne(e){return e===308}function Pe(e,t){let n=Fe(e[`x-upload-offset`]??e[`upload-offset`]);if(n!==void 0)return Math.min(n,t);let r=A(e.range)?.match(/^bytes=0-(\d+)$/);if(!r)return;let i=Number(r[1]);if(!(!Number.isSafeInteger(i)||i<0))return Math.min(i+1,t)}function Fe(e){let t=A(e);if(t===void 0)return;let n=Number(t);return Number.isSafeInteger(n)&&n>=0?n:void 0}function A(e){return Array.isArray(e)?e[0]:e}const j=3e4;async function M(e){let t=await ye(e.localPath,e.platform),n=e.baseUrl.endsWith(`/`)?e.baseUrl:`${e.baseUrl}/`,r=pe();try{let i=await P({normalizedBase:n,token:e.token,artifact:t,uploadAttemptId:r,signal:e.signal});return i?.kind===`cache-hit`?i.uploadId:i?.kind===`direct-upload`?await Ie({normalizedBase:n,token:e.token,artifact:t,preflight:i,uploadAttemptId:r,onProgress:e.onProgress,signal:e.signal})||(e.onProgress?.({type:`fallback`,from:`direct`,to:`legacy`,fileName:t.fileName}),await N({normalizedBase:n,token:e.token,artifact:t,onProgress:e.onProgress,signal:e.signal})):await N({normalizedBase:n,token:e.token,artifact:t,onProgress:e.onProgress,signal:e.signal})}finally{t.cleanup()}}async function Ie(e){let t=async t=>(await He(e.artifact,t,e.onProgress,e.signal),await Ue({normalizedBase:e.normalizedBase,token:e.token,uploadId:t.uploadId,signal:e.signal}));try{return await t(e.preflight)}catch(n){if(e.signal?.aborted)throw n;return Re(n)?await Le(e,t):void 0}}async function Le(e,t){let n=await P({normalizedBase:e.normalizedBase,token:e.token,artifact:e.artifact,uploadAttemptId:e.uploadAttemptId,signal:e.signal});if(n?.kind===`cache-hit`)return n.uploadId;if(n?.kind===`direct-upload`)try{return await t(n)}catch{return}}function Re(e){return e instanceof t?ke(e):!0}async function N(e){let{normalizedBase:n,token:r,artifact:i}=e,a=new URL(`upload`,n),o={"content-type":i.contentType,"x-artifact-type":i.artifactType,"x-artifact-filename":i.fileName,"x-artifact-hash":i.sha256,"x-artifact-hash-algorithm":`sha256`,"transfer-encoding":`chunked`};Object.assign(o,g(r));let s=await D({url:a,method:`POST`,headers:o,payloadPath:i.payloadPath,timeoutMessage:`Artifact upload timed out`,timeoutHint:`The upload to the remote daemon exceeded the 5-minute timeout.`,errorMessage:`Failed to upload artifact to remote daemon`,errorHint:`Verify the remote daemon is reachable and supports artifact uploads.`,signal:e.signal,progress:{stage:`legacy`,fileName:i.fileName,onProgress:e.onProgress}});try{let e=JSON.parse(s.body);if(!e.ok||!e.uploadId)throw new t(`COMMAND_FAILED`,`Upload failed: ${s.body}`);return e.uploadId}catch(e){throw e instanceof t?e:new t(`COMMAND_FAILED`,`Invalid upload response: ${s.body}`)}}async function P(e){let t=new URL(`upload/preflight`,e.normalizedBase),n={"content-type":`application/json`};Object.assign(n,g(e.token));let r=await fetch(t,{method:`POST`,headers:n,signal:ze(e.signal,j),body:JSON.stringify({uploadAttemptId:e.uploadAttemptId,sha256:e.artifact.sha256,fileName:e.artifact.fileName,sizeBytes:e.artifact.sizeBytes,artifactType:e.artifact.artifactType,...e.artifact.platform?{platform:e.artifact.platform}:{},contentType:e.artifact.contentType})}).catch(t=>{if(e.signal?.aborted)throw t});if(r?.ok)return Be(await r.json().catch(()=>void 0))}function ze(e,t){let n=AbortSignal.timeout(t);return e?AbortSignal.any([e,n]):n}function Be(e){if(!e||typeof e!=`object`)return;let t=e;if(t.ok!==!0||typeof t.uploadId!=`string`)return;if(t.cacheHit===!0)return{kind:`cache-hit`,uploadId:t.uploadId};let n=t.upload;if(!n||typeof n.url!=`string`)return;let r=n.headers??{};if(Ve(r))return{kind:`direct-upload`,uploadId:t.uploadId,url:n.url,headers:r}}function Ve(e){return!e||typeof e!=`object`||Array.isArray(e)?!1:Object.values(e).every(e=>typeof e==`string`)}async function He(e,n,r,i){let a=await D({url:new URL(n.url),method:`PUT`,headers:n.headers,payloadPath:e.payloadPath,timeoutMessage:`Direct artifact upload timed out`,timeoutHint:`The direct upload ticket did not accept the artifact within the timeout.`,errorMessage:`Failed to upload artifact with direct upload ticket`,retryable:!0,signal:i,progress:{stage:`direct`,fileName:e.fileName,onProgress:r}});if(a.statusCode<200||a.statusCode>=300)throw new t(`COMMAND_FAILED`,`Direct artifact upload failed`,{statusCode:a.statusCode,statusMessage:a.statusMessage})}async function Ue(e){let n=new URL(`upload/finalize`,e.normalizedBase),r={"content-type":`application/json`};Object.assign(r,g(e.token));let i=await fetch(n,{method:`POST`,headers:r,signal:ze(e.signal,j),body:JSON.stringify({uploadId:e.uploadId})}).catch(n=>{throw e.signal?.aborted?n:new t(`COMMAND_FAILED`,`Failed to finalize direct artifact upload`,{},n)});if(!i.ok)throw new t(`COMMAND_FAILED`,`Direct artifact upload finalize failed`,{status:i.status,statusText:i.statusText});let a=await i.json().catch(()=>void 0);if(!a?.ok||!a.uploadId)throw new t(`COMMAND_FAILED`,`Invalid upload finalize response`);return a.uploadId}async function We(e,t,n){let r=[...e.positionals??[]],i=e.flags?{...e.flags}:void 0,a=e.meta?.installSource,o={},s,c=Te();if(!ut(t))return Xe({positionals:r,flags:i,installSource:a,uploadedArtifactId:s,clientArtifactPaths:o});Ge(e),i=qe(e,r,i,o);let l=await Ze(e,t,c,n);return l&&(a=l.installSource,s=l.uploadedArtifactId??s),e.command!==`install`&&e.command!==`reinstall`||(s=await Ke(e,t,r,c,n)??s),Xe({positionals:r,flags:i,installSource:a,uploadedArtifactId:s,clientArtifactPaths:o})}function Ge(e){if(e.flags?.saveScript!==void 0)throw new t(`INVALID_ARGS`,`--save-script is not supported against a remote daemon: the healed script would be written on the daemon host, not on this machine.`,{hint:`Run the script against a local daemon to capture a healed .ad, or re-run without --save-script.`,command:e.command})}async function Ke(e,t,n,r,i){let a=n.length===1?0:1,o=n[a];if(o===void 0)return;if(o.startsWith(`remote:`)){n[a]=o.slice(7);return}let s=Ye(o,e.meta?.cwd);if(s)return await M({localPath:s,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform,onProgress:r,signal:i})}function qe(e,t,n,r){let i=Qe(e,t);if(!i)return n;i.positionalIndex!==void 0&&i.positionalPath!==void 0&&(t[i.positionalIndex]=i.positionalPath);let a=Je(n,i.flagKey??`out`,i.flagPath);return r[i.field]=i.localPath,a}function Je(e,t,n){return n===void 0?e:{...e??{},[t]:n}}function Ye(e,t){let n=b.isAbsolute(e)?e:b.resolve(t??process.cwd(),e);return x.existsSync(n)?n:void 0}function Xe(e){return{positionals:e.positionals,flags:e.flags,installSource:e.installSource,uploadedArtifactId:e.uploadedArtifactId,...Object.keys(e.clientArtifactPaths).length>0?{clientArtifactPaths:e.clientArtifactPaths}:{}}}async function Ze(e,t,n,r){let i=e.meta?.installSource;if(e.command!==`install_source`||!i||i.kind!==`path`)return null;let a=i.path.trim();if(!a)return{installSource:i};if(a.startsWith(`remote:`))return{installSource:{...i,path:a.slice(7)}};let o=b.isAbsolute(a)?a:b.resolve(e.meta?.cwd??process.cwd(),a);if(!x.existsSync(o))return{installSource:{...i,path:o}};let s=await M({localPath:o,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform,onProgress:n,signal:r});return{installSource:{...i,path:o},uploadedArtifactId:s}}function Qe(e,t){if(e.command===`screenshot`){let n=rt(e,`path`,`.png`);return t[0]?{field:`path`,localPath:n,positionalIndex:0,positionalPath:I(`screenshot`,`.png`)}:{field:`path`,localPath:n,positionalIndex:0,flagPath:I(`screenshot`,`.png`)}}if(e.command===`record`&&(t[0]??``).toLowerCase()===`start`){if(!tt(e)&&e.flags?.platform===void 0)return null;let t=et(e),n=nt(rt(e,`outPath`,t,1),e);return{field:`outPath`,localPath:n,positionalIndex:1,positionalPath:I(`recording`,b.extname(n)||t)}}return e.command===`test`?{field:`artifactsDir`,localPath:$e(e),flagKey:`artifactsDir`,flagPath:at(`test-artifacts`)}:null}function $e(e){let t=e.flags?.artifactsDir;return it(F(t)?t:`.agent-device/test-artifacts`,e.meta?.cwd)}function et(e){return p(e.flags?.platform)}function tt(e){return F(e.positionals?.[1])||F(e.flags?.out)}function nt(e,t){return t.flags?.platform===`web`?m(e,et(t)):e}function rt(e,t,n,r=0){let i=e.positionals?.[r]??e.flags?.out,a=`${t===`path`?`screenshot`:`recording`}-${Date.now()}${n}`;return it(F(i)?i:a,e.meta?.cwd)}function it(e,t){return b.isAbsolute(e)?e:b.resolve(t??process.cwd(),e)}function F(e){return typeof e==`string`&&e.trim().length>0}function I(e,t){let n=t.startsWith(`.`)?t:`.${t}`;return b.posix.join(`/tmp`,`agent-device-${e}-${Date.now()}-${Math.random().toString(36).slice(2,8)}${n}`)}function at(e){return b.posix.join(`/tmp`,`agent-device-${e}-${Date.now()}-${Math.random().toString(36).slice(2,8)}`)}async function ot(e,t,n){let r=Array.isArray(n.data?.artifacts)?n.data.artifacts:[];if(r.length===0||!e.baseUrl)return n;let i=n.data?{...n.data}:{},a=[];for(let n of r){if(!n||typeof n!=`object`||typeof n.artifactId!=`string`){a.push(n);continue}let r=st(n,t),o=await ct({baseUrl:e.baseUrl,token:e.token,artifactId:n.artifactId,destinationPath:r,requestScope:t.meta,isDirectory:n.artifactType===`test-artifacts`});i[n.field]=o,a.push({...n,localPath:o})}return i.artifacts=a,{ok:!0,data:i}}function st(e,t){if(e.localPath&&e.localPath.trim().length>0)return e.localPath;let n=t.meta?.clientArtifactPaths?.[e.field];if(n&&n.trim().length>0)return n;let r=e.fileName?.trim()||`${e.field}-${Date.now()}`;return b.resolve(t.meta?.cwd??process.cwd(),r)}async function ct(e){let{downloadRemoteArtifactFromUrl:t}=await import(`./artifact-download.js`);return await t({artifactUrl:new URL(lt(e.baseUrl,e.artifactId)),token:e.token,artifactId:e.artifactId,destinationPath:e.destinationPath,requestScope:e.requestScope,...e.timeoutMs===void 0?{}:{timeoutMs:e.timeoutMs},...e.isDirectory===void 0?{}:{isDirectory:e.isDirectory}})}function lt(e,t){let n=e.endsWith(`/`)?e:`${e}/`;return new URL(`artifacts/${encodeURIComponent(t)}`,n).toString()}function ut(e){return typeof e.baseUrl==`string`&&e.baseUrl.length>0}const dt=3e3,ft=1e3;function pt(e){let t=Tt(e);if(!t||typeof t!=`object`)return null;let n=t,r=mt(n);if(!r)return null;let i=ht(n);return i?{token:r,...i,transport:_t(n.transport),pid:R(n.pid)??0,version:L(n.version),codeOrigin:gt(n.codeOrigin),codeSignature:L(n.codeSignature),processStartTime:L(n.processStartTime),policyDigest:L(n.policyDigest)}:null}function mt(e){return typeof e.token==`string`&&e.token.length>0?e.token:null}function ht(e){let t=R(e.port),n=R(e.httpPort);return t===void 0&&n===void 0?null:{port:t,httpPort:n}}function gt(e){return e===`installed`||e===`checkout`?e:void 0}function _t(e){return e===`socket`||e===`http`||e===`dual`?e:void 0}function L(e){return typeof e==`string`?e:void 0}function R(e){return Number.isInteger(e)&&Number(e)>0?Number(e):void 0}function z(e){let t=Tt(e);if(!t||typeof t!=`object`)return null;let n=t;return Number.isInteger(n.pid)&&Number(n.pid)>0?{pid:Number(n.pid),processStartTime:typeof n.processStartTime==`string`?n.processStartTime:void 0,startedAt:typeof n.startedAt==`number`?n.startedAt:void 0}:null}function vt(e,t){let n=z(e.lockPath);return n!==null&&n.pid!==t&&y(n.pid,n.processStartTime)}function B(e){Et(e)}function V(e){Et(e)}function yt(e){let t=H(e);if(!t.hasLock||t.hasInfo)return;let n=z(e.lockPath);if(!n){V(e.lockPath);return}y(n.pid,n.processStartTime)||V(e.lockPath)}async function bt(e,t,n={}){let r=n.stopLiveProcesses??!0,i={reason:t,removedInfo:!1,removedLock:!1,stoppedInfoProcess:!1,stoppedLockProcess:!1};try{let t=x.existsSync(e.infoPath),n=pt(e.infoPath);if(n){let t=y(n.pid,n.processStartTime);t&&!r?i.retainedInfoProcess=!0:(t&&(await U(n),i.stoppedInfoProcess=!0),B(e.infoPath),i.removedInfo=!0)}else t&&(B(e.infoPath),i.removedInfo=!0);let a=x.existsSync(e.lockPath),o=z(e.lockPath);if(o){let t=y(o.pid,o.processStartTime);t&&!r?i.retainedLockProcess=!0:(t&&(await se(o.pid,{termTimeoutMs:dt,killTimeoutMs:ft,expectedStartTime:o.processStartTime}),i.stoppedLockProcess=!0),V(e.lockPath),i.removedLock=!0)}else a&&(V(e.lockPath),i.removedLock=!0)}catch(e){i.error=e instanceof Error?e.message:String(e)}return u({level:i.error?`warn`:`info`,phase:`daemon_startup_metadata_cleanup`,data:i}),i}function H(e){return{hasInfo:x.existsSync(e.infoPath),hasLock:x.existsSync(e.lockPath)}}async function xt(e){let t=H(e);if(!t.hasLock||t.hasInfo)return!1;let n=z(e.lockPath);return!n||!y(n.pid,n.processStartTime)?(V(e.lockPath),!0):!1}async function U(e){await se(e.pid,{termTimeoutMs:dt,killTimeoutMs:ft,expectedStartTime:e.processStartTime})}function St(e){return typeof e.baseUrl==`string`&&e.baseUrl.length>0}function Ct(e,t=oe(process.env.AGENT_DEVICE_STATE_DIR)){let n=wt(t);return e.hasLock&&!e.hasInfo?`agent-device attempted to clean stale daemon metadata automatically, but ${t.lockPath} still exists without ${t.infoPath}. Retry with --debug; if this persists after confirming no agent-device daemon process is running, run: ${n}`:e.hasLock&&e.hasInfo?`agent-device attempted to clean stale daemon metadata automatically, but ${t.infoPath} and ${t.lockPath} still remain. Retry with --debug; if this persists after confirming no agent-device daemon process is running, run: ${n}`:e.hasInfo?`agent-device did not observe reachable daemon metadata after retrying, and ${t.infoPath} still remains. Stale metadata was cleaned automatically when safe; retry with --debug. If this persists after confirming no agent-device daemon process is running, run: ${n}`:`agent-device did not observe reachable daemon metadata after retrying. Stale metadata was cleaned automatically when safe; retry with --debug and check daemon diagnostics logs. If stale metadata returns after confirming no agent-device daemon process is running, run: ${n}`}function wt(e){return`rm -f ${ie(e.infoPath)} ${ie(e.lockPath)}`}function Tt(e){if(!x.existsSync(e))return null;try{return JSON.parse(x.readFileSync(e,`utf8`))}catch{return null}}function Et(e){try{x.existsSync(e)&&x.unlinkSync(e)}catch{}}function W(e,n,r){return new t(`COMMAND_FAILED`,`Invalid daemon response`,{requestId:e.meta?.requestId,line:n},r instanceof Error?r:void 0)}function Dt(e){let t=t=>(e.onError(t),!0);return{handleLine(n){let r;try{r=JSON.parse(n)}catch(r){return t(W(e.req,n,r))}if(ue(r))try{return e.onProgress?.(r.event),!1}catch(e){return t(e)}return ce(r)?(e.onResponse(r.response),!0):e.responseFormat===`socket-legacy`?(e.onResponse(r),!0):t(W(e.req,n,Error(`Missing daemon progress response envelope`)))}}}function Ot(e,t){return le(e)&&String(Array.isArray(t)?t.join(`,`):t??``).includes(`application/x-ndjson`)}function kt(e,t){let{req:n,isSettled:r,resolve:i,reject:a,clearTimeout:o}=t,s=``,c=Dt({req:n,onProgress:t.onProgress,responseFormat:`socket-legacy`,onResponse(t){o(),i(t),e.end()},onError(e){o(),a(e)}});e.setEncoding(`utf8`),e.on(`data`,e=>{if(r())return;let t=v(s,e);s=t.buffer;for(let e of t.lines)if(c.handleLine(e))return}),e.on(`end`,()=>{if(r())return;let e=s.trim();e&&c.handleLine(e)||(o(),a(W(n,e)))})}function At(e,n){let{req:r,handleResponseBody:i,reject:a,clearTimeout:o}=n,s=``,c=!1,l=Dt({req:r,onProgress:n.onProgress,responseFormat:`ndjson-envelope`,onResponse(e){c=!0,o(),i(JSON.stringify(e))},onError(e){c=!0,o(),a(e)}});e.setEncoding(`utf8`),e.on(`data`,e=>{if(c)return;let t=v(s,e);s=t.buffer;for(let e of t.lines)if(e&&l.handleLine(e))return}),e.on(`end`,()=>{if(c)return;let e=s.trim();e&&l.handleLine(e)||(c=!0,o(),a(W(r,e)))}),e.on(`error`,e=>{c||(c=!0,o(),a(new t(`COMMAND_FAILED`,`Failed to read daemon response`,{requestId:r.meta?.requestId},e instanceof Error?e:void 0)))})}const jt=1e4,Mt=8388608;function Nt(e,t){return h(e,`sessions/${encodeURIComponent(t.session)}/requests/${encodeURIComponent(t.requestId)}/diagnostics`)}function Pt(e){let{logPath:t,...n}=e;return n}async function Ft(e,t){let n=Pt(e),r=e.diagnosticsRecord,i=r?.requestId??t.requestId;if(!r)return G(n,t.endpoint,i,`the daemon named no diagnostics record`);try{let e=de(t.stateDir,r),a=await It({endpoint:t.endpoint,ref:r,destinationPath:e});return a?G(n,t.endpoint,i,a):{...n,logPath:e}}catch(e){return G(n,t.endpoint,i,e instanceof Error?e.message:String(e))}}function G(e,t,n,r){return{...e,logPathUnavailable:`remote daemon ${t.baseUrl}, request ${n??`unknown`}: ${r}`}}async function It(e){let{endpoint:t,ref:n,destinationPath:r}=e,i;try{i=new URL(Nt(t.baseUrl,n))}catch{return`daemon base URL is not a valid URL`}try{let e=await _(i.protocol);return await x.promises.mkdir(b.dirname(r),{recursive:!0}),await new Promise(n=>{let a=!1,o=e=>{if(!a){if(a=!0,clearTimeout(c),e===void 0){n(void 0);return}x.promises.rm(r,{force:!0}).finally(()=>{n(e)})}},s=e.request({protocol:i.protocol,host:i.hostname,port:i.port,method:`GET`,path:i.pathname+i.search,headers:{...g(t.token),...te(t.tenantId)}},e=>{let t=e.statusCode??500;if(t!==200){e.resume(),o(`HTTP ${t}`);return}let n=x.createWriteStream(r),i=0;e.on(`data`,e=>{i+=e.length,i>Mt&&(s.destroy(),n.destroy(),o(`record exceeds ${Mt} bytes`))}),e.on(`error`,e=>{n.destroy(),o(e.message)}),n.on(`error`,e=>{o(e.message)}),n.on(`finish`,()=>{o(void 0)}),e.pipe(n)}),c=setTimeout(()=>{o(`fetch timed out after ${jt}ms`),s.destroy()},jt);s.on(`error`,e=>{o(e.message)}),s.end()})}catch(e){return e instanceof Error?e.message:String(e)}}function Lt(e,n){let{info:r,req:i,stateDir:a,resolve:o,reject:s}=n;try{let n=Rt(e);if(n.error){zt(n.error,{info:r,req:i,stateDir:a,reject:s});return}if(!n.result||typeof n.result!=`object`){s(new t(`COMMAND_FAILED`,`Invalid daemon RPC response`,{requestId:i.meta?.requestId}));return}Ut(r,i,n.result,o,s)}catch(n){s(new t(`COMMAND_FAILED`,`Invalid daemon response`,{requestId:i.meta?.requestId,line:e},n instanceof Error?n:void 0))}}function Rt(e){return JSON.parse(e)}async function zt(e,t){let{info:n,req:r,stateDir:i,reject:a}=t,o=r.meta?.requestId,s=Bt(e);if(!n.baseUrl){a(Ht(s,o));return}a(Ht(await Ft(s,{endpoint:{baseUrl:n.baseUrl,token:n.token,tenantId:r.meta?.tenantId},stateDir:i,requestId:o}),o))}function Bt(t){let r=t.data??{},i=Vt(r.cause);return{code:n(r.code==null?void 0:String(r.code),`COMMAND_FAILED`),message:String(r.message??t.message??`Daemon RPC request failed`),cause:i,details:typeof r.details==`object`&&r.details?r.details:void 0,hint:typeof r.hint==`string`?r.hint:void 0,diagnosticId:typeof r.diagnosticId==`string`?r.diagnosticId:void 0,logPath:typeof r.logPath==`string`?r.logPath:void 0,diagnosticsRecord:e(r.diagnosticsRecord),retriable:typeof r.retriable==`boolean`?r.retriable:void 0,supportedOn:typeof r.supportedOn==`string`?r.supportedOn:void 0}}function Vt(e){return r(e)}function Ht(e,r){return new t(n(e.code,`COMMAND_FAILED`),e.message,{...e.details??{},hint:e.hint,diagnosticId:e.diagnosticId,logPath:e.logPath,logPathUnavailable:e.logPathUnavailable,diagnosticsRecord:e.diagnosticsRecord,retriable:e.retriable,supportedOn:e.supportedOn,requestId:r},e.cause)}async function Ut(e,t,n,r,i){try{r(e.baseUrl&&n.ok?await ot(e,t,n):n)}catch(e){i(e)}}function Wt(e,t){let n=e.meta?.requestId??l();return Gt(e.command)?{jsonrpc:`2.0`,id:n,method:Kt(e.command),params:{...qt(e,e.command,t),...e.command===`lease_allocate`?a(e.flags):{}}}:{jsonrpc:`2.0`,id:n,method:`agent_device.command`,params:e}}function Gt(e){return e===`lease_allocate`||e===`lease_heartbeat`||e===`lease_release`}function Kt(e){switch(e){case`lease_allocate`:return`agent_device.lease.allocate`;case`lease_heartbeat`:return`agent_device.lease.heartbeat`;case`lease_release`:return`agent_device.lease.release`}}function qt(e,t,n){return i(o(e),t,{includeTokenParam:n.includeTokenParam,token:e.token,session:e.session})}const Jt=[`xcodebuild .*AgentDeviceRunnerUITests/RunnerTests/testCommand`,String.raw`xcodebuild .*AgentDeviceRunner\.env\.session-`,String.raw`xcodebuild build-for-testing .*apple/runner/AgentDeviceRunner/AgentDeviceRunner\.xcodeproj`],Yt=new Set([`apple`,`ios`,`macos`]);function Xt(e){return e!==void 0&&Yt.has(e)}function K(e){let{info:n,statePaths:r,remote:i,timeoutMs:a,requestId:o,command:s,platform:c,session:l,action:d}=e,f=i?{terminated:0}:$t(),p=!i&&Zt(s),m=p?en(n,r):{forcedKill:!1},h=Xt(c)||f.terminated>0;return u({level:`error`,phase:`daemon_request_timeout`,data:{timeoutMs:a,requestId:o,command:s,timedOutRunnerPidsTerminated:f.terminated,timedOutRunnerCleanupError:f.error,daemonPidReset:p?n.pid:void 0,daemonPidForceKilled:p?m.forcedKill:void 0,daemonPreservedAfterTimeout:!i&&!p,daemonBaseUrl:n.baseUrl}}),new t(`COMMAND_FAILED`,`Daemon request timed out`,{timeoutMs:a,requestId:o,reason:`daemon_transport_timeout`,hint:Qt({remote:i,resetDaemon:p,command:s,appleCleanupEvidence:h,session:l,action:d})})}function Zt(e){return s(e).onTimeout===`reset-daemon`}function Qt(e){let{remote:t,resetDaemon:n,command:r,appleCleanupEvidence:i,session:a,action:o}=e;if(t)return r===c.record&&o===`stop`?`The remote daemon is still exporting the recording. Run agent-device record stop${a?` --session ${a}`:``} again to wait for that export and receive the completed recording.`:`Retry with --debug and verify the remote daemon URL, auth token, and remote host logs.`;if(!n){let e=i&&r===c.snapshot?` If this was the first Apple-platform snapshot on the device, run agent-device prepare ios-runner with the same --platform before snapshot/test so runner startup is handled explicitly.`:``;return`Retry with --debug and check daemon diagnostics logs. The timed-out ${r??`request`} request was canceled${i?` and Apple runner work was aborted when detected`:``}; the daemon was kept alive so the session can still be closed or inspected.${e}`}return i?`Retry with --debug and check daemon diagnostics logs. Timed-out Apple runner xcodebuild processes were terminated when detected.`:`Retry with --debug and check daemon diagnostics logs. The daemon was reset after the timeout.`}function $t(){let e=0;try{for(let t of Jt)f(`pkill`,[`-f`,t],{allowFailure:!0}).exitCode===0&&(e+=1);return{terminated:e}}catch(t){return{terminated:e,error:t instanceof Error?t.message:String(t)}}}function en(e,t){let n=!1;try{y(e.pid,e.processStartTime)&&(process.kill(e.pid,`SIGKILL`),n=!0)}catch{U(e)}finally{B(t.infoPath),V(t.lockPath)}return{forcedKill:n}}const tn=3e3,nn=`daemon_endpoint_unavailable`;function rn(e){return e instanceof t&&e.code===`COMMAND_FAILED`&&e.details?.reason===nn}function q(e){return new t(`COMMAND_FAILED`,e===`http`?`Daemon HTTP endpoint is unavailable`:`Daemon socket endpoint is unavailable`,{reason:nn,transport:e})}async function an(e,t){let n=_n(e,t);if(await J(e,n))return!0;let r=vn(e,t,n);return r?await J(e,r):!1}async function J(e,t){return t===`http`?await sn(e):await on(e.port)}function on(e){return e?new Promise(t=>{let n=!1,r=ve.createConnection({host:`127.0.0.1`,port:e},()=>{i(!0)}),i=e=>{n||(n=!0,r.destroy(),t(e))};r.setTimeout(500),r.on(`timeout`,()=>{i(!1)}),r.on(`error`,()=>{i(!1)})}):Promise.resolve(!1)}function sn(e){return ln(e).then(e=>e.reachable)}async function cn(e,n){let r=await ln(e,n);if(!e.baseUrl||!r.reachable)return r;let i=[r,r.upstream].find(e=>typeof e?.rpcProtocolVersion==`number`&&e.rpcProtocolVersion!==2);if(i)throw new t(`COMMAND_FAILED`,`Remote daemon RPC protocol is incompatible`,{daemonBaseUrl:e.baseUrl,clientVersion:ae(),remoteVersion:i.version,remoteService:i.service,supportedRpcProtocolVersion:2,remoteRpcProtocolVersion:i.rpcProtocolVersion,hint:`Upgrade agent-device on the client or remote host so both support the same daemon RPC protocol.`});return r}async function ln(e,t){let n=e.baseUrl?h(e.baseUrl,`health`):e.httpPort?`http://127.0.0.1:${e.httpPort}/health`:null;if(!n)return{reachable:!1};let r=new URL(n),i=await _(r.protocol),a=Math.min(e.baseUrl?tn:500,t??1/0);if(a<=0)return{reachable:!1,timedOut:!0};let o=AbortSignal.timeout(Math.ceil(a));return await new Promise(t=>{let n=e.baseUrl?g(e.token):{},s=()=>o.aborted?{reachable:!1,timedOut:!0}:{reachable:!1},c=i.request({protocol:r.protocol,host:r.hostname,port:r.port,path:r.pathname+r.search,method:`GET`,timeout:a,signal:o,headers:n},e=>{let n=``;e.setEncoding(`utf8`),e.on(`data`,e=>{n+=e}),e.on(`end`,()=>{let r=e.statusCode??500;t({reachable:r<500,statusCode:r,...un(n)})}),e.on(`error`,()=>t(s())),e.on(`aborted`,()=>t(s()))});c.on(`timeout`,()=>{c.destroy(),t({reachable:!1,timedOut:!0})}),c.on(`error`,()=>{t(s())}),c.end()})}function un(e){try{let t=JSON.parse(e),n=t.upstream&&typeof t.upstream==`object`?dn(t.upstream):void 0;return{...dn(t),...n?{upstream:n}:{}}}catch{return{}}}function dn(e){return{service:typeof e.service==`string`?e.service:void 0,version:typeof e.version==`string`?e.version:void 0,rpcProtocolVersion:typeof e.rpcProtocolVersion==`number`?e.rpcProtocolVersion:void 0,...typeof e.instanceId==`string`?{instanceId:e.instanceId}:{},...typeof e.hostArch==`string`?{hostArch:e.hostArch}:{}}}async function fn(e,t,n,r,i,a={}){let o=_n(e,n),s=typeof i==`number`?performance.now()+i:void 0;try{return await Y(e,t,r,i,o,a)}catch(c){if(e.baseUrl&&hn(c))return await pn(e,t,r,i,s,o,a);gn(c)&&$(e);let l=vn(e,n,o);if(!l||!yn(c,o))throw c;return await Y(e,t,r,i,l,a)}}async function pn(e,n,r,i,a,o,s){$(e);let c=mn(e,n,r,i,a),l=await cn(e,c);if(l.timedOut&&i!==void 0&&c!==void 0&&c<=tn)throw K({info:e,statePaths:r,...Z(n,!0,i)});let u=mn(e,n,r,i,a);if(!l.reachable)throw new t(`COMMAND_FAILED`,`Remote daemon is unavailable`,{daemonBaseUrl:e.baseUrl});e.remoteInstanceId=l.instanceId,e.remoteUpstreamInstanceId=l.upstream?.instanceId,Dn(e,l);try{return await Y(e,n,r,u,o,s)}catch(t){throw gn(t)&&$(e),t}}function mn(e,t,n,r,i){if(i===void 0||r===void 0)return;let a=i-performance.now();if(a>0)return a;throw K({info:e,statePaths:n,...Z(t,!0,r)})}function hn(e){return e instanceof t&&e.details?.reason===`remote_instance_mismatch`}function gn(e){return e instanceof t&&(e.details?.reason===`daemon_transport_failure`||e.details?.reason===`daemon_transport_timeout`||e.details?.reason===`daemon_response_read_failure`)}async function Y(e,t,n,r,i,a){return i===`http`?await Tn(e,t,n,r,a):await Sn(e,t,n,r,a)}function _n(e,n){if(e.baseUrl){if(n===`socket`)throw new t(`COMMAND_FAILED`,`Remote daemon endpoint only supports HTTP transport`,{daemonBaseUrl:e.baseUrl});return`http`}if(n===`http`||n===`socket`)return bn(e,n);let r=(e.transport===`socket`||e.transport===`dual`?[`socket`,`http`]:[`http`,`socket`]).find(t=>X(e,t));if(r)return r;throw new t(`COMMAND_FAILED`,`Daemon metadata has no reachable transport`)}function X(e,t){return t===`http`?!!e.httpPort:!!e.port}function vn(e,t,n){if(t!==`auto`||e.baseUrl)return null;let r=n===`socket`?`http`:`socket`;return X(e,r)?r:null}function yn(e,n){return n===`socket`&&e instanceof t&&e.code===`COMMAND_FAILED`&&e.message===`Failed to communicate with daemon`&&e.details?.daemonSocketRequestWritten===!1}function bn(e,t){if(X(e,t))return t;throw q(t)}function xn(e,n,r,i={}){return u({level:`error`,phase:`daemon_request_socket_error`,data:{requestId:n,message:e instanceof Error?e.message:String(e)}}),new t(`COMMAND_FAILED`,`Failed to communicate with daemon`,{...i,reason:`daemon_transport_failure`,requestId:n,hint:r?`Retry command. If this persists, verify the remote daemon URL, auth token, and remote host reachability.`:`Retry command. If this persists, clean stale daemon metadata and start a fresh session.`},e instanceof Error?e:void 0)}async function Sn(e,t,n,r,i){let a=e.port;if(!a)throw q(`socket`);return new Promise((o,s)=>{let c=!1,l=ve.createConnection({host:`127.0.0.1`,port:a},()=>{c=!0,l.write(`${JSON.stringify(t)}\n`)}),u=!1,d=typeof r==`number`?setTimeout(()=>{u=!0,l.destroy(),s(K({info:e,statePaths:n,...Z(t,!1,r)}))},r):void 0;kt(l,{req:t,onProgress:i.onProgress,isSettled:()=>u,clearTimeout:()=>{d&&clearTimeout(d)},resolve:e=>{u=!0,o(e)},reject:e=>{u=!0,s(e)}}),l.on(`error`,e=>{u||(u=!0,d&&clearTimeout(d),s(xn(e,t.meta?.requestId,!1,{daemonSocketRequestWritten:c})))})})}function Z(e,t,n){return{remote:t,timeoutMs:n,requestId:e.meta?.requestId,command:e.command,platform:e.flags?.platform,session:e.session,action:e.positionals?.[0]}}function Cn(e){return{...e.remoteInstanceId?{[re]:e.remoteInstanceId}:{},...e.remoteUpstreamInstanceId?{[ee]:e.remoteUpstreamInstanceId}:{}}}function wn(e,t){return e===409&&t[`x-agent-device-instance-mismatch`]===`true`}async function Tn(e,n,r,i,a){let o=e.baseUrl?new URL(h(e.baseUrl,`rpc`)):e.httpPort?new URL(`http://127.0.0.1:${e.httpPort}/rpc`):null;if(!o)throw q(`http`);let s=JSON.stringify(Wt(n,{includeTokenParam:!e.baseUrl})),c={"content-type":`application/json`,"content-length":Buffer.byteLength(s)};e.baseUrl&&(Object.assign(c,g(e.token)),Object.assign(c,Cn(e)));let l=await _(o.protocol);return await new Promise((u,d)=>{let f=l.request({protocol:o.protocol,host:o.hostname,port:o.port,method:`POST`,path:o.pathname+o.search,headers:c},i=>{if(wn(i.statusCode,i.headers??{})){i.resume(),m&&clearTimeout(m),d(new t(`COMMAND_FAILED`,`Remote daemon instance changed`,{reason:`remote_instance_mismatch`,daemonBaseUrl:e.baseUrl}));return}if(Ot(n,i.headers?.[`content-type`])){At(i,{req:n,onProgress:a.onProgress,reject:d,clearTimeout:()=>{m&&clearTimeout(m)},handleResponseBody:t=>{Lt(t,{info:e,req:n,stateDir:r.baseDir,resolve:u,reject:d})}});return}ne(i).catch(e=>{throw new t(`COMMAND_FAILED`,`Failed to read daemon response`,{requestId:n.meta?.requestId,reason:`daemon_response_read_failure`},e instanceof Error?e:void 0)}).then(t=>{m&&clearTimeout(m),Lt(t,{info:e,req:n,stateDir:r.baseDir,resolve:u,reject:d})}).catch(e=>{m&&clearTimeout(m),d(e)})}),p=St(e),m=typeof i==`number`?setTimeout(()=>{f.destroy(),d(K({info:e,statePaths:r,...Z(n,p,i)}))},i):void 0;f.on(`error`,e=>{m&&clearTimeout(m),d(xn(e,n.meta?.requestId,p))}),f.write(s),f.end()})}let Q;function En(e,t){return e.baseUrl===t.baseUrl&&e.token===t.token&&e.pid===t.pid}function Dn(e,t){!t.instanceId||t.upstream&&!t.upstream.instanceId||(Q={baseUrl:e.baseUrl??``,token:e.token,pid:e.pid,health:Promise.resolve(t)})}function $(e){Q&&En(Q,e)&&(Q=void 0)}async function On(e){if(Q&&En(Q,e))return await Q.health;let t={baseUrl:e.baseUrl??``,token:e.token,pid:e.pid,health:cn(e)};Q=t;try{let e=await t.health;return(!e.reachable||!e.instanceId||e.upstream&&!e.upstream.instanceId)&&Q===t&&(Q=void 0),e}catch(e){throw Q===t&&(Q=void 0),e}}export{bt as a,vt as c,xt as d,B as f,We as g,U as h,fn as i,St as l,Ct as m,an as n,yt as o,V as p,rn as r,H as s,On as t,pt as u};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime.js";import{N as t}from"./sdk-contracts.js";import{
|
|
1
|
+
import{r as e}from"./rolldown-runtime.js";import{N as t}from"./sdk-contracts.js";import{f as n}from"./sdk-batch.js";import r from"node:path";import i from"node:fs";import a from"node:crypto";var o=e({DAEMON_POLICY_ENV:()=>s,loadDaemonPolicy:()=>g,parseDaemonPolicy:()=>_,resolveDaemonPolicyCommandName:()=>m});const s=`AGENT_DEVICE_DAEMON_POLICY`,c=[`device-shutdown`],l=n,u=new Set(l.filter(e=>e.catalog.group===`internal`&&e.daemon!==void 0&&e.platformExecution.kind===`none`).map(e=>e.name)),d=new Map(l.flatMap(e=>{let{group:t,servesPublicCommand:n}=e.catalog;return t===`public`?[[e.name,e.name]]:t!==`internal`||u.has(e.name)?[]:[[e.name,n??e.name]]})),f=new Set(d.values()),p=new Set(l.filter(e=>e.catalog.group===`local-cli`).map(e=>e.name));function m(e){if(!u.has(e))return d.get(e)??e}const h=new Set([`version`,`devices`,`commands`,`capabilities`]);function g(e=process.env){let t=e[s]?.trim();if(!t)return;let n=r.resolve(t),a;try{a=JSON.parse(i.readFileSync(n,`utf8`))}catch(e){throw w(n,`cannot read policy JSON: ${T(e)}`)}return _(a,n)}function _(e,t){let n=x(e,`policy`,t);for(let e of Object.keys(n))if(!h.has(e))throw w(t,`unknown key "${e}"`);if(n.version!==1)throw w(t,`"version" must be 1`);let r=n.devices===void 0?void 0:v(n.devices,t),i=n.commands===void 0?void 0:y(n.commands,t),o=n.capabilities===void 0?new Set:b(n.capabilities,t),s=JSON.stringify({devices:r?[...r].sort():null,commands:i?{mode:i.mode,names:[...i.names].sort()}:null,capabilities:[...o].sort()});return Object.freeze({sourcePath:t,digest:a.createHash(`sha256`).update(s).digest(`hex`),deviceIds:r,commands:i,deniedCapabilities:o})}function v(e,t){let n=x(e,`devices`,t);C(n,[`allow`],`devices`,t);let r=S(n.allow,`devices.allow`,t);if(r.length===0)throw w(t,`"devices.allow" must not be empty`);return new Set(r.map((e,n)=>{let r=`devices.allow[${n}]`,i=x(e,r,t);C(i,[`udid`,`serial`],r,t);let a=[i.udid,i.serial].filter(e=>e!==void 0);if(a.length!==1||typeof a[0]!=`string`||!a[0].trim())throw w(t,`"${r}" must name exactly one "udid" or "serial"`);return a[0].trim()}))}function y(e,t){let n=x(e,`commands`,t);if(C(n,[`allow`,`deny`],`commands`,t),n.allow===void 0==(n.deny===void 0))throw w(t,`"commands" must set exactly one of "allow" or "deny"`);let r=n.allow===void 0?`deny`:`allow`,i=`commands.${r}`,a=S(n[r],i,t).map(e=>{if(typeof e==`string`&&p.has(e))throw w(t,`"${i}" names ${JSON.stringify(e)}, which runs in the client; name the daemon command it sends, such as "runtime"`);if(typeof e!=`string`||!f.has(e))throw w(t,`"${i}" names unknown command ${JSON.stringify(e)}`);return e});return Object.freeze({mode:r,names:new Set(a)})}function b(e,t){let n=x(e,`capabilities`,t);C(n,[`deny`],`capabilities`,t);let r=c;return new Set(S(n.deny,`capabilities.deny`,t).map(e=>{if(typeof e!=`string`||!r.includes(e))throw w(t,`"capabilities.deny" names unknown capability ${JSON.stringify(e)}`);return e}))}function x(e,t,n){if(typeof e==`object`&&e&&!Array.isArray(e))return e;throw w(n,`"${t}" must be an object`)}function S(e,t,n){if(Array.isArray(e))return e;throw w(n,`"${t}" must be an array`)}function C(e,t,n,r){for(let i of Object.keys(e))if(!t.includes(i))throw w(r,`unknown key "${n}.${i}"`)}function w(e,n){return new t(`INVALID_ARGS`,`Invalid daemon policy ${e}: ${n}`,{policyPath:e,hint:`Fix the file named by ${s}, then start the daemon again.`})}function T(e){return e instanceof Error?e.message:String(e)}export{g as n,m as r,o as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{_ as e,o as t,x as n}from"./sdk-device.js";import{
|
|
1
|
+
import{_ as e,o as t,x as n}from"./sdk-device.js";import{Zt as r}from"./sdk-batch.js";import{b as i,n as a}from"./owner-identity.js";import"./process.js";import{t as o}from"./daemon-registration.js";import{r as s}from"./durable-resource.js";import"./src7.js";import c from"node:path";import l from"node:fs";import u from"node:crypto";import d from"node:os";function f(e){return p(`family`in e?e.family:e.platform,e.appleOs,e.id)}function p(e,t,n){return`local:${e}:${t??`none`}:${n}`}function m(){let e=process.env.AGENT_DEVICE_CLAIMS_DIR?.trim();return e?c.resolve(e):c.join(d.homedir(),`.agent-device`,`device-claims`)}function h(e){let t=u.createHash(`sha256`).update(e).digest(`hex`);return c.join(m(),`${t}.json`)}function g(e){return{deviceKey:e.deviceKey,ownerToken:e.ownerToken,ownerPid:e.ownerPid,ownerStartTime:e.ownerStartTime}}function _(e){return e.schemaVersion===3}function v(e){return r(e.allocator.instanceId)}function y(e){return D(e)?e.schemaVersion===3?S(e):e.schemaVersion===2?O(e):e.schemaVersion===1?k(e):null:null}function b(e){return D(e)&&e.schemaVersion===3}const x=[`ownerPid`,`ownerStartTime`,`ownerToken`,`session`,`workspace`,`abandonedAtMs`];function S(e){if(e.kind!==`allocator`||C(e))return null;let t=w(e);return t&&{schemaVersion:3,kind:`allocator`,...t}}function C(e){return x.some(t=>e[t]!==void 0)}function w(e){if(!D(e.device)||!P(e.device.name))return null;let t=e.device.name,n=s(e.device),r=F(e.deviceKey),i=F(e.stateDir),a=T(e.allocator),o=N(e);return!n||!r||!i||!a||!o||r!==f(n)?null:{deviceKey:r,device:{...n,name:t},stateDir:i,allocator:a,createdAtMs:o.createdAtMs,updatedAtMs:o.updatedAtMs}}function T(e){if(!D(e))return null;let t=E(e.instanceId),n=E(e.identityIncarnationId);return t&&n?{instanceId:t,identityIncarnationId:n}:null}function E(e){return P(e)&&e===e.trim()?e:null}function D(e){return!!e&&typeof e==`object`&&!Array.isArray(e)}function O(e){if(!D(e.device)||!P(e.device.name))return null;let t=s(e.device);return t?A(e,t,e.device.name):null}function k(n){if(!D(n.device))return null;let r=n.device,i=r.name;if(!P(i)||!e(r.platform))return null;let a=t(r.platform),o=s({id:r.id,family:a.platform,kind:r.kind,target:r.target,...r.appleOs===void 0?a.platform===`apple`?{appleOs:r.platform===`macos`?`macos`:`ios`}:{}:{appleOs:r.appleOs},...r.iosPhysicalDeviceBackend===void 0?{}:{iosPhysicalDeviceBackend:r.iosPhysicalDeviceBackend}});return o?A(n,o,i):null}function A(e,t,n){let r=j(e),i=M(e),a=N(e);return!r||!i||!a||r.deviceKey!==f(t)?null:{schemaVersion:2,...r,device:{...t,name:n},...i,...a}}function j(e){let t=F(e.deviceKey),n=F(e.session),r=F(e.workspace),i=F(e.stateDir);return!t||!n||!r||!i?null:{deviceKey:t,session:n,workspace:r,stateDir:i}}function M(e){let{ownerPid:t,ownerStartTime:n}=e,r=F(e.ownerToken);return!I(t)||!r||n!==null&&!P(n)?null:{ownerPid:t,ownerStartTime:n,ownerToken:r}}function N(e){let{createdAtMs:t,updatedAtMs:n,abandonedAtMs:r}=e;return!L(t)||!L(n)||r!==void 0&&!L(r)?null:{createdAtMs:t,updatedAtMs:n,...L(r)?{abandonedAtMs:r}:{}}}function P(e){return typeof e==`string`&&e.length>0}function F(e){return P(e)?e:null}function I(e){return typeof e==`number`&&Number.isInteger(e)&&e>0}function L(e){return typeof e==`number`&&Number.isFinite(e)}function R(e){let t=m(),n=z(t);if(`claims`in n)return n.claims;let r=n.entries.filter(e=>e.isFile()&&e.name.endsWith(`.json`)).map(e=>K(c.join(t,e.name))).filter(e=>e!==null).filter(t=>B(t.claim??t.allocatorClaim,e)),a=i(r.flatMap(e=>e.claim?[e.claim.ownerPid]:[]));return r.map(e=>e.claim?J(e,a.get(e.claim.ownerPid)??null):e)}function z(e){try{return{entries:l.readdirSync(e,{withFileTypes:!0})}}catch(t){let n=t.code;return n===`ENOENT`||n===`ENOTDIR`?{claims:[]}:{claims:[{fileName:c.basename(e),classification:`unknown`,error:String(t)}]}}}function B(e,t){return!e||[V(e,t.udid??t.serial),H(e,t.device),U(e,t.platform)].every(Boolean)}function V(e,t){return!t||e.device.id===t}function H(e,t){return!t||e.device.name===t||e.device.id===t}function U(e,t){return n({platform:e.device.family,appleOs:e.device.appleOs},t)}function W(e){let t=K(e);return t?.claim?J(t,i([t.claim.ownerPid]).get(t.claim.ownerPid)??null):t}function G(e){let t=K(e);return t?.allocatorClaim||t?.classification===`allocator-inconsistent`?t:null}function K(e){let t=c.basename(e);try{return q(t,l.readFileSync(e,`utf8`))}catch(e){let n=e.code;return n===`ENOENT`||n===`ENOTDIR`?null:{fileName:t,classification:`unknown`,error:String(e)}}}function q(e,t){try{let n=JSON.parse(t),r=y(n);return r?_(r)?{fileName:e,deviceKey:r.deviceKey,allocatorClaim:r,classification:`allocator-held`}:{fileName:e,deviceKey:r.deviceKey,claim:r,classification:`unknown`}:{fileName:e,classification:b(n)?`allocator-inconsistent`:`inconsistent`}}catch(t){return{fileName:e,classification:`inconsistent`,error:String(t)}}}function J(e,t){let n=e.claim;if(!n)return e;let r={pid:n.ownerPid,startTime:n.ownerStartTime},i=a({owner:r,stateDir:n.stateDir},t),s=i===`live`&&o({...r,stateDir:n.stateDir});return{...e,classification:s?`owner-daemon-superseded`:i}}function Y(e){switch(e){case`owner-process-dead`:case`owner-process-reused`:case`owner-state-dir-gone`:case`owner-daemon-superseded`:return!0;case`live`:case`unknown`:case`inconsistent`:return!1;case`allocator-inconsistent`:return!1;case`allocator-held`:return!1}}function X(e){switch(e){case`owner-process-dead`:case`owner-daemon-superseded`:return!0;case`live`:case`owner-process-reused`:case`owner-state-dir-gone`:case`unknown`:case`inconsistent`:return!1;case`allocator-inconsistent`:return!1;case`allocator-held`:return!1}}export{G as a,f as c,R as i,h as l,Y as n,v as o,W as r,g as s,X as t,m as u};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{F as e,N as t,P as n,c as r,o as i}from"./sdk-contracts.js";import"./capture.js";import{i as a,p as o}from"./sdk-batch-runner.js";import{p as s}from"./android-input-ownership.js";import{C as c,d as l,l as u,p as d}from"./sdk-device.js";import{f,n as p,u as m}from"./lease-scope.js";import{$t as h,Er as ee,Ir as te,Jr as g,Jt as ne,ar as re,en as ie,kr as ae}from"./sdk-batch.js";import{a as oe}from"./script.js";import"./session-store.js";import{i as se}from"./back-mode.js";import{r as _}from"./diagnostics.js";import{t as ce}from"./timeouts.js";import"./diagnostics2.js";import{s as le}from"./device-shell.js";import{n as ue}from"./retry.js";import{n as v}from"./runtime-transport-hints.js";import{_ as de,a as fe,c as pe,d as y,f as me,g as he,h as ge,i as _e,l as ve,m as ye,n as b,o as be,p as x,r as xe,s as S,u as Se,v as Ce,y as we}from"./human-control-contract.js";import{c as Te}from"./request-cancel.js";import{t as Ee}from"./request.js";import{n as De,t as Oe,u as ke}from"./provider-session-ownership.js";import{r as Ae}from"./application-lifecycle-runtime.js";import{a as je,c as C,l as Me,n as Ne,o as Pe,r as Fe,t as Ie}from"./device-claim-inspection.js";import{b as Le,c as Re,g as ze,i as Be,p as Ve,x as w}from"./perf-runtime-plan.js";import{n as He,r as Ue,t as We}from"./lease-context.js";import{d as Ge,g as Ke,u as qe}from"./screenshot-runtime.js";import{n as Je}from"./screen-recording-admission-ledger.js";import{a as Ye,c as Xe,d as T,l as Ze,n as Qe,o as $e,r as et,u as E}from"./src8.js";import{n as tt,t as nt}from"./compatibility-policy.js";import{o as rt}from"./screen-recording-resource-recovery.js";import D from"node:path";import"node:fs";import it,{createHash as at}from"node:crypto";import ot from"node:os";import O from"node:fs/promises";function st(e,t){return k(e,t)?t:`${e}:${t}`}function k(e,t){return t.startsWith(`${e}:`)}function ct(e,t){return!e.partitioned||k(e.tenant,t)}var lt=class{active=new Map;waiters=new Map;async run(e,t){this.active.set(e,(this.active.get(e)??0)+1);try{return await t()}finally{let t=(this.active.get(e)??1)-1;if(t>0)this.active.set(e,t);else{this.active.delete(e);let t=this.waiters.get(e);this.waiters.delete(e);for(let e of t??[])e()}}}async wait(e,t){if(t?.throwIfAborted(),!this.active.has(e))return;let n=this.waiters.get(e)??new Set,r=()=>{},i=()=>{};try{await new Promise((a,o)=>{r=a,i=()=>o(t?.reason),n.add(r),this.waiters.set(e,n),t?.addEventListener(`abort`,i,{once:!0})})}finally{t?.removeEventListener(`abort`,i),n.delete(r),n.size===0&&this.waiters.get(e)===n&&this.waiters.delete(e)}}},ut=class{entriesByLeaseId=new Map;retain(e,t){let n={wanted:t,released:!1},r=this.entriesByLeaseId.get(e)??new Set;return r.add(n),this.entriesByLeaseId.set(e,r),{leaseId:e,release:()=>this.releasePass(e,r,n)}}forget(e){let t=this.entriesByLeaseId.get(e);if(t){for(let e of t)e.released=!0;this.entriesByLeaseId.delete(e)}}isDeferred(e){let t=this.entriesByLeaseId.get(e);if(!t)return!1;for(let e of t)e.wanted()||t.delete(e);return t.size>0||(this.entriesByLeaseId.delete(e),!1)}releasePass(e,t,n){return!n.released&&(n.released=!0,t.delete(n),t.size===0&&this.entriesByLeaseId.delete(e),n.wanted())}},dt=class{holdsByDevice=new Map;mutations=new lt;inFlightWork=new ut;leases=new Map;runBindings=new Map;deviceBindings=new Map;maxActiveSimulatorLeases;resolveLeaseTtlMs;now;onLeaseExpired;providerSessionOwnership;constructor(e={}){this.maxActiveSimulatorLeases=Number.isInteger(e.maxActiveSimulatorLeases)?Math.max(0,Number(e.maxActiveSimulatorLeases)):0,this.resolveLeaseTtlMs=ve(e),this.now=e.now??(()=>Date.now()),this.onLeaseExpired=e.onLeaseExpired,this.providerSessionOwnership=new Oe({now:this.now,retentionMs:e.providerSessionRetentionMs})}allocateLease(e){let t=ye(e);this.cleanupExpiredLeases();let n=this.resolveLeaseTtlMs(t.ttlMs);this.assertHumanControlAdmission(t);let r=this.refreshExistingRunBinding(t,n);if(r)return r;this.assertDeviceAvailable(t),this.enforceCapacity(t.backend);let i=pe(t,n,this.now());return this.leases.set(i.leaseId,i),this.bindLease(i),{...i}}refreshExistingRunBinding(e,t){let n=x(e),r=this.runBindings.get(n);if(!r)return;let i=this.leases.get(r);if(!i){this.runBindings.delete(n);return}if(i.clientId===e.clientId)return this.refreshLease(i,t);if(i.deviceKey)throw Se(i);return S(i,e),this.refreshLease(i,t)}heartbeatLease(e){let t=de(e.leaseId);this.cleanupExpiredLeases();let n=this.getActiveLease(t);be(n,e),S(n,e);let r=e.ttlMs===void 0?me(n):this.resolveLeaseTtlMs(e.ttlMs);return this.refreshLease(n,r)}retainLeaseWork(e,t){let n=this.inFlightWork.retain(e.leaseId,t);return{leaseId:n.leaseId,release:()=>{let t=n.release();return t&&this.refreshProtectedLease(e.leaseId,this.now()),t}}}releaseLease(e){let t=this.getLease(e);return t?(this.leases.delete(t.leaseId),this.unbindLease(t),this.inFlightWork.forget(t.leaseId),{released:!0,lease:t}):{released:!1}}getLease(e){let t=de(e.leaseId);this.cleanupExpiredLeases();let n=this.leases.get(t);if(n)return be(n,e),S(n,e),{...n}}assertLeaseAdmission(e){let t=ge(e);this.cleanupExpiredLeases(),S(this.getActiveLease(t.leaseId),t)}listActiveLeases(){return this.cleanupExpiredLeases(),Array.from(this.leases.values()).map(e=>({...e}))}recordProviderSession(e,t){this.cleanupExpiredLeases();let n=e.expiresAt<=this.now()?e.expiresAt:void 0;this.providerSessionOwnership.record(e,t),this.leases.has(e.leaseId)||this.providerSessionOwnership.markLeaseReleased(e,n)}resolveProviderSession(e){return this.cleanupExpiredLeases(),this.providerSessionOwnership.resolve(e)}listHumanControlHolds(e){this.cleanupExpiredLeases();let t=e.kind===`lease`?y(this.requireHumanControlLease(e.leaseId)):void 0;return[...this.holdsByDevice.entries()].filter(([e])=>t===void 0||t===e).flatMap(([,e])=>[...e.values()].map(({hold:e})=>b(e))).sort((e,t)=>e.id.localeCompare(t.id))}async putHumanControlHold(e,n,r,i){i?.throwIfAborted();let a=_e(n),o=fe(r);this.cleanupExpiredLeases();let s=this.resolveHumanControlScope(e,o),c=y(s),l=this.findHumanControlHold(a);if(l&&(this.assertHoldAuthority(e,l),y(l.hold.scope)!==c))throw new t(`INVALID_ARGS`,`Release a hold before changing its device scope.`);let u=this.now(),d={...e.kind===`lease`?{ownerLeaseId:e.leaseId}:{},hold:{id:a,scope:s,state:`activating`,...o.reason?{reason:o.reason}:{},createdAt:l?.hold.createdAt??u,updatedAt:u}},f=this.holdsByDevice.get(c)??new Map;return this.holdsByDevice.set(c,f),f.set(a,d),await this.activateHumanControlHold(c,d,o.ttlMs,i)}async activateHumanControlHold(e,n,r,i){let a=this.holdsByDevice.get(e),{id:o}=n.hold;try{if(await this.mutations.wait(e,i),i?.throwIfAborted(),a.get(o)!==n)throw new t(`COMMAND_FAILED`,`Human-control hold changed before activation completed.`,{holdId:o});let s=this.now();return n.hold={...n.hold,state:`active`,updatedAt:s,...r===void 0?{}:{expiresAt:s+r}},this.refreshHeldLease(e,s),b(n.hold)}catch(t){throw a.get(o)===n&&this.deleteHumanControlHold(e,o),t}}removeHumanControlHold(e,t){let n=_e(t);this.cleanupExpiredLeases();let r=this.findHumanControlHold(n);if(!r)return;this.assertHoldAuthority(e,r);let i=y(r.hold.scope);return this.deleteHumanControlHold(i,n),b(r.hold)}deleteHumanControlHold(e,t){let n=this.holdsByDevice.get(e);n.delete(t),n.size===0&&(this.holdsByDevice.delete(e),this.refreshHeldLease(e,this.now()))}assertHumanControlAdmission(e){this.expireHumanControlHolds();let t=y(e),n=t===void 0?void 0:this.holdsByDevice.get(t)?.values().next().value;if(n)throw xe(n.hold)}async runDeviceMutation(e,t){if(!e)return await t();this.cleanupExpiredLeases();let n=this.getActiveLease(e.leaseId);this.assertHumanControlAdmission(n);let r=y(n);return r===void 0?await t():await this.mutations.run(r,t)}requireHumanControlLease(e){let n=this.getActiveLease(e);if(!n.deviceKey)throw new t(`UNSUPPORTED_OPERATION`,`Human control requires a device-scoped remote lease.`);return{...n,deviceKey:n.deviceKey}}resolveHumanControlScope(e,n){if(e.kind===`host`){if(!n.scope)throw new t(`INVALID_ARGS`,`Host human control requires a lease device scope.`);return n.scope}if(n.scope)throw new t(`INVALID_ARGS`,`Lease-owner human control uses the admitted lease device; do not supply scope.`);let r=this.requireHumanControlLease(e.leaseId);return{backend:r.backend,leaseProvider:r.leaseProvider,deviceKey:r.deviceKey}}assertHoldAuthority(e,n){if(e.kind===`host`)return;let r=this.requireHumanControlLease(e.leaseId);if(n.ownerLeaseId!==r.leaseId||y(r)!==y(n.hold.scope))throw new t(`UNAUTHORIZED`,`Human-control hold does not belong to the admitted lease.`,{reason:`LEASE_SCOPE_MISMATCH`})}findHumanControlHold(e){for(let t of this.holdsByDevice.values()){let n=t.get(e);if(n)return n}}hasHumanControl(e){let t=y(e);return t!==void 0&&this.holdsByDevice.has(t)}isLeaseProtected(e,t){return e.expiresAt>t||this.hasHumanControl(e)||this.inFlightWork.isDeferred(e.leaseId)}expireHumanControlHolds(){let e=this.now();for(let[t,n]of this.holdsByDevice){let r=0;for(let[t,{hold:i}]of n)i.expiresAt===void 0||i.expiresAt>e||(r=Math.max(r,i.expiresAt),n.delete(t));n.size===0&&(this.holdsByDevice.delete(t),this.refreshHeldLease(t,r))}}refreshHeldLease(e,t){this.refreshProtectedLease(this.deviceBindings.get(e),t)}refreshProtectedLease(e,t){let n=e?this.leases.get(e):void 0;n&&this.refreshLease(n,me(n),Math.max(t,n.heartbeatAt))}consumeExpiredLeases(){this.expireHumanControlHolds();let e=this.now(),t=[];for(let n of this.leases.values()){if(this.isLeaseProtected(n,e))continue;this.leases.delete(n.leaseId),this.unbindLease(n,n.expiresAt);let r={...n};t.push(r),this.onLeaseExpired?.(r)}return t}consumeExpiredLease(e){this.expireHumanControlHolds();let t=he(e);if(!t)return;let n=this.leases.get(t);if(!n||this.isLeaseProtected(n,this.now()))return;this.leases.delete(n.leaseId),this.unbindLease(n,n.expiresAt);let r={...n};return this.onLeaseExpired?.(r),r}cleanupExpiredLeases(){this.consumeExpiredLeases()}enforceCapacity(e){if(e!==`ios-simulator`||this.maxActiveSimulatorLeases<=0)return;let n=Array.from(this.leases.values()).filter(e=>e.backend===`ios-simulator`).length;if(!(n<this.maxActiveSimulatorLeases))throw new t(`DEVICE_IN_USE`,`No simulator lease capacity available`,{reason:`LEASE_CAPACITY_EXCEEDED`,activeLeases:n,maxActiveLeases:this.maxActiveSimulatorLeases,backend:e,hint:`Retry after releasing another simulator lease.`})}getActiveLease(e){let n=this.leases.get(e);if(n)return n;throw new t(`UNAUTHORIZED`,`Lease is not active`,{reason:`LEASE_NOT_FOUND`})}refreshLease(e,t,n=this.now()){let r={...e,heartbeatAt:n,expiresAt:n+t};return this.leases.set(r.leaseId,r),this.bindLease(r),{...r}}bindLease(e){this.runBindings.set(x(e),e.leaseId);let t=y(e);t&&this.deviceBindings.set(t,e.leaseId)}unbindLease(e,t=this.now()){this.runBindings.delete(x(e));let n=y(e);n&&this.deviceBindings.delete(n),this.providerSessionOwnership.markLeaseReleased(e,t)}assertDeviceAvailable(e){let t=y({backend:e.backend,leaseProvider:e.leaseProvider,deviceKey:e.deviceKey});if(!t)return;let n=this.deviceBindings.get(t);if(!n)return;let r=this.leases.get(n);if(!r){this.deviceBindings.delete(t);return}throw Se(r)}};function ft(e){let n=we(e.meta?.sessionIsolation??e.flags?.sessionIsolation),r=e.meta?.tenantId??e.flags?.tenant,i=Ce(r);if(r&&!i)throw new t(`INVALID_ARGS`,`Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.`);if(n!==`tenant`)return e;if(!i)throw new t(`INVALID_ARGS`,`session isolation mode tenant requires --tenant (or meta.tenantId).`);let a=e.session||`default`;return k(i,a)?{...e,meta:{...e.meta,tenantId:i,sessionIsolation:n}}:{...e,session:st(i,a),meta:{...e.meta,tenantId:i,sessionIsolation:n}}}function pt(e,n,r,i={}){if(Ge(e.command))return;let a=He(e);gt(e,a);let o=r?.lease;if(r===void 0&&!a.leaseId&&mt(e,i.providerAppCatalog))return;if(e.command===`human_control`&&!o&&!a.leaseId)throw new t(`UNSUPPORTED_OPERATION`,`Takeover requires an active remote device lease. Local takeover is not supported.`);if(e.command!==`human_control`&&!o&&e.meta?.sessionIsolation!==`tenant`&&(!a.leaseId||!a.tenantId&&!a.runId))return;_t(a,o);let s=Ue(e,r);n.assertLeaseAdmission(m(s));let c=n.heartbeatLease(m(s));return qe(e)&&n.assertHumanControlAdmission(c),c}function mt(e,t){let n=Ke(e);return n?.kind===`unconditional`||n?.kind===`provider-app-catalog`&&t?.supports(n.provider)===!0}function ht(e){Ge(e.command)||gt(e,He(e))}function gt(e,n){if(e.command!==`open`)return;let r=p(n);if(r.length!==0)throw new t(`INVALID_ARGS`,`Proxy open requires leaseId, tenantId, runId, clientId, and deviceKey lease metadata.`,{missing:r})}function _t(e,t){t&&(A(`leaseId`,e.leaseId,t.leaseId),A(`tenantId`,e.tenantId,t.tenantId),A(`runId`,e.runId,t.runId),A(`leaseProvider`,e.leaseProvider,t.leaseProvider),A(`clientId`,e.clientId,t.clientId),A(`deviceKey`,e.deviceKey,t.deviceKey))}function A(e,n,r){if(!(!n||!r||n===r))throw new t(`UNAUTHORIZED`,`Lease does not match session owner (${e})`,{reason:`LEASE_SESSION_MISMATCH`,field:e})}async function vt(e,t){if(!t.leaseProvider||!e)return!1;try{return await e(t),_({level:`info`,phase:`provider_lease_expired_released`,data:{leaseId:t.leaseId,provider:t.leaseProvider}}),!0}catch(e){return _({level:`error`,phase:`provider_lease_expiry_release_failed`,data:{leaseId:t.leaseId,provider:t.leaseProvider,error:e instanceof Error?e.message:String(e)}}),!1}}function yt(e){ht(e)}async function bt(e){let t=e.sessionStore.get(e.sessionName),n=t?.lease;return!t||!n||!e.leaseRegistry.consumeExpiredLease(n.leaseId)?!1:(_({level:`info`,phase:`leased_session_expired`,data:{reason:`LEASE_EXPIRED`,leaseId:n.leaseId,session:t.name,deviceKey:n.deviceKey}}),await e.teardownSession(t,t.name).catch(e=>{_({level:`debug`,phase:`leased_session_expiry_cleanup_failed`,data:{reason:`LEASE_EXPIRED`,leaseId:n.leaseId,session:t.name,error:e instanceof Error?e.message:String(e)}})}),await Le(t.deviceClaim).catch(e=>{_({level:`warn`,phase:`leased_session_expiry_device_claim_clear_failed`,data:{session:t.name,deviceKey:t.deviceClaim?.deviceKey,error:e instanceof Error?e.message:String(e)}})}),e.sessionStore.delete(t.name),!0)}function xt(e){let{sessionName:t,sessionStore:n,leaseRegistry:r}=e,i=n.get(t),a=pt(e.req,r,i,{providerAppCatalog:e.providerAppCatalog});if(!a)return e.req;let o={...e.req,internal:{...e.req.internal,admittedLease:a}};return i?.lease&&n.set(t,{...i,lease:{...i.lease,leaseBackend:a.backend,expiresAt:a.expiresAt}}),o}function St(e){return We(e.req,e.req.internal?.admittedLease)??e.existingLease}async function Ct(e){let t=e.session.lease;if(!t)return;let n=f({leaseId:t.leaseId,tenantId:t.tenantId,runId:t.runId,leaseBackend:t.leaseBackend,leaseProvider:t.leaseProvider,deviceKey:t.deviceKey,clientId:t.clientId}),r=e.leaseRegistry.getLease(n),i=r?await e.leaseLifecycleProvider?.release?.(r):void 0,a=De(i);r&&a&&e.leaseRegistry.recordProviderSession(r,a);let o=e.leaseRegistry.releaseLease(n);return _({level:`info`,phase:`session_lease_released`,data:{session:e.session.name,leaseId:t.leaseId,released:o.released}}),i}const wt=[`platform`,`target`],Tt=[`iosSimulatorDeviceSet`,`androidDeviceAllowlist`];function Et(e){return u({deviceName:e?.device,udid:e?.udid,serial:e?.serial})}function Dt(e){return Et(e)||At(e,wt)}function Ot(e){return Dt(e)||At(e,Tt)}function kt(e){return typeof e==`string`&&e.trim().length>0}function At(e,t){return e?t.some(t=>kt(e[t])):!1}function jt(e){return{appleSimulatorAppTarget:Mt(e)}}function Mt(e){return e&&!a(e)?e:void 0}function Nt(){return Je({displayName:`audio probe`})}function Pt(){return Je({displayName:`perf capture`})}function Ft(e){let t={version:2,platform:e.platform??null,target:e.target??null,runtimeHints:e.runtimeHints??null,initialStaticEnv:e.initialStaticEnv,steps:e.steps};return at(`sha256`).update(re(t),`utf8`).digest(`hex`)}function It(e,t,n){return new Gt(Rt(Lt(t.resolve(e))),n).parse()}function Lt(e){let t=e.trim();return t.startsWith("${")&&t.endsWith(`}`)?t.slice(2,-1).trim():t}function Rt(e){let n=[],r=0;for(;r<e.length;){let i=e.slice(r),a=/^\s+/.exec(i)?.[0].length??0;if(a>0){r+=a;continue}let o=zt(i);if(!o)throw new t(`INVALID_ARGS`,`Unsupported runFlow.when.true expression near "${i.slice(0,24)}".`);n.push(o.value),r+=o.length}return n}function zt(e){return Bt(e)??Vt(e)??Ht(e)??Ut(e)??Wt(e)}function Bt(e){return e.startsWith(`maestro.platform`)?{value:{type:`platform`},length:16}:null}function Vt(e){let t=/^(==|!=|&&|\|\|)/.exec(e)?.[1];return t?{value:{type:`operator`,value:t},length:t.length}:null}function Ht(e){let t=e[0];return t===`(`||t===`)`?{value:{type:`paren`,value:t},length:1}:null}function Ut(e){let t=/^(['"])(.*?)\1/.exec(e);return t?{value:{type:`string`,value:t[2]??``},length:t[0].length}:null}function Wt(e){let t=/^(true|false)\b/.exec(e)?.[1];return t?{value:{type:`boolean`,value:t===`true`},length:t.length}:null}var Gt=class{index=0;tokens;platform;constructor(e,t){this.tokens=e,this.platform=t}parse(){let e=this.parseOr();if(this.peek())throw new t(`INVALID_ARGS`,`Unsupported trailing runFlow.when.true expression.`);return e}parseOr(){let e=this.parseAnd();for(;this.consumeOperator(`||`);)e=this.parseAnd()||e;return e}parseAnd(){let e=this.parsePrimary();for(;this.consumeOperator(`&&`);)e=this.parsePrimary()&&e;return e}parsePrimary(){let e=this.peek();if(!e)throw new t(`INVALID_ARGS`,`Incomplete runFlow.when.true expression.`);if(e.type===`boolean`)return this.index+=1,e.value;if(e.type===`paren`&&e.value===`(`){this.index+=1;let e=this.parseOr();if(!this.consumeParen(`)`))throw new t(`INVALID_ARGS`,`Unclosed runFlow.when.true parenthesis.`);return e}return this.parsePlatformComparison()}parsePlatformComparison(){this.consumePlatformToken();let e=this.consumeComparisonOperator(),t=this.consumeStringLiteral(),n=this.platform===t.toLowerCase();return e.value===`==`?n:!n}consumePlatformToken(){if(this.peek()?.type!==`platform`)throw new t(`INVALID_ARGS`,`runFlow.when.true supports maestro.platform comparisons.`);this.index+=1}consumeComparisonOperator(){let e=this.peek();if(e?.type!==`operator`||e.value!==`==`&&e.value!==`!=`)throw new t(`INVALID_ARGS`,`runFlow.when.true comparison requires == or !=.`);return this.index+=1,e}consumeStringLiteral(){let e=this.peek();if(e?.type!==`string`)throw new t(`INVALID_ARGS`,`runFlow.when.true comparison requires a string literal.`);return this.index+=1,e.value}consumeOperator(e){let t=this.peek();return t?.type!==`operator`||t.value!==e?!1:(this.index+=1,!0)}consumeParen(e){let t=this.peek();return t?.type!==`paren`||t.value!==e?!1:(this.index+=1,!0)}peek(){return this.tokens[this.index]}};function Kt(e){switch(e.kind){case`runFlow`:return!(`include`in e);case`repeat`:case`retry`:return!(`commands`in e);default:return!1}}function qt(e,t){return{...N(e,t),source:e.source}}function j(e,n,r){if(e===void 0)return;let i=r??Ye[n]??{},a=$e(i),o;if(typeof e==`number`)o=e;else{let r=e.trim();if(r===``)throw new t(`INVALID_ARGS`,`Maestro ${n} must be ${a}.`);o=Number(r)}if(!Number.isFinite(o)||Math.abs(o)>2**53-1||i.integer&&!Number.isSafeInteger(o)||i.nonNegative&&o<0||i.positive&&o<=0)throw new t(`INVALID_ARGS`,`Maestro ${n} must be ${a}.`);return o}function Jt(e,t,n,r){return j(e===void 0?t:n.resolve(String(e)),r)}function M(t){if(t?.aborted)throw e()}async function Yt(e,n){if(e.include.kind===`commands`)return{kind:`program`,source:e.source,config:{},commands:e.include.commands};if(!n.loadProgram)throw new t(`INVALID_ARGS`,`Maestro file runFlow requires a program loader.`);return M(n.signal),n.signal?await n.loadProgram(e.include.path,e.source.path,n.signal):await n.loadProgram(e.include.path,e.source.path)}function Xt(e,t){if(e.include.kind===`file`)return D.resolve(t?D.dirname(t):process.cwd(),e.include.path)}function Zt(e){return e===void 0?void 0:D.resolve(e)}function Qt(e,n){let r=Xt(e,e.source.path);if(r&&n.has(r))throw new t(`INVALID_ARGS`,`Maestro runFlow cycle detected at ${r}.`);return r}function $t(e,n,r,i){let a=e.include.kind===`file`?Zt(n.source.path):void 0,o=new Set([r,a].filter(e=>e!==void 0)),s=[...o].find(e=>i.has(e));if(s)throw new t(`INVALID_ARGS`,`Maestro runFlow cycle detected at ${s}.`);return o.forEach(e=>i.add(e)),o}function en(e,t,n){return e.platform&&e.platform!==n.platform?!1:e.true===void 0?!0:typeof e.true==`boolean`?e.true:It(e.true,t,n.platform)}function tn(e){return[...e.visible?[{kind:`visible`,selector:e.visible}]:[],...e.notVisible?[{kind:`notVisible`,selector:e.notVisible}]:[]]}function N(e,t){return typeof e==`string`?t.resolve(e):Array.isArray(e)?e.map(e=>N(e,t)):e&&typeof e==`object`?Object.fromEntries(Object.entries(e).map(([e,n])=>[e,N(n,t)])):e}async function nn(e,t){M(t.signal);let n=Zt(e.source.path),r={options:t,context:Xe(t.defaults,t.env),activeIncludePaths:new Set(n===void 0?[]:[n]),staticallyExecutedControls:0,staticallySkippedControls:0};return{steps:await rn(e,[],void 0,e.source.path,r),staticallyExecutedControls:r.staticallyExecutedControls,staticallySkippedControls:r.staticallySkippedControls}}async function rn(e,t,n,r,i){M(i.options.signal);let a=mn(t,e.config.env),o=e.config.appId??n,s=i.context.enter(e.config.env);try{let t=[...e.config.onFlowStart??[],...e.commands,...e.config.onFlowComplete??[]],n=[];for(let s of t)n.push(...await on(s,a,o,e.source.path??r,i));return n}finally{s()}}async function an(e,t,n,r,i){let a=[];for(let o of e)a.push(...await on(o,t,n,r,i));return a}async function on(e,t,n,r,i){M(i.options.signal);let a=hn(e,r);switch(a.kind){case`runFlow`:{let e=cn(a,i);if(e===`omit`)return i.staticallySkippedControls+=1,[];let o=await sn(a,t,n,r,i);return e===`flatten`?(i.staticallyExecutedControls+=1,o):[P(a,t,n,o)]}case`repeat`:return[P(a,t,n,await an(a.commands,t,n,r,i))];case`retry`:return[P(a,t,n,await an(a.commands,t,n,r,i))];default:return[fn(a,t,n)]}}async function sn(e,t,n,r,i){let a=un(e,i.context),o=Qt(a,i.activeIncludePaths),s=await Yt(a,i.options);M(i.options.signal);let c=$t(a,s,o,i.activeIncludePaths),l=mn(t,e.env),u=i.context.enter(e.env);try{return await rn(s,l,n,s.source.path??e.source.path??r,i)}finally{u(),c.forEach(e=>i.activeIncludePaths.delete(e))}}function cn(e,t){let n=e.when;return n?n.platform!==void 0&&n.platform!==t.options.platform?`omit`:ln(n.true,t)||(n.visible||n.notVisible?`opaque`:`flatten`):`flatten`}function ln(e,t){if(e===!1)return`omit`;if(typeof e==`string`)return dn(t.context.resolveDeferred(e))?`opaque`:It(e,t.context,t.options.platform)?void 0:`omit`}function un(e,t){return e.include.kind===`file`?{...e,include:{...e.include,path:t.resolve(e.include.path)}}:e}function dn(e){return/\$\{[A-Za-z_][A-Za-z0-9_.]*\}/.test(e)}function fn(e,t,n){return T({kind:`command`,command:e,source:e.source,scopes:t,appId:n})}function P(e,t,n,r){return T({kind:`opaque`,command:pn(e),source:e.source,scopes:t,body:r,appId:n})}function pn(e){switch(e.kind){case`runFlow`:return T({kind:e.kind,source:e.source,when:e.when,label:e.label,...e.include.kind===`file`?{includePath:e.include.path}:{}});case`repeat`:return{kind:e.kind,source:e.source,times:e.times};case`retry`:return T({kind:e.kind,source:e.source,maxRetries:e.maxRetries})}}function mn(e,t){return t===void 0?e:[...e,t]}function hn(e,t){return e.source.path||!t?e:{...e,source:{...e.source,path:t}}}async function gn(e,t={}){let{steps:n,staticallyExecutedControls:r,staticallySkippedControls:i}=await nn(e,t),a=_n(t.runtimeHints),o=T({kind:`maestroReplayPlan`,platform:t.platform,target:t.target,runtimeHints:a,initialStaticEnv:structuredClone({...t.defaults??{},...e.config.env??{},...t.env??{}}),steps:structuredClone(n),total:n.length,compatibility:{staticallyExecutedControls:r,staticallySkippedControls:i}}),s=Ft(o);return vn({...o,digest:s})}function _n(e){if(!e)return;let t=Object.entries(e).filter(e=>e[1]!==void 0);return t.length===0?void 0:Object.fromEntries(t)}function vn(e){if(!e||typeof e!=`object`||Object.isFrozen(e))return e;for(let t of Object.values(e))vn(t);return Object.freeze(e)}function yn(e,t={}){let{from:n,planDigest:r}=t;if(n===void 0&&r===void 0)return{allowed:!0,startIndex:0};if(n===void 0||r===void 0)return{allowed:!1,reason:`replay --from requires --plan-digest (and --plan-digest requires --from).`};if(!Number.isInteger(n)||n<1||n>e.total)return{allowed:!1,reason:`replay --from ${n} is out of range for a ${e.total}-step plan.`};if(r!==e.digest)return{allowed:!1,reason:`replay --plan-digest does not match the current plan digest.`};if(n===1)return{allowed:!0,startIndex:0};for(let t=0;t<n-1;t+=1){let n=e.steps[t];if(n.kind===`opaque`)return{allowed:!1,reason:`step ${t+1} is opaque runtime control flow (${n.command.kind}) and cannot be skipped safely.`};if(n.command.kind===`runScript`||n.command.kind===`evalScript`)return{allowed:!1,reason:`step ${t+1} (${n.command.kind}) can produce outputEnv values and cannot be skipped safely.`}}let i=e.steps[n-1];return i.kind===`opaque`?{allowed:!1,reason:`step ${n} is opaque runtime control flow (${i.command.kind}) and cannot be resumed into.`}:{allowed:!0,startIndex:n-1}}function bn(e,n={}){let r=yn(e,n);if(!r.allowed)throw new t(`INVALID_ARGS`,r.reason);return r.startIndex}function xn(e,n){if(!Number.isInteger(n)||n<0||n>e.total)throw new t(`INVALID_ARGS`,`Maestro replay startIndex ${n} is out of range for a ${e.total}-step plan.`);return n}const Sn=`maestro-test-failure`;function F(e,n={}){return new t(`COMMAND_FAILED`,e,{...n,reason:Sn})}function Cn(e){return e instanceof t&&e.code===`COMMAND_FAILED`&&e.details?.reason===Sn}const wn=new Set([``,`false`,`0`,`null`,`undefined`]);function Tn(e){return typeof e==`boolean`?e:typeof e==`number`?e!==0&&!Number.isNaN(e):!wn.has(e)}async function En(e,t){M(t.options.signal);try{return await zn(e,t.context,async()=>await Dn(e,t))}catch(t){throw R(t,e)}}async function Dn(e,t){if(e.kind===`command`)return await On(e.command,e.appId,t);await Pn(e,t)}async function On(e,t,n){if(e.kind===`evalScript`)return await jn(e,n);let r=qt(e,n.context);try{return await Mn(r,t,n)}catch(e){if(M(n.options.signal),An(r)&&Cn(e)){n.warnings.push(kn(r,e)),n.skipped+=1;return}throw Bn(e,r)}}function kn(e,n){let r=`${e.source.path?`${e.source.path}:`:``}line ${e.source.line}`,i=n instanceof t?n.message:String(n);return`Optional Maestro ${e.kind} skipped at ${r}: ${i}`}function An(e){return`optional`in e&&e.optional===!0}async function jn(e,n){let{evaluateMaestroEvalScript:r}=await import(`./engine-eval-script.js`);if(n.options.trustedScripts===!1)throw new t(`UNAUTHORIZED`,`Maestro evalScript is not permitted for flows received over the remote daemon surface: node:vm is not a security sandbox, so an untrusted expression can escape to the host.`);let i=await r(e.script,n.context.values);n.context.replaceOutput(i),n.executed+=1}async function Mn(e,t,n){switch(e.kind){case`assertVisible`:await L({kind:`visible`,selector:e.target},n.timing.assertVisibleTimeoutMs,n),n.executed+=1;return;case`assertNotVisible`:await L({kind:`notVisible`,selector:e.target},n.timing.assertNotVisibleTimeoutMs,n),n.executed+=1;return;case`assertTrue`:if(!Tn(e.condition))throw F(`Maestro assertTrue condition was falsy: ${JSON.stringify(e.condition)}`);n.executed+=1;return;case`extendedWaitUntil`:await L(Rn(e),j(e.timeout,`extendedWaitUntil.timeout`)??n.timing.extendedWaitUntilTimeoutMs,n),n.executed+=1;return;default:return await Nn(e,t,n)}}async function Nn(e,t,n){let r=T({command:e,env:n.context.values,appId:t===void 0?void 0:n.context.resolve(t),generation:n.context.generation,invalidateObservation:n.context.invalidateObservation,cachedObservation:n.context.observation,signal:n.options.signal}),i=await n.port.execute(r);return M(n.options.signal),i.observation&&n.context.recordObservation(i.observation),i.outputEnv&&n.context.merge(i.outputEnv),i.artifactPaths?.forEach(e=>n.artifacts.add(e)),n.executed+=1,i}async function Pn(e,t){let n=qt(e.command,t.context);switch(n.kind){case`runFlow`:if(n.when&&!await In(n.when,t)){t.skipped+=1;return}t.executed+=1,await I(e.body,t);return;case`repeat`:{let r=Jt(n.times,0,t.context,`repeat.times`);t.executed+=1;for(let n=0;n<r;n+=1)M(t.options.signal),await I(e.body,t);return}case`retry`:{let r=Math.min(Jt(n.maxRetries,1,t.context,`retry.maxRetries`),tt.control.retryMaxRetries);t.executed+=1,await Fn(e.body,r,t);return}}}async function I(e,t){for(let n of e)await En(n,t)}async function Fn(e,n,r){let i;for(let t=0;t<=n;t+=1){M(r.options.signal);try{await I(e,r);return}catch(t){if(M(r.options.signal),!Cn(Hn(t)))throw t;i=R(t,e[0])}}throw i||new t(`COMMAND_FAILED`,`Maestro retry commands failed.`)}async function In(e,t){if(!en(e,t.context,t.options))return!1;for(let n of tn(e))if(M(t.options.signal),!(await Ln(n,t.timing.runFlowConditionTimeoutMs,t)).matched)return!1;return!0}async function L(e,t,n){if(!(await Ln(e,t,n)).matched)throw F(`Maestro ${e.kind} condition did not match.`)}async function Ln(e,t,n){let r={condition:e,timeoutMs:t,generation:n.context.generation,env:n.context.values,...n.context.observation?{cachedObservation:n.context.observation}:{},...n.options.signal?{signal:n.options.signal}:{}},i=await n.port.observe(r);return M(n.options.signal),n.context.recordObservation(i),i}function Rn(e){if(e.visible)return{kind:`visible`,selector:e.visible};if(e.notVisible)return{kind:`notVisible`,selector:e.notVisible};throw new t(`INVALID_ARGS`,`Maestro extendedWaitUntil requires one condition.`)}async function zn(e,t,n){let r=e.scopes.map(e=>t.enter({...e}));try{return await n()}finally{for(let e=r.length-1;e>=0;--e)r[e]()}}function R(e,t){if(Vn(e))return e;let n=t?.source??{line:1};return{kind:`maestroPlanStepFailure`,error:Un(e,t?.command),source:n,...t?{command:t.command}:{}}}function Bn(e,t){return{kind:`maestroPlanStepFailure`,error:Un(e,t),source:t.source,command:t}}function Vn(e){return!!(e&&typeof e==`object`&&e.kind===`maestroPlanStepFailure`)}function Hn(e){return Vn(e)?e.error:e}function Un(e,n){if(!(e instanceof t)||!n||/\bline \d+\b/.test(e.message))return e;let r=n.source.path?`${n.source.path}:`:``;return new t(e.code,`${e.message} (${r}line ${n.source.line})`,e.details)}async function Wn(e,n,r={}){M(r.signal);let i=r.startIndex??0;if(!Number.isInteger(i)||i<0||i>e.total)throw new t(`INVALID_ARGS`,`Maestro replay startIndex ${i} is out of range for a ${e.total}-step plan.`);let a={plan:e,port:n,options:r,context:Xe(r.defaults,r.env?{...r.env}:{}),timing:nt,artifacts:new Set,warnings:[],executed:e.compatibility.staticallyExecutedControls,skipped:e.compatibility.staticallySkippedControls};for(let t=i;t<e.steps.length;t+=1)try{await Gn(e.steps[t],t,a)}catch(e){throw Hn(e)}return{executed:a.executed,skipped:a.skipped,generation:a.context.generation,artifactPaths:[...a.artifacts],...a.warnings.length>0?{warnings:a.warnings}:{}}}async function Gn(e,t,n){M(n.options.signal);let r=n.options.now??Date.now,i=r(),a=n.port.readMetrics?.(),o=n.context.generation,s={command:e.command,source:e.source,generation:o,stepIndex:t+1,stepTotal:n.plan.total};z(()=>n.options.observer?.commandStarted?.(s));try{let t=await En(e,n);M(n.options.signal),z(()=>n.options.observer?.commandCompleted?.({...s,durationMs:r()-i,...Kn(a,n.port.readMetrics?.()),...t?.data?{data:t.data}:{}}))}catch(t){let o=R(t,e);throw z(()=>n.options.observer?.commandFailed?.({...s,...o.command?{command:o.command}:{},source:o.source,durationMs:r()-i,...Kn(a,n.port.readMetrics?.()),error:o.error,artifactPaths:[...n.artifacts],warnings:[...n.warnings]})),o}}function Kn(e,t){return!e||!t?{}:{runtimeMetrics:{hierarchyCaptures:t.hierarchyCaptures-e.hierarchyCaptures,screenshotCaptures:t.screenshotCaptures-e.screenshotCaptures,tapRetries:t.tapRetries-e.tapRetries,settleLatches:t.settleLatches-e.settleLatches,settleTimeouts:t.settleTimeouts-e.settleTimeouts}}}function z(e){try{e?.()}catch{}}async function qn(e,t,n={}){let r=Jn(e,n);return await Wn(e,t,{...n,startIndex:r})}function Jn(e,t){return t.from!==void 0||t.planDigest!==void 0?bn(e,{from:t.from,planDigest:t.planDigest}):xn(e,t.startIndex??0)}function Yn(e){return Kt(e)?{command:e.kind,...e.kind===`runFlow`?V(e.label??e.includePath):{}}:{command:e.kind,...Xn(e)}}function Xn(e){return`label`in e&&e.label?V(e.label):Zn(e)?V(ir(e.target)):Qn(e)?$n(e):e.kind===`inputText`?V(`<text>`):er(e)}function Zn(e){return e.kind===`tapOn`||e.kind===`doubleTapOn`||e.kind===`longPressOn`}function Qn(e){return e.kind===`assertVisible`||e.kind===`assertNotVisible`||e.kind===`extendedWaitUntil`||e.kind===`scrollUntilVisible`}function $n(e){switch(e.kind){case`assertVisible`:case`assertNotVisible`:return V(B(e.target));case`extendedWaitUntil`:return V(B(e.visible??e.notVisible));case`scrollUntilVisible`:return V(B(e.element))}}function er(e){return tr(e)?nr(e):e.kind===`swipe`?rr(e):e.kind===`runFlow`?V(e.label??(e.include.kind===`file`?e.include.path:``)):e.kind===`assertTrue`?V(String(e.condition)):{}}function tr(e){return e.kind===`openLink`||e.kind===`takeScreenshot`||e.kind===`runScript`||e.kind===`pressKey`}function nr(e){switch(e.kind){case`openLink`:return V(e.link);case`takeScreenshot`:return V(e.path);case`runScript`:return V(e.file);case`pressKey`:return V(e.key)}}function rr(e){return V(e.gesture.kind===`coordinates`?`${ar(e.gesture.start)} to ${ar(e.gesture.end)}`:e.gesture.direction)}function ir(e){return e.space===`target`?B(e.selector):`${e.x},${e.y}${e.space===`percent`?`%`:``}`}function B(e){return e?.id??e?.text}function ar(e){return`${e.x},${e.y}${e.space===`percent`?`%`:``}`}function V(e){return e?{value:e}:{}}const or=new Set(String.raw`^$\.*+?()[]{}|`);function sr(e,t){try{return RegExp(`^(?:${t})$`,`ims`).test(e)}catch{return e.toLocaleLowerCase()===t.toLocaleLowerCase()}}function cr(e){try{new RegExp(e)}catch{return e}let t=``;for(let n=0;n<e.length;n+=1){let r=e[n];if(r!==`\\`){if(or.has(r))return;t+=r;continue}let i=e[n+1];if(i===void 0||!or.has(i))return;t+=i,n+=1}return t}function lr(e,t,n){if(n===`android`&&e.visibleToUser===!1)return!1;if(g(e.rect))return t.isVisibleInEffectiveViewport(e);if(e.rect)return!1;if(n!==`android`&&e.hittable===!0)return!0;let r=t.findAncestor(e,e=>ae(e,n)?e:null);return r?g(r.rect)?t.isVisibleInEffectiveViewport(r):n!==`android`&&r.hittable===!0:!1}function ur(e,t,n){return!!n.findAncestor(e,e=>e.index===t.index?e:null)}function dr(e,t){let n=[t.id===void 0?void 0:pr(e.identifier,t.id),t.text===void 0?void 0:mr(e,t.text)].filter(e=>e!==void 0);return!(n.length===0&&t.enabled===void 0&&t.selected===void 0||n.some(e=>!e)||t.enabled!==void 0&&e.enabled!==!1!==t.enabled||t.selected!==void 0&&e.selected===!0!==t.selected)}function fr(e){return e.matches.filter(t=>lr(t,e.visibility,e.platform))}function pr(e,t){let n=e??``;return E(n)===E(t)||sr(n,t)}function mr(e,t){return[e.label,Ze(e),e.identifier].filter(e=>!!e).some(e=>pr(e,t))}function hr(e){return e.index!==void 0||e.childOf!==void 0||e.below!==void 0||e.above!==void 0||e.leftOf!==void 0||e.rightOf!==void 0||e.containsChild!==void 0||e.containsDescendants!==void 0}function gr(e){return e.text!==void 0||e.id!==void 0||e.enabled!==void 0||e.selected!==void 0}function _r(e,t,n){let r=[],i=0;for(let a of e)for(let e of n){let n=yr(a.rect,e.rect);n===void 0||!vr(t,a.rect,e.rect)||r.push({node:a,distance:n,order:i++})}return r.sort((e,t)=>e.distance-t.distance||e.order-t.order),r.map(({node:e})=>e)}function vr(e,t,n){switch(e){case`below`:return t.y>n.y;case`above`:return t.y<n.y;case`leftOf`:return t.x<n.x;case`rightOf`:return t.x>n.x}}function yr(e,t){if(!(!br(e)||!br(t)))return Math.fround(Math.hypot(H(e.x,e.width)-H(t.x,t.width),H(e.y,e.height)-H(t.y,t.height)))}function br(e){return!!(e&&[e.x,e.y,e.width,e.height].every(Number.isFinite))}function H(e,t){return e+Math.trunc(t/2)}function xr(e,n={},r={}){let i=ee(e.nodes,n);n.onVisibilityContextCreated?.();let a=new WeakMap,o=new WeakSet,s=new WeakMap,c=new Map,l=t=>t.parentIndex===void 0?void 0:i.nodeByIndex.get(t.parentIndex)??e.nodes[t.parentIndex],u=e=>{let t=s.get(e);if(t)return t;let n=new Set,r=new Set,i=l(e);for(;i&&!r.has(i.index);)r.add(i.index),n.add(i.index),i=l(i);return s.set(e,n),n},d=(t,r)=>{let i=c.get(t);i||(i=new WeakMap,c.set(t,i));let a=i.get(r);if(a)return a;n.onPositionComputed?.(t,r);let o=_r(e.nodes,t,m(r).indexed),s={ordered:o,candidateIndexes:new Set(o.map(e=>e.index))};return i.set(r,s),s},f=(e,t)=>d(e,t).ordered,p=(e,t)=>d(e,t).candidateIndexes,m=i=>{let s=a.get(i);if(s)return s;if(o.has(i))throw new t(`INVALID_ARGS`,`Maestro selector relations cannot contain cycles.`);o.add(i),n.onSelectorComputed?.(i);try{let t=Sr(e,i,l,u,m,p),n={matches:t,indexed:Er(t,i.index,r.orderUnindexed)};return a.set(i,n),n}finally{o.delete(i)}};return{visibility:i,resolve:m,resolvePosition:f}}function Sr(e,t,n,r,i,a){let{index:o,childOf:s,below:c,above:l,leftOf:u,rightOf:d,containsChild:f,containsDescendants:p,...m}=t,h=gr(m)?e.nodes.filter(e=>dr(e,m)):[...e.nodes];if(s){let e=new Set(i(s).indexed.map(e=>e.index));h=h.filter(t=>wr(r(t),e))}if(f){let e=new Set(i(f).indexed.map(n).filter(e=>e!==void 0).map(e=>e.index));h=h.filter(t=>e.has(t.index))}if(p){let e=p.map(e=>Cr(i(e).indexed,r));h=h.filter(t=>e.every(e=>e.has(t.index)))}for(let[e,n]of Tr(t)){let t=a(e,n);h=h.filter(e=>t.has(e.index))}return h}function Cr(e,t){let n=new Set;for(let r of e)for(let e of t(r))n.add(e);return n}function wr(e,t){for(let n of e)if(t.has(n))return!0;return!1}function Tr(e){return[[`below`,e.below],[`above`,e.above],[`leftOf`,e.leftOf],[`rightOf`,e.rightOf]].filter(e=>e[1]!==void 0)}function Er(e,t,n){if(t===void 0)return n?n(e):[...e];let r=Or(e)[kr(t)];return r?[r]:[]}function Dr(e,t){return t===void 0?e[0]:Or(e)[kr(t)]}function Or(e){return[...e].sort((e,t)=>{let n=U(e.rect?.y),r=U(t.rect?.y);return n===r?U(e.rect?.x)-U(t.rect?.x):n-r})}function U(e){return e!==void 0&&Number.isFinite(e)?e:2**53-1}function kr(e){let n=typeof e==`number`?e:Number(e.trim());if(!Number.isSafeInteger(n)||n<0)throw new t(`INVALID_ARGS`,`Maestro selector.index must be a non-negative integer.`);return n}const Ar={android:{kind:`exact`,provider:`android-helper`},ios:{kind:`divergence`,provider:`apple-xctest`,reason:`maestro-clickable-not-exposed-by-provider`}};function jr(e,t){let n=Ar[t];if(n.kind===`divergence`)return n;let r=s(e);return r?r.kind!==`exact`||r.provider!==n.provider?{kind:`divergence`,provider:n.provider,reason:`unregistered-provider-evidence`}:r:{kind:`divergence`,provider:n.provider,reason:`exact-evidence-not-retained`}}function W(e,t){return t.kind===`exact`?e.map((e,n)=>({node:e,order:n,rank:Mr(t.clickableByNodeIndex.get(e.index))})).sort((e,t)=>t.rank-e.rank||e.order-t.order).map(({node:e})=>e):[...e]}function Mr(e){return e===!0?2:+(e===!1)}function Nr(e,t,n,r={}){let i=jr(e,n),a=Fr(e,i,r),o=Pr(t,a),s=fr({visibility:a.visibility,matches:o.matches,platform:n});return{...o,visible:s,clickability:i,ranked:Ir(s,t,n,a.visibility,i)}}function Pr(e,t){return{matches:t.resolve(e).matches,parentMatched:e.childOf===void 0||t.resolve(e.childOf).indexed.length>0}}function Fr(e,t,n={}){return xr(e,n,t?{orderUnindexed:e=>W(e,t)}:{})}function Ir(e,t,n,r,i){let a=n!==`ios`||!Br(t)?e:e.filter(n=>{if(Ur(n))return!0;let i=e.filter(e=>e!==n&&Vr(n,e,t));return!i.some(e=>Ur(e)&&ur(n,e,r))&&!i.some(e=>ur(e,n,r))});return t.index===void 0&&i?W(a,i):a}function Lr(e,t){let n=t===void 0?e.find(G):Rr(e,t);return!n||!G(n)?null:{node:n,rect:n.rect}}function Rr(e,t){return Dr(e,t)}function zr(e){return G(e)?e.rect:void 0}function G(e){return g(e.rect)}function Br(e){return e.id!==void 0||e.text!==void 0}function Vr(e,t,n){if(n.id!==void 0&&K(e.identifier)!==K(t.identifier))return!1;if(n.text!==void 0){let n=Hr(e),r=new Set(Hr(t));if(!n.some(e=>r.has(e)))return!1}return!0}function Hr(e){return[e.label,e.value,e.identifier].map(K).filter(e=>e!==void 0)}function K(e){if(e)return E(e)||void 0}function Ur(e){let t=te(e.type??``);return t===`button`||t===`link`||t===`switch`||t===`searchfield`||t===`textfield`||t===`securetextfield`||t===`textview`}const Wr=Symbol(`maestroFlowProgram`),Gr=Symbol(`maestroFailureCommand`),Kr=Symbol(`maestroFailurePlan`);function qr(e,t){let n=et(e,{sourcePath:t});return{sourcePath:t,name:n.config.name,appTarget:Zr(n),[Wr]:n}}async function Jr(e,t,n){let r;try{let i=Qe(D.dirname(e.sourcePath),n.readSource),a=await gn(e[Wr],{defaults:n.defaults,env:n.env,platform:n.platform,target:n.target,runtimeHints:n.runtimeHints,loadProgram:i,signal:n.signal}),o=bn(a,{from:n.from,planDigest:n.planDigest}),s=await qn(a,t,{defaults:n.defaults,env:n.env,platform:n.platform,target:n.target,loadProgram:i,signal:n.signal,startIndex:o,trustedScripts:n.trustedScripts,observer:Xr(a,n.observer,e=>{r=e})});return{ok:!0,replayed:a.total-o,planDigest:a.digest,startIndex:o,artifactPaths:s.artifactPaths,...s.warnings?{warnings:s.warnings}:{}}}catch(e){return{ok:!1,error:r?.error??e,...r?{failure:r}:{}}}}function Yr(e,t){let n=$r(e[Gr]),r=e[Kr].platform;return!n||r!==`android`&&r!==`ios`?[]:Nr(t,n.selector,r).ranked.map(e=>({node:e,basis:ei(n.selector,e)}))}function Xr(e,t,n){return{commandStarted:e=>t?.actionStarted?.(q(e)),commandCompleted:e=>t?.actionCompleted?.({...q(e),durationMs:e.durationMs,runtimeMetrics:e.runtimeMetrics,data:e.data}),commandFailed:r=>{let i=yn(e,{from:r.stepIndex,planDigest:e.digest}),a={...q(r),durationMs:r.durationMs,error:r.error,artifactPaths:r.artifactPaths,warnings:[...r.warnings],isControl:Kt(r.command),redactions:r.command.kind===`inputText`&&r.command.text.length>0?[{name:`inputText.text`,value:r.command.text}]:[],resume:i.allowed?{allowed:!0,from:r.stepIndex,planDigest:e.digest}:{allowed:!1,from:r.stepIndex,planDigest:e.digest,reason:i.reason},[Gr]:r.command,[Kr]:e};n(a),t?.actionFailed?.(a)}}}function q(e){let t=Yn(e.command);return{action:t.command,...t.value?{value:t.value}:{},source:e.source,generation:e.generation,stepIndex:e.stepIndex,stepTotal:e.stepTotal}}function Zr(e){return[e.config.appId,...[...e.config.onFlowStart??[],...e.commands].filter(e=>e.kind===`launchApp`).map(e=>e.kind===`launchApp`?e.appId:void 0)].find(Qr)}function Qr(e){return!!(e?.trim()&&!e.includes(`$`)&&!a(e))}function $r(e){switch(e.kind){case`tapOn`:return e.target.space===`target`?{selector:e.target.selector}:void 0;case`doubleTapOn`:case`longPressOn`:return e.target.space===`target`?{selector:e.target.selector}:void 0;case`assertVisible`:case`assertNotVisible`:return{selector:e.target};case`extendedWaitUntil`:return e.visible?{selector:e.visible}:e.notVisible?{selector:e.notVisible}:void 0;case`scrollUntilVisible`:return{selector:e.element};case`swipe`:return e.gesture.kind===`target`?{selector:e.gesture.from}:void 0;default:return}}function ei(e,t){return e.id!==void 0||e.text!==void 0&&dr({...t,label:void 0,value:void 0},{text:e.text})?`id`:e.text===void 0?`other`:`label`}const ti=`This replay request carries no script sources. Replay scripts are read by the client and sent with the request; upgrade the agent-device client that issued it to a version that sends script sources.`;function ni(e,n){let r=e.files[n];if(r===void 0)throw new t(`INVALID_ARGS`,`replay script source is missing ${n}; it was not part of the script sources sent with this request.`,{path:n,entry:e.entry});return r}function ri(e){let t=oe(e);for(let n of e){if(n.command!==`open`)continue;let e=n.positionals?.[0];return oi(e)?{appTarget:e,platform:t}:{appTarget:void 0,platform:t}}return{appTarget:void 0,platform:t}}function ii(e,t){return t===`ios`?si(e)??{}:{}}function ai(e,t){let n=ri(t);return e?.platform!==void 0||!n.platform?e??{}:{...e,platform:n.platform}}function oi(e){return!!(e&&e.trim()&&!e.includes(`$`)&&!a(e))}function si(e){let t=Mt(e);return t?{appleSimulatorAppTarget:t}:void 0}function ci(e){let n=e.flags??{};if(n.waitMs===void 0)return;let[r]=se(`waitMs`);if(!r)throw new t(`INTERNAL_ERROR`,`The waitMs option has no flag declaration whose bounds the daemon can enforce.`);return o(n,`waitMs`,{min:r.min,max:r.max})}function li(e){let t=e.internal?.openDeviceWait?.waitedMs;return t===void 0?{}:{waitedMs:t}}function ui(e){return{...li(e),offersDeviceWait:e.command===`open`&&typeof e.flags?.waitMs!=`number`}}function di(e){let{req:t,budgetMs:n,sessionName:r,sessionStore:i,deviceId:a}=e;if(t.command===`open`&&n!==void 0&&!(a===void 0||i.get(r)))return pi({req:t,sessionName:r,sessionStore:i,deviceId:a,budgetMs:n})}function fi(e,t,n){let r=e.findByDevice(t);if(!(!r||r.address===n))return r}function pi(e){let{req:t,sessionName:n,sessionStore:r,deviceId:i,budgetMs:a}=e,o=ue.fromTimeoutMs(a),s=()=>fi(r,i,n),c=async()=>{for(;;){let e=s();if(!e||o.isExpired())return;Ee({type:`command`,status:`progress`,message:`Waiting for ${e.session.device.name}: held by session "${e.address}" (${Math.round(o.elapsedMs())}ms of the ${Math.round(a)}ms wait budget used)`}),await ce(Math.min(250,o.remainingMs())),Te(t.meta?.requestId)}};return{waitForDeviceOutsideLocks:c,runWhenDeviceIsUnheld:async e=>{let{acquireLocks:n,task:r}=e;for(;;){let e=await n(async()=>{if(s()){if(!o.isExpired())return{ran:!1};mi(t,o.elapsedMs())}return{ran:!0,outcome:await r()}});if(e.ran)return e.outcome;await c()}}}}function mi(e,t){if(t<=0)return;let n=e.internal??={};n.openDeviceWait={waitedMs:t}}const hi={label:`Materialized paths`,plural:!0,expiredHint:`Materialized paths are released automatically when their TTL expires; re-run the command that materialized them if the paths are still needed.`},J=new Map;async function gi(e){let t=await O.mkdtemp(D.join(ot.tmpdir(),`agent-device-materialized-`));try{let n=await bi(e.installablePath,D.join(t,`installable`)),r=e.archivePath?await bi(e.archivePath,D.join(t,`archive`)):void 0,i=it.randomUUID(),a=e.ttlMs??9e5,o=Date.now()+a,s=setTimeout(()=>{yi(i)},a);return J.set(i,{rootPath:t,installablePath:n,archivePath:r,tenantId:e.tenantId,sessionName:e.sessionName,expiresAt:o,timer:s}),{materializationId:i,installablePath:n,...r?{archivePath:r}:{},expiresAt:new Date(o).toISOString()}}catch(e){throw await O.rm(t,{recursive:!0,force:!0}),e}}async function _i(e,t){await Y(e,ke(J,e,t,hi))}async function vi(e){let t=Array.from(J.entries()).filter(([,t])=>t.sessionName===e);await Promise.all(t.map(async([e,t])=>{await Y(e,t)}))}async function yi(e){let t=J.get(e);if(t)try{await Y(e,t)}catch{}}async function Y(e,t){clearTimeout(t.timer),J.delete(e),await O.rm(t.rootPath,{recursive:!0,force:!0})}async function bi(e,t){let n=await O.stat(e);await O.mkdir(t,{recursive:!0});let r=D.join(t,D.basename(e));return n.isDirectory()?(await O.cp(e,r,{recursive:!0}),r):(await O.copyFile(e,r),r)}function xi(e){return e.device.platform===`web`}function Si(e){return e.toArray().filter(e=>e.device.platform===`web`).map(e=>e.name)}async function Ci(e){let{session:t,sessionName:n,sessionStore:r}=e;t.appLog&&await Ve({session:t,sessionName:n,sessionStore:r,resourcePath:ze.resolvePath(r.resolveSessionDir(n))})}async function wi(e){let t=e.sessionStore.get(e.sessionName)??e.session;t.perfCapture&&await Be({...e,session:t,intent:`disposal`})}async function Ti(e,t){await t.stopSnapshotHelper(e.device)}async function Ei(e){let{session:t,sessionName:n,sessionStore:r,platformCleanup:i}=e;await i.closeManagedBrowser({device:t.device,sessionName:n,stateDir:r.resolveDaemonStateDir(),openSessionNames:()=>Si(r)})}async function Di(e){let t=[];for(let{step:n,run:r}of e)try{await r()}catch(e){t.push({step:n,error:e})}return t}function Oi(e){if(e.failures.length===0)return;let n=e.failures.map(({step:e})=>e),r=e.failures.map(({step:e,error:t})=>`${e}: ${t instanceof Error?t.message:String(t)}`);return _({level:`error`,phase:e.phase,data:{session:e.sessionName,failedSteps:n,errors:r}}),new t(`COMMAND_FAILED`,`Session cleanup left ${e.failures.length} resource(s) unreleased: ${r.join(`; `)}`,{reason:`session_cleanup_incomplete`,session:e.sessionName,failedSteps:n,hint:`Some session resources failed to release; inspect the session log for per-resource diagnostics. The session was still deleted, so retrying is safe.`})}async function ki(e){let{session:n,sessionName:r,sessionStore:i}=e;if(!e.platformCleanup)throw new t(`INTERNAL_ERROR`,`Platform resource cleanup was not supplied by root runtime composition`);let a=e.platformCleanup,o=[{step:`recording`,run:()=>Ai({session:n,sessionName:r,sessionStore:i})},...e.appLog===`run`?[{step:`app_log`,run:()=>Ci({session:n,sessionName:r,sessionStore:i})}]:[],{step:`audio_probe`,run:()=>ji({session:n,sessionName:r,sessionStore:i})},{step:`perf_capture`,run:()=>wi({session:n,sessionName:r,sessionStore:i})},{step:`platform_snapshot_helper`,run:()=>Ti(n,a)},{step:`web_browser`,run:()=>Ei({session:n,sessionName:r,sessionStore:i,platformCleanup:a})}];o.push({step:`materialized_paths`,run:()=>vi(r)});let s=Oi({sessionName:r,phase:`session_teardown_cleanup_failed`,failures:await Di(o)});if(s)throw s}async function Ai(e){let t=e.sessionStore.get(e.sessionName)??e.session;t.screenRecording&&await rt({intent:`disposal`,session:t,sessionName:e.sessionName,sessionStore:e.sessionStore})}async function ji(e){let t=e.sessionStore.get(e.sessionName)??e.session;t.audioProbe&&await Re({intent:`disposal`,session:t,sessionName:e.sessionName,sessionStore:e.sessionStore})}function Mi(e){return d(e)&&e.kind===`simulator`}function Ni(e){return e.platform===`android`&&e.kind===`emulator`}const Pi=[`platform`,`metroHost`,`metroPort`,`bundleUrl`,`launchUrl`];function X(e){return e?[e.metroHost,e.metroPort,e.bundleUrl,e.launchUrl].filter(e=>e!==void 0&&e!==``).length:0}function Z(e){if(!e)return{};let t={};return e.metroHost!==void 0&&(t.metroHost=e.metroHost),e.metroPort!==void 0&&(t.metroPort=String(e.metroPort)),e.bundleUrl!==void 0&&(t.bundleUrl=e.bundleUrl),e.launchUrl!==void 0&&(t.launchUrl=e.launchUrl),t}function Q(e){return Ae(Z(e))}function $(e,n){if(e!==void 0){if(typeof e!=`string`)throw new t(`INVALID_ARGS`,`Invalid open runtime ${n}: expected string.`);return v(e)}}function Fi(e){if(e!==void 0){if(!Number.isInteger(e)||e<1||e>65535)throw new t(`INVALID_ARGS`,`Invalid runtime metroPort: ${String(e)}. Use an integer between 1 and 65535.`);return e}}function Ii(e){if(e!==void 0){if(typeof e!=`number`)throw new t(`INVALID_ARGS`,`Invalid open runtime metroPort: expected integer.`);return Fi(e)}}function Li(e,n,i){if(e===void 0)return i;if(!r(e))throw new t(`INVALID_ARGS`,`Invalid open runtime platform: ${String(e)}. Use "ios", "android", or "harmonyos".`);if(i&&e!==i)throw new t(`INVALID_ARGS`,`open runtime targets ${e}, but session "${n}" is bound to ${i}.`);return e}function Ri(e){if(r(e))return e}function zi(e,t){return{platform:t,metroHost:v(e?.metroHost),metroPort:Fi(e?.metroPort),bundleUrl:v(e?.bundleUrl),launchUrl:v(e?.launchUrl)}}function Bi(e,t){return{platform:t.platform??e?.platform,metroHost:t.metroHost??e?.metroHost,metroPort:t.metroPort??e?.metroPort,bundleUrl:t.bundleUrl??e?.bundleUrl,launchUrl:t.launchUrl??e?.launchUrl}}function Vi(e){if(Ni(e))return`10.0.2.2`;if(Mi(e))return`127.0.0.1`}function Hi(e,t){if(!e||v(e.metroHost)||v(e.bundleUrl)||e.metroPort===void 0)return e;let n=Vi(t);return n?{...e,metroHost:n}:e}function Ui(e){let{runtime:n,sessionName:r,platform:i}=e;if(n===void 0)return;if(!n||typeof n!=`object`||Array.isArray(n))throw new t(`INVALID_ARGS`,`open runtime must be an object.`);let a=n,o=Object.keys(a).find(e=>!Pi.includes(e));if(o)throw new t(`INVALID_ARGS`,`Invalid open runtime field: ${o}. Supported fields are ${Pi.join(`, `)}.`);return{platform:Li(a.platform,r,i),metroHost:$(a.metroHost,`metroHost`),metroPort:Ii(a.metroPort),bundleUrl:$(a.bundleUrl,`bundleUrl`),launchUrl:$(a.launchUrl,`launchUrl`)}}function Wi(e,t,n){if(n){if(X(n)===0){e.clearRuntimeHints(t);return}return e.setRuntimeHints(t,n),n}}function Gi(e,n,r,i){let a=e.getRuntimeHints(n);if(!a)return;let o=r?c(r):void 0,s=Ri(o)??i;if(a.platform&&r&&!s)throw new t(`INVALID_ARGS`,`Session runtime hints are only supported on iOS, Android, and HarmonyOS sessions, but session "${n}" is bound to ${o}.`);if(a.platform&&s&&a.platform!==s)throw new t(`INVALID_ARGS`,`Session runtime hints target ${a.platform}, but session "${n}" is bound to ${o}. Clear the runtime hints or use a different session.`);return s&&a.platform!==s?{...a,platform:s}:a}function Ki(e){let{req:t,sessionStore:n,sessionName:r,device:i}=e,a=i?Ri(c(i)):e.platform,o=n.getRuntimeHints(r),s=Ui({runtime:t.runtime,sessionName:r,platform:a});if(t.runtime===void 0){let e=Gi(n,r,i,a);return{runtime:i?Hi(e,i):e,previousRuntime:o,replacedStoredRuntime:!1}}let l=s&&X(s)>0?s:void 0;return{runtime:i?Hi(l,i):l,previousRuntime:o,replacedStoredRuntime:!0}}function qi(e){return Ki(e).runtime}function Ji(e){try{return{ok:!0,data:Ki(e)}}catch(e){let t=n(e);return i(t.code,t.message,t.details)}}async function Yi(e){let{previousRuntime:t,clearRuntimeHints:n}=e;if(!Xi(e))return;let r=e.session;r?.appBundleId&&await n({appId:r.appBundleId,values:Z(t)})}function Xi(e){return e.replacedStoredRuntime&&!!e.session?.appBundleId&&Q(e.previousRuntime)&&!Q(e.runtime)}function Zi(e){let{device:t,owner:n,stateDir:r,intent:i}=e,a=i.kind===`exact-owner`&&ie(i.owner,n)?ne(i.fence):null;if(!a)return{status:`binding-invalid`};let o=C(w(t)),s=Fe(Me(o));if(!s)return{status:`missing`};let c=s.allocatorClaim;return!c||!$i(c.stateDir,r)||!ie(Pe(c),n)?{status:`conflict`,conflict:s}:c.allocator.identityIncarnationId===a.identityIncarnationId?{status:`covered`}:{status:`incarnation-stale`,heldIncarnationId:c.allocator.identityIncarnationId}}function Qi(e){let t=C(w(e));return je(Me(t))}function $i(e,t){return D.resolve(e)===D.resolve(t)}function ea(e,t,n=`status`){let r=t.claim??t.allocatorClaim,i=c(r?{platform:r.device.family,appleOs:r.device.appleOs}:e),a=l(e.platform)?`--udid`:`--serial`;return[`agent-device device ${n}`,`--platform ${le(i)}`,`${a} ${le(e.id)}`,...n===`release`||Ne(t.classification)?[`--stale`]:[]].join(` `)}function ta(e,n){if(n.classification===`allocator-held`)return ra(e,n);let r=n.claim,i=ea(e,n,Ie(n.classification)?`release`:`status`),a=c(r?{platform:r.device.family,appleOs:r.device.appleOs}:e);return new t(`DEVICE_IN_USE`,r?`${a} device ${e.id} is owned by session "${r.session}" in workspace "${r.workspace}".`:`${e.name} has an ownership claim that could not be verified.`,{reason:ua(n.classification),classification:n.classification,deviceKey:n.deviceKey,...r?{owner:{session:r.session,workspace:r.workspace,stateDir:r.stateDir}}:{},recovery:{command:i},hint:Ie(n.classification)?`The recorded owner can no longer release this device; settle its resources and release the claim with: ${i}`:`Inspect the owner with: ${i}`,retriable:!1})}function na(e,t){return la(ta(e,t))}function ra(e,n){let r=n.allocatorClaim,i=c({platform:r.device.family,appleOs:r.device.appleOs}),a=ea(e,n);return new t(`DEVICE_IN_USE`,`${i} device ${e.id} is held by managed-device allocator "${r.allocator.instanceId}" for installation "${r.stateDir}".`,{reason:`DEVICE_CLAIM_ALLOCATOR_HELD`,classification:n.classification,deviceKey:n.deviceKey,owner:{kind:`allocator`,stateDir:r.stateDir,allocator:r.allocator},recovery:{command:a},hint:`This device belongs to a managed pool and is released only after its allocator proves the identity removed; inspect with: ${a}`,retriable:!1})}function ia(e,n){return new t(`COMMAND_FAILED`,`${c(e)} device ${e.id} is a managed identity with no allocator-held execution claim for this installation.`,{reason:`allocator-claim-missing`,owner:h(n),deviceKey:C(w(e)),retriable:!1,hint:`A managed identity becomes executable only after its allocator activates it and this installation holds its allocator-held claim.`})}function aa(e,n,r){return new t(`COMMAND_FAILED`,`${c(e)} device ${e.id} is held for identity incarnation "${r}", which is not the incarnation this binding fences.`,{reason:`allocator-claim-incarnation-stale`,owner:h(n),deviceKey:C(w(e)),heldIncarnationId:r,retriable:!1,hint:`The managed identity was re-provisioned; obtain a new grant from the allocator.`})}function oa(e,n){return new t(`COMMAND_FAILED`,`A managed local owner executes only under an exact-owner binding that carries a managed binding fence.`,{reason:`runtime-contract-invalid`,owner:h(n),deviceKey:C(w(e)),retriable:!1})}function sa(e,t,n){switch(n.status){case`binding-invalid`:return{admitted:!1,error:oa(e,t)};case`missing`:return{admitted:!1,error:ia(e,t)};case`covered`:return{admitted:!0};case`incarnation-stale`:return{admitted:!1,error:aa(e,t,n.heldIncarnationId)};case`conflict`:return{admitted:!1,error:ta(e,n.conflict)}}}function ca(e,t,n){let r=sa(e,t,n);return r.admitted?void 0:la(r.error)}function la(e){let{hint:t,retriable:n,...r}=e.details??{};return i(e.code,e.message,r,{hint:t,retriable:n})}function ua(e){switch(e){case`live`:return`DEVICE_CLAIM_LIVE_OWNER`;case`owner-process-dead`:case`owner-daemon-superseded`:return`DEVICE_CLAIM_RECOVERY_PENDING`;case`owner-process-reused`:case`owner-state-dir-gone`:case`unknown`:case`inconsistent`:case`allocator-inconsistent`:return`DEVICE_CLAIM_OWNER_UNCERTAIN`}}function da(e){switch(e.kind){case`local-family`:return`ordinary`;case`managed-local`:return`allocator-held`;case`provider-runtime`:return`none`}}export{hr as $,gi as A,Yr as B,wi as C,Si as D,xi as E,ii as F,Nr as G,qr as H,ai as I,Rr as J,Ir as K,ri as L,ui as M,ci as N,_i as O,si as P,xr as Q,ti as R,Ci as S,ki as T,Fr as U,Jr as V,Pr as W,W as X,zr as Y,jr as Z,Ri as _,St as _t,ta as a,Pt as at,Ai as b,ct as bt,zi as c,Dt as ct,Yi as d,kt as dt,fr as et,Bi as f,xt as ft,Xi as g,Ct as gt,Wi as h,vt as ht,sa as i,j as it,di as j,vi as k,X as l,Et as lt,Z as m,bt as mt,ca as n,cr as nt,Qi as o,Nt as ot,qi as p,yt as pt,Lr as q,na as r,F as rt,Zi as s,jt as st,da as t,lr as tt,Q as u,Ot as ut,Ji as v,ft as vt,Ti as w,Oi as x,ji as y,dt as yt,ni as z};
|
|
1
|
+
import{F as e,N as t,P as n,c as r,o as i}from"./sdk-contracts.js";import"./capture.js";import{i as a,p as o}from"./sdk-batch-runner.js";import{p as s}from"./android-input-ownership.js";import{C as c,d as l,l as u,p as d}from"./sdk-device.js";import{f,n as p,u as m}from"./lease-scope.js";import{Ar as h,Dr as ee,Lr as te,Yr as g,Yt as ne,en as _,or as re,tn as ie}from"./sdk-batch.js";import{a as ae}from"./script.js";import"./session-store.js";import{i as oe}from"./back-mode.js";import{r as v}from"./diagnostics.js";import{t as se}from"./timeouts.js";import"./diagnostics2.js";import{s as ce}from"./device-shell.js";import{n as le}from"./retry.js";import{n as y}from"./runtime-transport-hints.js";import{_ as ue,a as de,c as fe,d as b,f as pe,g as me,h as he,i as ge,l as _e,m as ve,n as x,o as ye,p as S,r as be,s as C,u as xe,v as Se,y as Ce}from"./human-control-contract.js";import{c as we}from"./request-cancel.js";import{t as Te}from"./request.js";import{n as Ee,t as De,u as Oe}from"./provider-session-ownership.js";import{r as ke}from"./application-lifecycle-runtime.js";import{a as Ae,c as w,l as je,n as Me,o as Ne,r as Pe,t as Fe}from"./device-claim-inspection.js";import{b as Ie,c as Le,g as Re,i as ze,p as Be,x as T}from"./perf-runtime-plan.js";import{n as Ve,r as He,t as Ue}from"./lease-context.js";import{d as We,g as Ge,u as Ke}from"./screenshot-runtime.js";import{n as qe}from"./screen-recording-admission-ledger.js";import{a as Je,c as Ye,d as E,l as Xe,n as Ze,o as Qe,r as $e,u as D}from"./src8.js";import{n as et,t as tt}from"./compatibility-policy.js";import{o as nt}from"./screen-recording-resource-recovery.js";import O from"node:path";import"node:fs";import rt,{createHash as it}from"node:crypto";import at from"node:os";import k from"node:fs/promises";function ot(e,t){return A(e,t)?t:`${e}:${t}`}function A(e,t){return t.startsWith(`${e}:`)}function st(e,t){return!e.partitioned||A(e.tenant,t)}var ct=class{active=new Map;waiters=new Map;async run(e,t){this.active.set(e,(this.active.get(e)??0)+1);try{return await t()}finally{let t=(this.active.get(e)??1)-1;if(t>0)this.active.set(e,t);else{this.active.delete(e);let t=this.waiters.get(e);this.waiters.delete(e);for(let e of t??[])e()}}}async wait(e,t){if(t?.throwIfAborted(),!this.active.has(e))return;let n=this.waiters.get(e)??new Set,r=()=>{},i=()=>{};try{await new Promise((a,o)=>{r=a,i=()=>o(t?.reason),n.add(r),this.waiters.set(e,n),t?.addEventListener(`abort`,i,{once:!0})})}finally{t?.removeEventListener(`abort`,i),n.delete(r),n.size===0&&this.waiters.get(e)===n&&this.waiters.delete(e)}}},lt=class{entriesByLeaseId=new Map;retain(e,t){let n={wanted:t,released:!1},r=this.entriesByLeaseId.get(e)??new Set;return r.add(n),this.entriesByLeaseId.set(e,r),{leaseId:e,release:()=>this.releasePass(e,r,n)}}forget(e){let t=this.entriesByLeaseId.get(e);if(t){for(let e of t)e.released=!0;this.entriesByLeaseId.delete(e)}}isDeferred(e){let t=this.entriesByLeaseId.get(e);if(!t)return!1;for(let e of t)e.wanted()||t.delete(e);return t.size>0||(this.entriesByLeaseId.delete(e),!1)}releasePass(e,t,n){return!n.released&&(n.released=!0,t.delete(n),t.size===0&&this.entriesByLeaseId.delete(e),n.wanted())}},ut=class{holdsByDevice=new Map;mutations=new ct;inFlightWork=new lt;leases=new Map;runBindings=new Map;deviceBindings=new Map;maxActiveSimulatorLeases;resolveLeaseTtlMs;now;onLeaseExpired;providerSessionOwnership;constructor(e={}){this.maxActiveSimulatorLeases=Number.isInteger(e.maxActiveSimulatorLeases)?Math.max(0,Number(e.maxActiveSimulatorLeases)):0,this.resolveLeaseTtlMs=_e(e),this.now=e.now??(()=>Date.now()),this.onLeaseExpired=e.onLeaseExpired,this.providerSessionOwnership=new De({now:this.now,retentionMs:e.providerSessionRetentionMs})}allocateLease(e){let t=ve(e);this.cleanupExpiredLeases();let n=this.resolveLeaseTtlMs(t.ttlMs);this.assertHumanControlAdmission(t);let r=this.refreshExistingRunBinding(t,n);if(r)return r;this.assertDeviceAvailable(t),this.enforceCapacity(t.backend);let i=fe(t,n,this.now());return this.leases.set(i.leaseId,i),this.bindLease(i),{...i}}refreshExistingRunBinding(e,t){let n=S(e),r=this.runBindings.get(n);if(!r)return;let i=this.leases.get(r);if(!i){this.runBindings.delete(n);return}if(i.clientId===e.clientId)return this.refreshLease(i,t);if(i.deviceKey)throw xe(i);return C(i,e),this.refreshLease(i,t)}heartbeatLease(e){let t=ue(e.leaseId);this.cleanupExpiredLeases();let n=this.getActiveLease(t);ye(n,e),C(n,e);let r=e.ttlMs===void 0?pe(n):this.resolveLeaseTtlMs(e.ttlMs);return this.refreshLease(n,r)}retainLeaseWork(e,t){let n=this.inFlightWork.retain(e.leaseId,t);return{leaseId:n.leaseId,release:()=>{let t=n.release();return t&&this.refreshProtectedLease(e.leaseId,this.now()),t}}}releaseLease(e){let t=this.getLease(e);return t?(this.leases.delete(t.leaseId),this.unbindLease(t),this.inFlightWork.forget(t.leaseId),{released:!0,lease:t}):{released:!1}}getLease(e){let t=ue(e.leaseId);this.cleanupExpiredLeases();let n=this.leases.get(t);if(n)return ye(n,e),C(n,e),{...n}}assertLeaseAdmission(e){let t=he(e);this.cleanupExpiredLeases(),C(this.getActiveLease(t.leaseId),t)}listActiveLeases(){return this.cleanupExpiredLeases(),Array.from(this.leases.values()).map(e=>({...e}))}recordProviderSession(e,t){this.cleanupExpiredLeases();let n=e.expiresAt<=this.now()?e.expiresAt:void 0;this.providerSessionOwnership.record(e,t),this.leases.has(e.leaseId)||this.providerSessionOwnership.markLeaseReleased(e,n)}resolveProviderSession(e){return this.cleanupExpiredLeases(),this.providerSessionOwnership.resolve(e)}listHumanControlHolds(e){this.cleanupExpiredLeases();let t=e.kind===`lease`?b(this.requireHumanControlLease(e.leaseId)):void 0;return[...this.holdsByDevice.entries()].filter(([e])=>t===void 0||t===e).flatMap(([,e])=>[...e.values()].map(({hold:e})=>x(e))).sort((e,t)=>e.id.localeCompare(t.id))}async putHumanControlHold(e,n,r,i){i?.throwIfAborted();let a=ge(n),o=de(r);this.cleanupExpiredLeases();let s=this.resolveHumanControlScope(e,o),c=b(s),l=this.findHumanControlHold(a);if(l&&(this.assertHoldAuthority(e,l),b(l.hold.scope)!==c))throw new t(`INVALID_ARGS`,`Release a hold before changing its device scope.`);let u=this.now(),d={...e.kind===`lease`?{ownerLeaseId:e.leaseId}:{},hold:{id:a,scope:s,state:`activating`,...o.reason?{reason:o.reason}:{},createdAt:l?.hold.createdAt??u,updatedAt:u}},f=this.holdsByDevice.get(c)??new Map;return this.holdsByDevice.set(c,f),f.set(a,d),await this.activateHumanControlHold(c,d,o.ttlMs,i)}async activateHumanControlHold(e,n,r,i){let a=this.holdsByDevice.get(e),{id:o}=n.hold;try{if(await this.mutations.wait(e,i),i?.throwIfAborted(),a.get(o)!==n)throw new t(`COMMAND_FAILED`,`Human-control hold changed before activation completed.`,{holdId:o});let s=this.now();return n.hold={...n.hold,state:`active`,updatedAt:s,...r===void 0?{}:{expiresAt:s+r}},this.refreshHeldLease(e,s),x(n.hold)}catch(t){throw a.get(o)===n&&this.deleteHumanControlHold(e,o),t}}removeHumanControlHold(e,t){let n=ge(t);this.cleanupExpiredLeases();let r=this.findHumanControlHold(n);if(!r)return;this.assertHoldAuthority(e,r);let i=b(r.hold.scope);return this.deleteHumanControlHold(i,n),x(r.hold)}deleteHumanControlHold(e,t){let n=this.holdsByDevice.get(e);n.delete(t),n.size===0&&(this.holdsByDevice.delete(e),this.refreshHeldLease(e,this.now()))}assertHumanControlAdmission(e){this.expireHumanControlHolds();let t=b(e),n=t===void 0?void 0:this.holdsByDevice.get(t)?.values().next().value;if(n)throw be(n.hold)}async runDeviceMutation(e,t){if(!e)return await t();this.cleanupExpiredLeases();let n=this.getActiveLease(e.leaseId);this.assertHumanControlAdmission(n);let r=b(n);return r===void 0?await t():await this.mutations.run(r,t)}requireHumanControlLease(e){let n=this.getActiveLease(e);if(!n.deviceKey)throw new t(`UNSUPPORTED_OPERATION`,`Human control requires a device-scoped remote lease.`);return{...n,deviceKey:n.deviceKey}}resolveHumanControlScope(e,n){if(e.kind===`host`){if(!n.scope)throw new t(`INVALID_ARGS`,`Host human control requires a lease device scope.`);return n.scope}if(n.scope)throw new t(`INVALID_ARGS`,`Lease-owner human control uses the admitted lease device; do not supply scope.`);let r=this.requireHumanControlLease(e.leaseId);return{backend:r.backend,leaseProvider:r.leaseProvider,deviceKey:r.deviceKey}}assertHoldAuthority(e,n){if(e.kind===`host`)return;let r=this.requireHumanControlLease(e.leaseId);if(n.ownerLeaseId!==r.leaseId||b(r)!==b(n.hold.scope))throw new t(`UNAUTHORIZED`,`Human-control hold does not belong to the admitted lease.`,{reason:`LEASE_SCOPE_MISMATCH`})}findHumanControlHold(e){for(let t of this.holdsByDevice.values()){let n=t.get(e);if(n)return n}}hasHumanControl(e){let t=b(e);return t!==void 0&&this.holdsByDevice.has(t)}isLeaseProtected(e,t){return e.expiresAt>t||this.hasHumanControl(e)||this.inFlightWork.isDeferred(e.leaseId)}expireHumanControlHolds(){let e=this.now();for(let[t,n]of this.holdsByDevice){let r=0;for(let[t,{hold:i}]of n)i.expiresAt===void 0||i.expiresAt>e||(r=Math.max(r,i.expiresAt),n.delete(t));n.size===0&&(this.holdsByDevice.delete(t),this.refreshHeldLease(t,r))}}refreshHeldLease(e,t){this.refreshProtectedLease(this.deviceBindings.get(e),t)}refreshProtectedLease(e,t){let n=e?this.leases.get(e):void 0;n&&this.refreshLease(n,pe(n),Math.max(t,n.heartbeatAt))}consumeExpiredLeases(){this.expireHumanControlHolds();let e=this.now(),t=[];for(let n of this.leases.values()){if(this.isLeaseProtected(n,e))continue;this.leases.delete(n.leaseId),this.unbindLease(n,n.expiresAt);let r={...n};t.push(r),this.onLeaseExpired?.(r)}return t}consumeExpiredLease(e){this.expireHumanControlHolds();let t=me(e);if(!t)return;let n=this.leases.get(t);if(!n||this.isLeaseProtected(n,this.now()))return;this.leases.delete(n.leaseId),this.unbindLease(n,n.expiresAt);let r={...n};return this.onLeaseExpired?.(r),r}cleanupExpiredLeases(){this.consumeExpiredLeases()}enforceCapacity(e){if(e!==`ios-simulator`||this.maxActiveSimulatorLeases<=0)return;let n=Array.from(this.leases.values()).filter(e=>e.backend===`ios-simulator`).length;if(!(n<this.maxActiveSimulatorLeases))throw new t(`DEVICE_IN_USE`,`No simulator lease capacity available`,{reason:`LEASE_CAPACITY_EXCEEDED`,activeLeases:n,maxActiveLeases:this.maxActiveSimulatorLeases,backend:e,hint:`Retry after releasing another simulator lease.`})}getActiveLease(e){let n=this.leases.get(e);if(n)return n;throw new t(`UNAUTHORIZED`,`Lease is not active`,{reason:`LEASE_NOT_FOUND`})}refreshLease(e,t,n=this.now()){let r={...e,heartbeatAt:n,expiresAt:n+t};return this.leases.set(r.leaseId,r),this.bindLease(r),{...r}}bindLease(e){this.runBindings.set(S(e),e.leaseId);let t=b(e);t&&this.deviceBindings.set(t,e.leaseId)}unbindLease(e,t=this.now()){this.runBindings.delete(S(e));let n=b(e);n&&this.deviceBindings.delete(n),this.providerSessionOwnership.markLeaseReleased(e,t)}assertDeviceAvailable(e){let t=b({backend:e.backend,leaseProvider:e.leaseProvider,deviceKey:e.deviceKey});if(!t)return;let n=this.deviceBindings.get(t);if(!n)return;let r=this.leases.get(n);if(!r){this.deviceBindings.delete(t);return}throw xe(r)}};function dt(e){let n=Ce(e.meta?.sessionIsolation??e.flags?.sessionIsolation),r=e.meta?.tenantId??e.flags?.tenant,i=Se(r);if(r&&!i)throw new t(`INVALID_ARGS`,`Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.`);if(n!==`tenant`)return e;if(!i)throw new t(`INVALID_ARGS`,`session isolation mode tenant requires --tenant (or meta.tenantId).`);let a=e.session||`default`;return A(i,a)?{...e,meta:{...e.meta,tenantId:i,sessionIsolation:n}}:{...e,session:ot(i,a),meta:{...e.meta,tenantId:i,sessionIsolation:n}}}function ft(e,n,r,i={}){if(We(e.command))return;let a=Ve(e);ht(e,a);let o=r?.lease;if(r===void 0&&!a.leaseId&&pt(e,i.providerAppCatalog))return;if(e.command===`human_control`&&!o&&!a.leaseId)throw new t(`UNSUPPORTED_OPERATION`,`Takeover requires an active remote device lease. Local takeover is not supported.`);if(e.command!==`human_control`&&!o&&e.meta?.sessionIsolation!==`tenant`&&(!a.leaseId||!a.tenantId&&!a.runId))return;gt(a,o);let s=He(e,r);n.assertLeaseAdmission(m(s));let c=n.heartbeatLease(m(s));return Ke(e)&&n.assertHumanControlAdmission(c),c}function pt(e,t){let n=Ge(e);return n?.kind===`unconditional`||n?.kind===`provider-app-catalog`&&t?.supports(n.provider)===!0}function mt(e){We(e.command)||ht(e,Ve(e))}function ht(e,n){if(e.command!==`open`)return;let r=p(n);if(r.length!==0)throw new t(`INVALID_ARGS`,`Proxy open requires leaseId, tenantId, runId, clientId, and deviceKey lease metadata.`,{missing:r})}function gt(e,t){t&&(j(`leaseId`,e.leaseId,t.leaseId),j(`tenantId`,e.tenantId,t.tenantId),j(`runId`,e.runId,t.runId),j(`leaseProvider`,e.leaseProvider,t.leaseProvider),j(`clientId`,e.clientId,t.clientId),j(`deviceKey`,e.deviceKey,t.deviceKey))}function j(e,n,r){if(!(!n||!r||n===r))throw new t(`UNAUTHORIZED`,`Lease does not match session owner (${e})`,{reason:`LEASE_SESSION_MISMATCH`,field:e})}async function _t(e,t){if(!t.leaseProvider||!e)return!1;try{return await e(t),v({level:`info`,phase:`provider_lease_expired_released`,data:{leaseId:t.leaseId,provider:t.leaseProvider}}),!0}catch(e){return v({level:`error`,phase:`provider_lease_expiry_release_failed`,data:{leaseId:t.leaseId,provider:t.leaseProvider,error:e instanceof Error?e.message:String(e)}}),!1}}function vt(e){mt(e)}async function yt(e){let t=e.sessionStore.get(e.sessionName),n=t?.lease;return!t||!n||!e.leaseRegistry.consumeExpiredLease(n.leaseId)?!1:(v({level:`info`,phase:`leased_session_expired`,data:{reason:`LEASE_EXPIRED`,leaseId:n.leaseId,session:t.name,deviceKey:n.deviceKey}}),await e.teardownSession(t,t.name).catch(e=>{v({level:`debug`,phase:`leased_session_expiry_cleanup_failed`,data:{reason:`LEASE_EXPIRED`,leaseId:n.leaseId,session:t.name,error:e instanceof Error?e.message:String(e)}})}),await Ie(t.deviceClaim).catch(e=>{v({level:`warn`,phase:`leased_session_expiry_device_claim_clear_failed`,data:{session:t.name,deviceKey:t.deviceClaim?.deviceKey,error:e instanceof Error?e.message:String(e)}})}),e.sessionStore.delete(t.name),!0)}function bt(e){let{sessionName:t,sessionStore:n,leaseRegistry:r}=e,i=n.get(t),a=ft(e.req,r,i,{providerAppCatalog:e.providerAppCatalog});if(!a)return e.req;let o={...e.req,internal:{...e.req.internal,admittedLease:a}};return i?.lease&&n.set(t,{...i,lease:{...i.lease,leaseBackend:a.backend,expiresAt:a.expiresAt}}),o}function xt(e){return Ue(e.req,e.req.internal?.admittedLease)??e.existingLease}async function St(e){let t=e.session.lease;if(!t)return;let n=f({leaseId:t.leaseId,tenantId:t.tenantId,runId:t.runId,leaseBackend:t.leaseBackend,leaseProvider:t.leaseProvider,deviceKey:t.deviceKey,clientId:t.clientId}),r=e.leaseRegistry.getLease(n),i=r?await e.leaseLifecycleProvider?.release?.(r):void 0,a=Ee(i);r&&a&&e.leaseRegistry.recordProviderSession(r,a);let o=e.leaseRegistry.releaseLease(n);return v({level:`info`,phase:`session_lease_released`,data:{session:e.session.name,leaseId:t.leaseId,released:o.released}}),i}const Ct=[`platform`,`target`],wt=[`iosSimulatorDeviceSet`,`androidDeviceAllowlist`];function Tt(e){return u({deviceName:e?.device,udid:e?.udid,serial:e?.serial})}function Et(e){return Tt(e)||kt(e,Ct)}function Dt(e){return Et(e)||kt(e,wt)}function Ot(e){return typeof e==`string`&&e.trim().length>0}function kt(e,t){return e?t.some(t=>Ot(e[t])):!1}function At(e){return{appleSimulatorAppTarget:jt(e)}}function jt(e){return e&&!a(e)?e:void 0}function Mt(){return qe({displayName:`audio probe`})}function Nt(){return qe({displayName:`perf capture`})}function Pt(e){let t={version:2,platform:e.platform??null,target:e.target??null,runtimeHints:e.runtimeHints??null,initialStaticEnv:e.initialStaticEnv,steps:e.steps};return it(`sha256`).update(re(t),`utf8`).digest(`hex`)}function Ft(e,t,n){return new Wt(Lt(It(t.resolve(e))),n).parse()}function It(e){let t=e.trim();return t.startsWith("${")&&t.endsWith(`}`)?t.slice(2,-1).trim():t}function Lt(e){let n=[],r=0;for(;r<e.length;){let i=e.slice(r),a=/^\s+/.exec(i)?.[0].length??0;if(a>0){r+=a;continue}let o=Rt(i);if(!o)throw new t(`INVALID_ARGS`,`Unsupported runFlow.when.true expression near "${i.slice(0,24)}".`);n.push(o.value),r+=o.length}return n}function Rt(e){return zt(e)??Bt(e)??Vt(e)??Ht(e)??Ut(e)}function zt(e){return e.startsWith(`maestro.platform`)?{value:{type:`platform`},length:16}:null}function Bt(e){let t=/^(==|!=|&&|\|\|)/.exec(e)?.[1];return t?{value:{type:`operator`,value:t},length:t.length}:null}function Vt(e){let t=e[0];return t===`(`||t===`)`?{value:{type:`paren`,value:t},length:1}:null}function Ht(e){let t=/^(['"])(.*?)\1/.exec(e);return t?{value:{type:`string`,value:t[2]??``},length:t[0].length}:null}function Ut(e){let t=/^(true|false)\b/.exec(e)?.[1];return t?{value:{type:`boolean`,value:t===`true`},length:t.length}:null}var Wt=class{index=0;tokens;platform;constructor(e,t){this.tokens=e,this.platform=t}parse(){let e=this.parseOr();if(this.peek())throw new t(`INVALID_ARGS`,`Unsupported trailing runFlow.when.true expression.`);return e}parseOr(){let e=this.parseAnd();for(;this.consumeOperator(`||`);)e=this.parseAnd()||e;return e}parseAnd(){let e=this.parsePrimary();for(;this.consumeOperator(`&&`);)e=this.parsePrimary()&&e;return e}parsePrimary(){let e=this.peek();if(!e)throw new t(`INVALID_ARGS`,`Incomplete runFlow.when.true expression.`);if(e.type===`boolean`)return this.index+=1,e.value;if(e.type===`paren`&&e.value===`(`){this.index+=1;let e=this.parseOr();if(!this.consumeParen(`)`))throw new t(`INVALID_ARGS`,`Unclosed runFlow.when.true parenthesis.`);return e}return this.parsePlatformComparison()}parsePlatformComparison(){this.consumePlatformToken();let e=this.consumeComparisonOperator(),t=this.consumeStringLiteral(),n=this.platform===t.toLowerCase();return e.value===`==`?n:!n}consumePlatformToken(){if(this.peek()?.type!==`platform`)throw new t(`INVALID_ARGS`,`runFlow.when.true supports maestro.platform comparisons.`);this.index+=1}consumeComparisonOperator(){let e=this.peek();if(e?.type!==`operator`||e.value!==`==`&&e.value!==`!=`)throw new t(`INVALID_ARGS`,`runFlow.when.true comparison requires == or !=.`);return this.index+=1,e}consumeStringLiteral(){let e=this.peek();if(e?.type!==`string`)throw new t(`INVALID_ARGS`,`runFlow.when.true comparison requires a string literal.`);return this.index+=1,e.value}consumeOperator(e){let t=this.peek();return t?.type!==`operator`||t.value!==e?!1:(this.index+=1,!0)}consumeParen(e){let t=this.peek();return t?.type!==`paren`||t.value!==e?!1:(this.index+=1,!0)}peek(){return this.tokens[this.index]}};function Gt(e){switch(e.kind){case`runFlow`:return!(`include`in e);case`repeat`:case`retry`:return!(`commands`in e);default:return!1}}function Kt(e,t){return{...P(e,t),source:e.source}}function M(e,n,r){if(e===void 0)return;let i=r??Je[n]??{},a=Qe(i),o;if(typeof e==`number`)o=e;else{let r=e.trim();if(r===``)throw new t(`INVALID_ARGS`,`Maestro ${n} must be ${a}.`);o=Number(r)}if(!Number.isFinite(o)||Math.abs(o)>2**53-1||i.integer&&!Number.isSafeInteger(o)||i.nonNegative&&o<0||i.positive&&o<=0)throw new t(`INVALID_ARGS`,`Maestro ${n} must be ${a}.`);return o}function qt(e,t,n,r){return M(e===void 0?t:n.resolve(String(e)),r)}function N(t){if(t?.aborted)throw e()}async function Jt(e,n){if(e.include.kind===`commands`)return{kind:`program`,source:e.source,config:{},commands:e.include.commands};if(!n.loadProgram)throw new t(`INVALID_ARGS`,`Maestro file runFlow requires a program loader.`);return N(n.signal),n.signal?await n.loadProgram(e.include.path,e.source.path,n.signal):await n.loadProgram(e.include.path,e.source.path)}function Yt(e,t){if(e.include.kind===`file`)return O.resolve(t?O.dirname(t):process.cwd(),e.include.path)}function Xt(e){return e===void 0?void 0:O.resolve(e)}function Zt(e,n){let r=Yt(e,e.source.path);if(r&&n.has(r))throw new t(`INVALID_ARGS`,`Maestro runFlow cycle detected at ${r}.`);return r}function Qt(e,n,r,i){let a=e.include.kind===`file`?Xt(n.source.path):void 0,o=new Set([r,a].filter(e=>e!==void 0)),s=[...o].find(e=>i.has(e));if(s)throw new t(`INVALID_ARGS`,`Maestro runFlow cycle detected at ${s}.`);return o.forEach(e=>i.add(e)),o}function $t(e,t,n){return e.platform&&e.platform!==n.platform?!1:e.true===void 0?!0:typeof e.true==`boolean`?e.true:Ft(e.true,t,n.platform)}function en(e){return[...e.visible?[{kind:`visible`,selector:e.visible}]:[],...e.notVisible?[{kind:`notVisible`,selector:e.notVisible}]:[]]}function P(e,t){return typeof e==`string`?t.resolve(e):Array.isArray(e)?e.map(e=>P(e,t)):e&&typeof e==`object`?Object.fromEntries(Object.entries(e).map(([e,n])=>[e,P(n,t)])):e}async function tn(e,t){N(t.signal);let n=Xt(e.source.path),r={options:t,context:Ye(t.defaults,t.env),activeIncludePaths:new Set(n===void 0?[]:[n]),staticallyExecutedControls:0,staticallySkippedControls:0};return{steps:await nn(e,[],void 0,e.source.path,r),staticallyExecutedControls:r.staticallyExecutedControls,staticallySkippedControls:r.staticallySkippedControls}}async function nn(e,t,n,r,i){N(i.options.signal);let a=pn(t,e.config.env),o=e.config.appId??n,s=i.context.enter(e.config.env);try{let t=[...e.config.onFlowStart??[],...e.commands,...e.config.onFlowComplete??[]],n=[];for(let s of t)n.push(...await an(s,a,o,e.source.path??r,i));return n}finally{s()}}async function rn(e,t,n,r,i){let a=[];for(let o of e)a.push(...await an(o,t,n,r,i));return a}async function an(e,t,n,r,i){N(i.options.signal);let a=mn(e,r);switch(a.kind){case`runFlow`:{let e=sn(a,i);if(e===`omit`)return i.staticallySkippedControls+=1,[];let o=await on(a,t,n,r,i);return e===`flatten`?(i.staticallyExecutedControls+=1,o):[F(a,t,n,o)]}case`repeat`:return[F(a,t,n,await rn(a.commands,t,n,r,i))];case`retry`:return[F(a,t,n,await rn(a.commands,t,n,r,i))];default:return[dn(a,t,n)]}}async function on(e,t,n,r,i){let a=ln(e,i.context),o=Zt(a,i.activeIncludePaths),s=await Jt(a,i.options);N(i.options.signal);let c=Qt(a,s,o,i.activeIncludePaths),l=pn(t,e.env),u=i.context.enter(e.env);try{return await nn(s,l,n,s.source.path??e.source.path??r,i)}finally{u(),c.forEach(e=>i.activeIncludePaths.delete(e))}}function sn(e,t){let n=e.when;return n?n.platform!==void 0&&n.platform!==t.options.platform?`omit`:cn(n.true,t)||(n.visible||n.notVisible?`opaque`:`flatten`):`flatten`}function cn(e,t){if(e===!1)return`omit`;if(typeof e==`string`)return un(t.context.resolveDeferred(e))?`opaque`:Ft(e,t.context,t.options.platform)?void 0:`omit`}function ln(e,t){return e.include.kind===`file`?{...e,include:{...e.include,path:t.resolve(e.include.path)}}:e}function un(e){return/\$\{[A-Za-z_][A-Za-z0-9_.]*\}/.test(e)}function dn(e,t,n){return E({kind:`command`,command:e,source:e.source,scopes:t,appId:n})}function F(e,t,n,r){return E({kind:`opaque`,command:fn(e),source:e.source,scopes:t,body:r,appId:n})}function fn(e){switch(e.kind){case`runFlow`:return E({kind:e.kind,source:e.source,when:e.when,label:e.label,...e.include.kind===`file`?{includePath:e.include.path}:{}});case`repeat`:return{kind:e.kind,source:e.source,times:e.times};case`retry`:return E({kind:e.kind,source:e.source,maxRetries:e.maxRetries})}}function pn(e,t){return t===void 0?e:[...e,t]}function mn(e,t){return e.source.path||!t?e:{...e,source:{...e.source,path:t}}}async function hn(e,t={}){let{steps:n,staticallyExecutedControls:r,staticallySkippedControls:i}=await tn(e,t),a=gn(t.runtimeHints),o=E({kind:`maestroReplayPlan`,platform:t.platform,target:t.target,runtimeHints:a,initialStaticEnv:structuredClone({...t.defaults??{},...e.config.env??{},...t.env??{}}),steps:structuredClone(n),total:n.length,compatibility:{staticallyExecutedControls:r,staticallySkippedControls:i}}),s=Pt(o);return _n({...o,digest:s})}function gn(e){if(!e)return;let t=Object.entries(e).filter(e=>e[1]!==void 0);return t.length===0?void 0:Object.fromEntries(t)}function _n(e){if(!e||typeof e!=`object`||Object.isFrozen(e))return e;for(let t of Object.values(e))_n(t);return Object.freeze(e)}function vn(e,t={}){let{from:n,planDigest:r}=t;if(n===void 0&&r===void 0)return{allowed:!0,startIndex:0};if(n===void 0||r===void 0)return{allowed:!1,reason:`replay --from requires --plan-digest (and --plan-digest requires --from).`};if(!Number.isInteger(n)||n<1||n>e.total)return{allowed:!1,reason:`replay --from ${n} is out of range for a ${e.total}-step plan.`};if(r!==e.digest)return{allowed:!1,reason:`replay --plan-digest does not match the current plan digest.`};if(n===1)return{allowed:!0,startIndex:0};for(let t=0;t<n-1;t+=1){let n=e.steps[t];if(n.kind===`opaque`)return{allowed:!1,reason:`step ${t+1} is opaque runtime control flow (${n.command.kind}) and cannot be skipped safely.`};if(n.command.kind===`runScript`||n.command.kind===`evalScript`)return{allowed:!1,reason:`step ${t+1} (${n.command.kind}) can produce outputEnv values and cannot be skipped safely.`}}let i=e.steps[n-1];return i.kind===`opaque`?{allowed:!1,reason:`step ${n} is opaque runtime control flow (${i.command.kind}) and cannot be resumed into.`}:{allowed:!0,startIndex:n-1}}function yn(e,n={}){let r=vn(e,n);if(!r.allowed)throw new t(`INVALID_ARGS`,r.reason);return r.startIndex}function bn(e,n){if(!Number.isInteger(n)||n<0||n>e.total)throw new t(`INVALID_ARGS`,`Maestro replay startIndex ${n} is out of range for a ${e.total}-step plan.`);return n}const xn=`maestro-test-failure`;function I(e,n={}){return new t(`COMMAND_FAILED`,e,{...n,reason:xn})}function Sn(e){return e instanceof t&&e.code===`COMMAND_FAILED`&&e.details?.reason===xn}const Cn=new Set([``,`false`,`0`,`null`,`undefined`]);function wn(e){return typeof e==`boolean`?e:typeof e==`number`?e!==0&&!Number.isNaN(e):!Cn.has(e)}async function Tn(e,t){N(t.options.signal);try{return await Rn(e,t.context,async()=>await En(e,t))}catch(t){throw z(t,e)}}async function En(e,t){if(e.kind===`command`)return await Dn(e.command,e.appId,t);await Nn(e,t)}async function Dn(e,t,n){if(e.kind===`evalScript`)return await An(e,n);let r=Kt(e,n.context);try{return await jn(r,t,n)}catch(e){if(N(n.options.signal),kn(r)&&Sn(e)){n.warnings.push(On(r,e)),n.skipped+=1;return}throw zn(e,r)}}function On(e,n){let r=`${e.source.path?`${e.source.path}:`:``}line ${e.source.line}`,i=n instanceof t?n.message:String(n);return`Optional Maestro ${e.kind} skipped at ${r}: ${i}`}function kn(e){return`optional`in e&&e.optional===!0}async function An(e,n){let{evaluateMaestroEvalScript:r}=await import(`./engine-eval-script.js`);if(n.options.trustedScripts===!1)throw new t(`UNAUTHORIZED`,`Maestro evalScript is not permitted for flows received over the remote daemon surface: node:vm is not a security sandbox, so an untrusted expression can escape to the host.`);let i=await r(e.script,n.context.values);n.context.replaceOutput(i),n.executed+=1}async function jn(e,t,n){switch(e.kind){case`assertVisible`:await R({kind:`visible`,selector:e.target},n.timing.assertVisibleTimeoutMs,n),n.executed+=1;return;case`assertNotVisible`:await R({kind:`notVisible`,selector:e.target},n.timing.assertNotVisibleTimeoutMs,n),n.executed+=1;return;case`assertTrue`:if(!wn(e.condition))throw I(`Maestro assertTrue condition was falsy: ${JSON.stringify(e.condition)}`);n.executed+=1;return;case`extendedWaitUntil`:await R(Ln(e),M(e.timeout,`extendedWaitUntil.timeout`)??n.timing.extendedWaitUntilTimeoutMs,n),n.executed+=1;return;default:return await Mn(e,t,n)}}async function Mn(e,t,n){let r=E({command:e,env:n.context.values,appId:t===void 0?void 0:n.context.resolve(t),generation:n.context.generation,invalidateObservation:n.context.invalidateObservation,cachedObservation:n.context.observation,signal:n.options.signal}),i=await n.port.execute(r);return N(n.options.signal),i.observation&&n.context.recordObservation(i.observation),i.outputEnv&&n.context.merge(i.outputEnv),i.artifactPaths?.forEach(e=>n.artifacts.add(e)),n.executed+=1,i}async function Nn(e,t){let n=Kt(e.command,t.context);switch(n.kind){case`runFlow`:if(n.when&&!await Fn(n.when,t)){t.skipped+=1;return}t.executed+=1,await L(e.body,t);return;case`repeat`:{let r=qt(n.times,0,t.context,`repeat.times`);t.executed+=1;for(let n=0;n<r;n+=1)N(t.options.signal),await L(e.body,t);return}case`retry`:{let r=Math.min(qt(n.maxRetries,1,t.context,`retry.maxRetries`),et.control.retryMaxRetries);t.executed+=1,await Pn(e.body,r,t);return}}}async function L(e,t){for(let n of e)await Tn(n,t)}async function Pn(e,n,r){let i;for(let t=0;t<=n;t+=1){N(r.options.signal);try{await L(e,r);return}catch(t){if(N(r.options.signal),!Sn(Vn(t)))throw t;i=z(t,e[0])}}throw i||new t(`COMMAND_FAILED`,`Maestro retry commands failed.`)}async function Fn(e,t){if(!$t(e,t.context,t.options))return!1;for(let n of en(e))if(N(t.options.signal),!(await In(n,t.timing.runFlowConditionTimeoutMs,t)).matched)return!1;return!0}async function R(e,t,n){if(!(await In(e,t,n)).matched)throw I(`Maestro ${e.kind} condition did not match.`)}async function In(e,t,n){let r={condition:e,timeoutMs:t,generation:n.context.generation,env:n.context.values,...n.context.observation?{cachedObservation:n.context.observation}:{},...n.options.signal?{signal:n.options.signal}:{}},i=await n.port.observe(r);return N(n.options.signal),n.context.recordObservation(i),i}function Ln(e){if(e.visible)return{kind:`visible`,selector:e.visible};if(e.notVisible)return{kind:`notVisible`,selector:e.notVisible};throw new t(`INVALID_ARGS`,`Maestro extendedWaitUntil requires one condition.`)}async function Rn(e,t,n){let r=e.scopes.map(e=>t.enter({...e}));try{return await n()}finally{for(let e=r.length-1;e>=0;--e)r[e]()}}function z(e,t){if(Bn(e))return e;let n=t?.source??{line:1};return{kind:`maestroPlanStepFailure`,error:Hn(e,t?.command),source:n,...t?{command:t.command}:{}}}function zn(e,t){return{kind:`maestroPlanStepFailure`,error:Hn(e,t),source:t.source,command:t}}function Bn(e){return!!(e&&typeof e==`object`&&e.kind===`maestroPlanStepFailure`)}function Vn(e){return Bn(e)?e.error:e}function Hn(e,n){if(!(e instanceof t)||!n||/\bline \d+\b/.test(e.message))return e;let r=n.source.path?`${n.source.path}:`:``;return new t(e.code,`${e.message} (${r}line ${n.source.line})`,e.details)}async function Un(e,n,r={}){N(r.signal);let i=r.startIndex??0;if(!Number.isInteger(i)||i<0||i>e.total)throw new t(`INVALID_ARGS`,`Maestro replay startIndex ${i} is out of range for a ${e.total}-step plan.`);let a={plan:e,port:n,options:r,context:Ye(r.defaults,r.env?{...r.env}:{}),timing:tt,artifacts:new Set,warnings:[],executed:e.compatibility.staticallyExecutedControls,skipped:e.compatibility.staticallySkippedControls};for(let t=i;t<e.steps.length;t+=1)try{await Wn(e.steps[t],t,a)}catch(e){throw Vn(e)}return{executed:a.executed,skipped:a.skipped,generation:a.context.generation,artifactPaths:[...a.artifacts],...a.warnings.length>0?{warnings:a.warnings}:{}}}async function Wn(e,t,n){N(n.options.signal);let r=n.options.now??Date.now,i=r(),a=n.port.readMetrics?.(),o=n.context.generation,s={command:e.command,source:e.source,generation:o,stepIndex:t+1,stepTotal:n.plan.total};B(()=>n.options.observer?.commandStarted?.(s));try{let t=await Tn(e,n);N(n.options.signal),B(()=>n.options.observer?.commandCompleted?.({...s,durationMs:r()-i,...Gn(a,n.port.readMetrics?.()),...t?.data?{data:t.data}:{}}))}catch(t){let o=z(t,e);throw B(()=>n.options.observer?.commandFailed?.({...s,...o.command?{command:o.command}:{},source:o.source,durationMs:r()-i,...Gn(a,n.port.readMetrics?.()),error:o.error,artifactPaths:[...n.artifacts],warnings:[...n.warnings]})),o}}function Gn(e,t){return!e||!t?{}:{runtimeMetrics:{hierarchyCaptures:t.hierarchyCaptures-e.hierarchyCaptures,screenshotCaptures:t.screenshotCaptures-e.screenshotCaptures,tapRetries:t.tapRetries-e.tapRetries,settleLatches:t.settleLatches-e.settleLatches,settleTimeouts:t.settleTimeouts-e.settleTimeouts}}}function B(e){try{e?.()}catch{}}async function Kn(e,t,n={}){let r=qn(e,n);return await Un(e,t,{...n,startIndex:r})}function qn(e,t){return t.from!==void 0||t.planDigest!==void 0?yn(e,{from:t.from,planDigest:t.planDigest}):bn(e,t.startIndex??0)}function Jn(e){return Gt(e)?{command:e.kind,...e.kind===`runFlow`?H(e.label??e.includePath):{}}:{command:e.kind,...Yn(e)}}function Yn(e){return`label`in e&&e.label?H(e.label):Xn(e)?H(rr(e.target)):Zn(e)?Qn(e):e.kind===`inputText`?H(`<text>`):$n(e)}function Xn(e){return e.kind===`tapOn`||e.kind===`doubleTapOn`||e.kind===`longPressOn`}function Zn(e){return e.kind===`assertVisible`||e.kind===`assertNotVisible`||e.kind===`extendedWaitUntil`||e.kind===`scrollUntilVisible`}function Qn(e){switch(e.kind){case`assertVisible`:case`assertNotVisible`:return H(V(e.target));case`extendedWaitUntil`:return H(V(e.visible??e.notVisible));case`scrollUntilVisible`:return H(V(e.element))}}function $n(e){return er(e)?tr(e):e.kind===`swipe`?nr(e):e.kind===`runFlow`?H(e.label??(e.include.kind===`file`?e.include.path:``)):e.kind===`assertTrue`?H(String(e.condition)):{}}function er(e){return e.kind===`openLink`||e.kind===`takeScreenshot`||e.kind===`runScript`||e.kind===`pressKey`}function tr(e){switch(e.kind){case`openLink`:return H(e.link);case`takeScreenshot`:return H(e.path);case`runScript`:return H(e.file);case`pressKey`:return H(e.key)}}function nr(e){return H(e.gesture.kind===`coordinates`?`${ir(e.gesture.start)} to ${ir(e.gesture.end)}`:e.gesture.direction)}function rr(e){return e.space===`target`?V(e.selector):`${e.x},${e.y}${e.space===`percent`?`%`:``}`}function V(e){return e?.id??e?.text}function ir(e){return`${e.x},${e.y}${e.space===`percent`?`%`:``}`}function H(e){return e?{value:e}:{}}const ar=new Set(String.raw`^$\.*+?()[]{}|`);function or(e,t){try{return RegExp(`^(?:${t})$`,`ims`).test(e)}catch{return e.toLocaleLowerCase()===t.toLocaleLowerCase()}}function sr(e){try{new RegExp(e)}catch{return e}let t=``;for(let n=0;n<e.length;n+=1){let r=e[n];if(r!==`\\`){if(ar.has(r))return;t+=r;continue}let i=e[n+1];if(i===void 0||!ar.has(i))return;t+=i,n+=1}return t}function cr(e,t,n){if(n===`android`&&e.visibleToUser===!1)return!1;if(g(e.rect))return t.isVisibleInEffectiveViewport(e);if(e.rect)return!1;if(n!==`android`&&e.hittable===!0)return!0;let r=t.findAncestor(e,e=>h(e,n)?e:null);return r?g(r.rect)?t.isVisibleInEffectiveViewport(r):n!==`android`&&r.hittable===!0:!1}function lr(e,t,n){return!!n.findAncestor(e,e=>e.index===t.index?e:null)}function ur(e,t){let n=[t.id===void 0?void 0:fr(e.identifier,t.id),t.text===void 0?void 0:pr(e,t.text)].filter(e=>e!==void 0);return!(n.length===0&&t.enabled===void 0&&t.selected===void 0||n.some(e=>!e)||t.enabled!==void 0&&e.enabled!==!1!==t.enabled||t.selected!==void 0&&e.selected===!0!==t.selected)}function dr(e){return e.matches.filter(t=>cr(t,e.visibility,e.platform))}function fr(e,t){let n=e??``;return D(n)===D(t)||or(n,t)}function pr(e,t){return[e.label,Xe(e),e.identifier].filter(e=>!!e).some(e=>fr(e,t))}function mr(e){return e.index!==void 0||e.childOf!==void 0||e.below!==void 0||e.above!==void 0||e.leftOf!==void 0||e.rightOf!==void 0||e.containsChild!==void 0||e.containsDescendants!==void 0}function hr(e){return e.text!==void 0||e.id!==void 0||e.enabled!==void 0||e.selected!==void 0}function gr(e,t,n){let r=[],i=0;for(let a of e)for(let e of n){let n=vr(a.rect,e.rect);n===void 0||!_r(t,a.rect,e.rect)||r.push({node:a,distance:n,order:i++})}return r.sort((e,t)=>e.distance-t.distance||e.order-t.order),r.map(({node:e})=>e)}function _r(e,t,n){switch(e){case`below`:return t.y>n.y;case`above`:return t.y<n.y;case`leftOf`:return t.x<n.x;case`rightOf`:return t.x>n.x}}function vr(e,t){if(!(!yr(e)||!yr(t)))return Math.fround(Math.hypot(U(e.x,e.width)-U(t.x,t.width),U(e.y,e.height)-U(t.y,t.height)))}function yr(e){return!!(e&&[e.x,e.y,e.width,e.height].every(Number.isFinite))}function U(e,t){return e+Math.trunc(t/2)}function br(e,n={},r={}){let i=ee(e.nodes,n);n.onVisibilityContextCreated?.();let a=new WeakMap,o=new WeakSet,s=new WeakMap,c=new Map,l=t=>t.parentIndex===void 0?void 0:i.nodeByIndex.get(t.parentIndex)??e.nodes[t.parentIndex],u=e=>{let t=s.get(e);if(t)return t;let n=new Set,r=new Set,i=l(e);for(;i&&!r.has(i.index);)r.add(i.index),n.add(i.index),i=l(i);return s.set(e,n),n},d=(t,r)=>{let i=c.get(t);i||(i=new WeakMap,c.set(t,i));let a=i.get(r);if(a)return a;n.onPositionComputed?.(t,r);let o=gr(e.nodes,t,m(r).indexed),s={ordered:o,candidateIndexes:new Set(o.map(e=>e.index))};return i.set(r,s),s},f=(e,t)=>d(e,t).ordered,p=(e,t)=>d(e,t).candidateIndexes,m=i=>{let s=a.get(i);if(s)return s;if(o.has(i))throw new t(`INVALID_ARGS`,`Maestro selector relations cannot contain cycles.`);o.add(i),n.onSelectorComputed?.(i);try{let t=xr(e,i,l,u,m,p),n={matches:t,indexed:Tr(t,i.index,r.orderUnindexed)};return a.set(i,n),n}finally{o.delete(i)}};return{visibility:i,resolve:m,resolvePosition:f}}function xr(e,t,n,r,i,a){let{index:o,childOf:s,below:c,above:l,leftOf:u,rightOf:d,containsChild:f,containsDescendants:p,...m}=t,h=hr(m)?e.nodes.filter(e=>ur(e,m)):[...e.nodes];if(s){let e=new Set(i(s).indexed.map(e=>e.index));h=h.filter(t=>Cr(r(t),e))}if(f){let e=new Set(i(f).indexed.map(n).filter(e=>e!==void 0).map(e=>e.index));h=h.filter(t=>e.has(t.index))}if(p){let e=p.map(e=>Sr(i(e).indexed,r));h=h.filter(t=>e.every(e=>e.has(t.index)))}for(let[e,n]of wr(t)){let t=a(e,n);h=h.filter(e=>t.has(e.index))}return h}function Sr(e,t){let n=new Set;for(let r of e)for(let e of t(r))n.add(e);return n}function Cr(e,t){for(let n of e)if(t.has(n))return!0;return!1}function wr(e){return[[`below`,e.below],[`above`,e.above],[`leftOf`,e.leftOf],[`rightOf`,e.rightOf]].filter(e=>e[1]!==void 0)}function Tr(e,t,n){if(t===void 0)return n?n(e):[...e];let r=Dr(e)[Or(t)];return r?[r]:[]}function Er(e,t){return t===void 0?e[0]:Dr(e)[Or(t)]}function Dr(e){return[...e].sort((e,t)=>{let n=W(e.rect?.y),r=W(t.rect?.y);return n===r?W(e.rect?.x)-W(t.rect?.x):n-r})}function W(e){return e!==void 0&&Number.isFinite(e)?e:2**53-1}function Or(e){let n=typeof e==`number`?e:Number(e.trim());if(!Number.isSafeInteger(n)||n<0)throw new t(`INVALID_ARGS`,`Maestro selector.index must be a non-negative integer.`);return n}const kr={android:{kind:`exact`,provider:`android-helper`},ios:{kind:`divergence`,provider:`apple-xctest`,reason:`maestro-clickable-not-exposed-by-provider`}};function Ar(e,t){let n=kr[t];if(n.kind===`divergence`)return n;let r=s(e);return r?r.kind!==`exact`||r.provider!==n.provider?{kind:`divergence`,provider:n.provider,reason:`unregistered-provider-evidence`}:r:{kind:`divergence`,provider:n.provider,reason:`exact-evidence-not-retained`}}function G(e,t){return t.kind===`exact`?e.map((e,n)=>({node:e,order:n,rank:jr(t.clickableByNodeIndex.get(e.index))})).sort((e,t)=>t.rank-e.rank||e.order-t.order).map(({node:e})=>e):[...e]}function jr(e){return e===!0?2:+(e===!1)}function Mr(e,t,n,r={}){let i=Ar(e,n),a=Pr(e,i,r),o=Nr(t,a),s=dr({visibility:a.visibility,matches:o.matches,platform:n});return{...o,visible:s,clickability:i,ranked:Fr(s,t,n,a.visibility,i)}}function Nr(e,t){return{matches:t.resolve(e).matches,parentMatched:e.childOf===void 0||t.resolve(e.childOf).indexed.length>0}}function Pr(e,t,n={}){return br(e,n,t?{orderUnindexed:e=>G(e,t)}:{})}function Fr(e,t,n,r,i){let a=n!==`ios`||!zr(t)?e:e.filter(n=>{if(Hr(n))return!0;let i=e.filter(e=>e!==n&&Br(n,e,t));return!i.some(e=>Hr(e)&&lr(n,e,r))&&!i.some(e=>lr(e,n,r))});return t.index===void 0&&i?G(a,i):a}function Ir(e,t){let n=t===void 0?e.find(K):Lr(e,t);return!n||!K(n)?null:{node:n,rect:n.rect}}function Lr(e,t){return Er(e,t)}function Rr(e){return K(e)?e.rect:void 0}function K(e){return g(e.rect)}function zr(e){return e.id!==void 0||e.text!==void 0}function Br(e,t,n){if(n.id!==void 0&&q(e.identifier)!==q(t.identifier))return!1;if(n.text!==void 0){let n=Vr(e),r=new Set(Vr(t));if(!n.some(e=>r.has(e)))return!1}return!0}function Vr(e){return[e.label,e.value,e.identifier].map(q).filter(e=>e!==void 0)}function q(e){if(e)return D(e)||void 0}function Hr(e){let t=te(e.type??``);return t===`button`||t===`link`||t===`switch`||t===`searchfield`||t===`textfield`||t===`securetextfield`||t===`textview`}const Ur=Symbol(`maestroFlowProgram`),Wr=Symbol(`maestroFailureCommand`),Gr=Symbol(`maestroFailurePlan`);function Kr(e,t){let n=$e(e,{sourcePath:t});return{sourcePath:t,name:n.config.name,appTarget:Xr(n),[Ur]:n}}async function qr(e,t,n){let r;try{let i=Ze(O.dirname(e.sourcePath),n.readSource),a=await hn(e[Ur],{defaults:n.defaults,env:n.env,platform:n.platform,target:n.target,runtimeHints:n.runtimeHints,loadProgram:i,signal:n.signal}),o=yn(a,{from:n.from,planDigest:n.planDigest}),s=await Kn(a,t,{defaults:n.defaults,env:n.env,platform:n.platform,target:n.target,loadProgram:i,signal:n.signal,startIndex:o,trustedScripts:n.trustedScripts,observer:Yr(a,n.observer,e=>{r=e})});return{ok:!0,replayed:a.total-o,planDigest:a.digest,startIndex:o,artifactPaths:s.artifactPaths,...s.warnings?{warnings:s.warnings}:{}}}catch(e){return{ok:!1,error:r?.error??e,...r?{failure:r}:{}}}}function Jr(e,t){let n=Qr(e[Wr]),r=e[Gr].platform;return!n||r!==`android`&&r!==`ios`?[]:Mr(t,n.selector,r).ranked.map(e=>({node:e,basis:$r(n.selector,e)}))}function Yr(e,t,n){return{commandStarted:e=>t?.actionStarted?.(J(e)),commandCompleted:e=>t?.actionCompleted?.({...J(e),durationMs:e.durationMs,runtimeMetrics:e.runtimeMetrics,data:e.data}),commandFailed:r=>{let i=vn(e,{from:r.stepIndex,planDigest:e.digest}),a={...J(r),durationMs:r.durationMs,error:r.error,artifactPaths:r.artifactPaths,warnings:[...r.warnings],isControl:Gt(r.command),redactions:r.command.kind===`inputText`&&r.command.text.length>0?[{name:`inputText.text`,value:r.command.text}]:[],resume:i.allowed?{allowed:!0,from:r.stepIndex,planDigest:e.digest}:{allowed:!1,from:r.stepIndex,planDigest:e.digest,reason:i.reason},[Wr]:r.command,[Gr]:e};n(a),t?.actionFailed?.(a)}}}function J(e){let t=Jn(e.command);return{action:t.command,...t.value?{value:t.value}:{},source:e.source,generation:e.generation,stepIndex:e.stepIndex,stepTotal:e.stepTotal}}function Xr(e){return[e.config.appId,...[...e.config.onFlowStart??[],...e.commands].filter(e=>e.kind===`launchApp`).map(e=>e.kind===`launchApp`?e.appId:void 0)].find(Zr)}function Zr(e){return!!(e?.trim()&&!e.includes(`$`)&&!a(e))}function Qr(e){switch(e.kind){case`tapOn`:return e.target.space===`target`?{selector:e.target.selector}:void 0;case`doubleTapOn`:case`longPressOn`:return e.target.space===`target`?{selector:e.target.selector}:void 0;case`assertVisible`:case`assertNotVisible`:return{selector:e.target};case`extendedWaitUntil`:return e.visible?{selector:e.visible}:e.notVisible?{selector:e.notVisible}:void 0;case`scrollUntilVisible`:return{selector:e.element};case`swipe`:return e.gesture.kind===`target`?{selector:e.gesture.from}:void 0;default:return}}function $r(e,t){return e.id!==void 0||e.text!==void 0&&ur({...t,label:void 0,value:void 0},{text:e.text})?`id`:e.text===void 0?`other`:`label`}const ei=`This replay request carries no script sources. Replay scripts are read by the client and sent with the request; upgrade the agent-device client that issued it to a version that sends script sources.`;function ti(e,n){let r=e.files[n];if(r===void 0)throw new t(`INVALID_ARGS`,`replay script source is missing ${n}; it was not part of the script sources sent with this request.`,{path:n,entry:e.entry});return r}function ni(e){let t=ae(e);for(let n of e){if(n.command!==`open`)continue;let e=n.positionals?.[0];return ai(e)?{appTarget:e,platform:t}:{appTarget:void 0,platform:t}}return{appTarget:void 0,platform:t}}function ri(e,t){return t===`ios`?oi(e)??{}:{}}function ii(e,t){let n=ni(t);return e?.platform!==void 0||!n.platform?e??{}:{...e,platform:n.platform}}function ai(e){return!!(e&&e.trim()&&!e.includes(`$`)&&!a(e))}function oi(e){let t=jt(e);return t?{appleSimulatorAppTarget:t}:void 0}function si(e){let n=e.flags??{};if(n.waitMs===void 0)return;let[r]=oe(`waitMs`);if(!r)throw new t(`INTERNAL_ERROR`,`The waitMs option has no flag declaration whose bounds the daemon can enforce.`);return o(n,`waitMs`,{min:r.min,max:r.max})}function ci(e){let t=e.internal?.openDeviceWait?.waitedMs;return t===void 0?{}:{waitedMs:t}}function li(e){return{...ci(e),offersDeviceWait:e.command===`open`&&typeof e.flags?.waitMs!=`number`}}function ui(e){let{req:t,budgetMs:n,sessionName:r,sessionStore:i,deviceId:a}=e;if(t.command===`open`&&n!==void 0&&!(a===void 0||i.get(r)))return fi({req:t,sessionName:r,sessionStore:i,deviceId:a,budgetMs:n})}function di(e,t,n){let r=e.findByDevice(t);if(!(!r||r.address===n))return r}function fi(e){let{req:t,sessionName:n,sessionStore:r,deviceId:i,budgetMs:a}=e,o=le.fromTimeoutMs(a),s=()=>di(r,i,n),c=async()=>{for(;;){let e=s();if(!e||o.isExpired())return;Te({type:`command`,status:`progress`,message:`Waiting for ${e.session.device.name}: held by session "${e.address}" (${Math.round(o.elapsedMs())}ms of the ${Math.round(a)}ms wait budget used)`}),await se(Math.min(250,o.remainingMs())),we(t.meta?.requestId)}};return{waitForDeviceOutsideLocks:c,runWhenDeviceIsUnheld:async e=>{let{acquireLocks:n,task:r}=e;for(;;){let e=await n(async()=>{if(s()){if(!o.isExpired())return{ran:!1};pi(t,o.elapsedMs())}return{ran:!0,outcome:await r()}});if(e.ran)return e.outcome;await c()}}}}function pi(e,t){if(t<=0)return;let n=e.internal??={};n.openDeviceWait={waitedMs:t}}const mi={label:`Materialized paths`,plural:!0,expiredHint:`Materialized paths are released automatically when their TTL expires; re-run the command that materialized them if the paths are still needed.`},Y=new Map;async function hi(e){let t=await k.mkdtemp(O.join(at.tmpdir(),`agent-device-materialized-`));try{let n=await yi(e.installablePath,O.join(t,`installable`)),r=e.archivePath?await yi(e.archivePath,O.join(t,`archive`)):void 0,i=rt.randomUUID(),a=e.ttlMs??9e5,o=Date.now()+a,s=setTimeout(()=>{vi(i)},a);return Y.set(i,{rootPath:t,installablePath:n,archivePath:r,tenantId:e.tenantId,sessionName:e.sessionName,expiresAt:o,timer:s}),{materializationId:i,installablePath:n,...r?{archivePath:r}:{},expiresAt:new Date(o).toISOString()}}catch(e){throw await k.rm(t,{recursive:!0,force:!0}),e}}async function gi(e,t){await X(e,Oe(Y,e,t,mi))}async function _i(e){let t=Array.from(Y.entries()).filter(([,t])=>t.sessionName===e);await Promise.all(t.map(async([e,t])=>{await X(e,t)}))}async function vi(e){let t=Y.get(e);if(t)try{await X(e,t)}catch{}}async function X(e,t){clearTimeout(t.timer),Y.delete(e),await k.rm(t.rootPath,{recursive:!0,force:!0})}async function yi(e,t){let n=await k.stat(e);await k.mkdir(t,{recursive:!0});let r=O.join(t,O.basename(e));return n.isDirectory()?(await k.cp(e,r,{recursive:!0}),r):(await k.copyFile(e,r),r)}function bi(e){return e.device.platform===`web`}function xi(e){return e.toArray().filter(e=>e.device.platform===`web`).map(e=>e.name)}async function Si(e){let{session:t,sessionName:n,sessionStore:r}=e;t.appLog&&await Be({session:t,sessionName:n,sessionStore:r,resourcePath:Re.resolvePath(r.resolveSessionDir(n))})}async function Ci(e){let t=e.sessionStore.get(e.sessionName)??e.session;t.perfCapture&&await ze({...e,session:t,intent:`disposal`})}async function wi(e,t){await t.stopSnapshotHelper(e.device)}async function Ti(e){let{session:t,sessionName:n,sessionStore:r,platformCleanup:i}=e;await i.closeManagedBrowser({device:t.device,sessionName:n,stateDir:r.resolveDaemonStateDir(),openSessionNames:()=>xi(r)})}async function Ei(e){let t=[];for(let{step:n,run:r}of e)try{await r()}catch(e){t.push({step:n,error:e})}return t}function Di(e){if(e.failures.length===0)return;let n=e.failures.map(({step:e})=>e),r=e.failures.map(({step:e,error:t})=>`${e}: ${t instanceof Error?t.message:String(t)}`);return v({level:`error`,phase:e.phase,data:{session:e.sessionName,failedSteps:n,errors:r}}),new t(`COMMAND_FAILED`,`Session cleanup left ${e.failures.length} resource(s) unreleased: ${r.join(`; `)}`,{reason:`session_cleanup_incomplete`,session:e.sessionName,failedSteps:n,hint:`Some session resources failed to release; inspect the session log for per-resource diagnostics. The session was still deleted, so retrying is safe.`})}async function Oi(e){let{session:n,sessionName:r,sessionStore:i}=e;if(!e.platformCleanup)throw new t(`INTERNAL_ERROR`,`Platform resource cleanup was not supplied by root runtime composition`);let a=e.platformCleanup,o=[{step:`recording`,run:()=>ki({session:n,sessionName:r,sessionStore:i})},...e.appLog===`run`?[{step:`app_log`,run:()=>Si({session:n,sessionName:r,sessionStore:i})}]:[],{step:`audio_probe`,run:()=>Ai({session:n,sessionName:r,sessionStore:i})},{step:`perf_capture`,run:()=>Ci({session:n,sessionName:r,sessionStore:i})},{step:`platform_snapshot_helper`,run:()=>wi(n,a)},{step:`web_browser`,run:()=>Ti({session:n,sessionName:r,sessionStore:i,platformCleanup:a})}];o.push({step:`materialized_paths`,run:()=>_i(r)});let s=Di({sessionName:r,phase:`session_teardown_cleanup_failed`,failures:await Ei(o)});if(s)throw s}async function ki(e){let t=e.sessionStore.get(e.sessionName)??e.session;t.screenRecording&&await nt({intent:`disposal`,session:t,sessionName:e.sessionName,sessionStore:e.sessionStore})}async function Ai(e){let t=e.sessionStore.get(e.sessionName)??e.session;t.audioProbe&&await Le({intent:`disposal`,session:t,sessionName:e.sessionName,sessionStore:e.sessionStore})}function ji(e){return d(e)&&e.kind===`simulator`}function Mi(e){return e.platform===`android`&&e.kind===`emulator`}const Ni=[`platform`,`metroHost`,`metroPort`,`bundleUrl`,`launchUrl`];function Z(e){return e?[e.metroHost,e.metroPort,e.bundleUrl,e.launchUrl].filter(e=>e!==void 0&&e!==``).length:0}function Q(e){if(!e)return{};let t={};return e.metroHost!==void 0&&(t.metroHost=e.metroHost),e.metroPort!==void 0&&(t.metroPort=String(e.metroPort)),e.bundleUrl!==void 0&&(t.bundleUrl=e.bundleUrl),e.launchUrl!==void 0&&(t.launchUrl=e.launchUrl),t}function $(e){return ke(Q(e))}function Pi(e,n){if(e!==void 0){if(typeof e!=`string`)throw new t(`INVALID_ARGS`,`Invalid open runtime ${n}: expected string.`);return y(e)}}function Fi(e){if(e!==void 0){if(!Number.isInteger(e)||e<1||e>65535)throw new t(`INVALID_ARGS`,`Invalid runtime metroPort: ${String(e)}. Use an integer between 1 and 65535.`);return e}}function Ii(e){if(e!==void 0){if(typeof e!=`number`)throw new t(`INVALID_ARGS`,`Invalid open runtime metroPort: expected integer.`);return Fi(e)}}function Li(e,n,i){if(e===void 0)return i;if(!r(e))throw new t(`INVALID_ARGS`,`Invalid open runtime platform: ${String(e)}. Use "ios", "android", or "harmonyos".`);if(i&&e!==i)throw new t(`INVALID_ARGS`,`open runtime targets ${e}, but session "${n}" is bound to ${i}.`);return e}function Ri(e){if(r(e))return e}function zi(e,t){return{platform:t,metroHost:y(e?.metroHost),metroPort:Fi(e?.metroPort),bundleUrl:y(e?.bundleUrl),launchUrl:y(e?.launchUrl)}}function Bi(e,t){return{platform:t.platform??e?.platform,metroHost:t.metroHost??e?.metroHost,metroPort:t.metroPort??e?.metroPort,bundleUrl:t.bundleUrl??e?.bundleUrl,launchUrl:t.launchUrl??e?.launchUrl}}function Vi(e){if(Mi(e))return`10.0.2.2`;if(ji(e))return`127.0.0.1`}function Hi(e,t){if(!e||y(e.metroHost)||y(e.bundleUrl)||e.metroPort===void 0)return e;let n=Vi(t);return n?{...e,metroHost:n}:e}function Ui(e){let{runtime:n,sessionName:r,platform:i}=e;if(n===void 0)return;if(!n||typeof n!=`object`||Array.isArray(n))throw new t(`INVALID_ARGS`,`open runtime must be an object.`);let a=n,o=Object.keys(a).find(e=>!Ni.includes(e));if(o)throw new t(`INVALID_ARGS`,`Invalid open runtime field: ${o}. Supported fields are ${Ni.join(`, `)}.`);return{platform:Li(a.platform,r,i),metroHost:Pi(a.metroHost,`metroHost`),metroPort:Ii(a.metroPort),bundleUrl:Pi(a.bundleUrl,`bundleUrl`),launchUrl:Pi(a.launchUrl,`launchUrl`)}}function Wi(e,t,n){if(n){if(Z(n)===0){e.clearRuntimeHints(t);return}return e.setRuntimeHints(t,n),n}}function Gi(e,n,r,i){let a=e.getRuntimeHints(n);if(!a)return;let o=r?c(r):void 0,s=Ri(o)??i;if(a.platform&&r&&!s)throw new t(`INVALID_ARGS`,`Session runtime hints are only supported on iOS, Android, and HarmonyOS sessions, but session "${n}" is bound to ${o}.`);if(a.platform&&s&&a.platform!==s)throw new t(`INVALID_ARGS`,`Session runtime hints target ${a.platform}, but session "${n}" is bound to ${o}. Clear the runtime hints or use a different session.`);return s&&a.platform!==s?{...a,platform:s}:a}function Ki(e){let{req:t,sessionStore:n,sessionName:r,device:i}=e,a=i?Ri(c(i)):e.platform,o=n.getRuntimeHints(r),s=Ui({runtime:t.runtime,sessionName:r,platform:a});if(t.runtime===void 0){let e=Gi(n,r,i,a);return{runtime:i?Hi(e,i):e,previousRuntime:o,replacedStoredRuntime:!1}}let l=s&&Z(s)>0?s:void 0;return{runtime:i?Hi(l,i):l,previousRuntime:o,replacedStoredRuntime:!0}}function qi(e){return Ki(e).runtime}function Ji(e){try{return{ok:!0,data:Ki(e)}}catch(e){let t=n(e);return i(t.code,t.message,t.details)}}async function Yi(e){let{previousRuntime:t,clearRuntimeHints:n}=e;if(!Xi(e))return;let r=e.session;r?.appBundleId&&await n({appId:r.appBundleId,values:Q(t)})}function Xi(e){return e.replacedStoredRuntime&&!!e.session?.appBundleId&&$(e.previousRuntime)&&!$(e.runtime)}function Zi(e){let{device:t,owner:n,stateDir:r,intent:i}=e,a=i.kind===`exact-owner`&&ie(i.owner,n)?ne(i.fence):null;if(!a)return{status:`binding-invalid`};let o=w(T(t)),s=Pe(je(o));if(!s)return{status:`missing`};let c=s.allocatorClaim;return!c||!$i(c.stateDir,r)||!ie(Ne(c),n)?{status:`conflict`,conflict:s}:c.allocator.identityIncarnationId===a.identityIncarnationId?{status:`covered`}:{status:`incarnation-stale`,heldIncarnationId:c.allocator.identityIncarnationId}}function Qi(e){let t=w(T(e));return Ae(je(t))}function $i(e,t){return O.resolve(e)===O.resolve(t)}function ea(e,t,n=`status`){let r=t.claim??t.allocatorClaim,i=c(r?{platform:r.device.family,appleOs:r.device.appleOs}:e),a=l(e.platform)?`--udid`:`--serial`;return[`agent-device device ${n}`,`--platform ${ce(i)}`,`${a} ${ce(e.id)}`,...n===`release`||Me(t.classification)?[`--stale`]:[]].join(` `)}function ta(e,n){if(n.classification===`allocator-held`)return ra(e,n);let r=n.claim,i=ea(e,n,Fe(n.classification)?`release`:`status`),a=c(r?{platform:r.device.family,appleOs:r.device.appleOs}:e);return new t(`DEVICE_IN_USE`,r?`${a} device ${e.id} is owned by session "${r.session}" in workspace "${r.workspace}".`:`${e.name} has an ownership claim that could not be verified.`,{reason:ua(n.classification),classification:n.classification,deviceKey:n.deviceKey,...r?{owner:{session:r.session,workspace:r.workspace,stateDir:r.stateDir}}:{},recovery:{command:i},hint:Fe(n.classification)?`The recorded owner can no longer release this device; settle its resources and release the claim with: ${i}`:`Inspect the owner with: ${i}`,retriable:!1})}function na(e,t){return la(ta(e,t))}function ra(e,n){let r=n.allocatorClaim,i=c({platform:r.device.family,appleOs:r.device.appleOs}),a=ea(e,n);return new t(`DEVICE_IN_USE`,`${i} device ${e.id} is held by managed-device allocator "${r.allocator.instanceId}" for installation "${r.stateDir}".`,{reason:`DEVICE_CLAIM_ALLOCATOR_HELD`,classification:n.classification,deviceKey:n.deviceKey,owner:{kind:`allocator`,stateDir:r.stateDir,allocator:r.allocator},recovery:{command:a},hint:`This device belongs to a managed pool and is released only after its allocator proves the identity removed; inspect with: ${a}`,retriable:!1})}function ia(e,n){return new t(`COMMAND_FAILED`,`${c(e)} device ${e.id} is a managed identity with no allocator-held execution claim for this installation.`,{reason:`allocator-claim-missing`,owner:_(n),deviceKey:w(T(e)),retriable:!1,hint:`A managed identity becomes executable only after its allocator activates it and this installation holds its allocator-held claim.`})}function aa(e,n,r){return new t(`COMMAND_FAILED`,`${c(e)} device ${e.id} is held for identity incarnation "${r}", which is not the incarnation this binding fences.`,{reason:`allocator-claim-incarnation-stale`,owner:_(n),deviceKey:w(T(e)),heldIncarnationId:r,retriable:!1,hint:`The managed identity was re-provisioned; obtain a new grant from the allocator.`})}function oa(e,n){return new t(`COMMAND_FAILED`,`A managed local owner executes only under an exact-owner binding that carries a managed binding fence.`,{reason:`runtime-contract-invalid`,owner:_(n),deviceKey:w(T(e)),retriable:!1})}function sa(e,t,n){switch(n.status){case`binding-invalid`:return{admitted:!1,error:oa(e,t)};case`missing`:return{admitted:!1,error:ia(e,t)};case`covered`:return{admitted:!0};case`incarnation-stale`:return{admitted:!1,error:aa(e,t,n.heldIncarnationId)};case`conflict`:return{admitted:!1,error:ta(e,n.conflict)}}}function ca(e,t,n){let r=sa(e,t,n);return r.admitted?void 0:la(r.error)}function la(e){let{hint:t,retriable:n,...r}=e.details??{};return i(e.code,e.message,r,{hint:t,retriable:n})}function ua(e){switch(e){case`live`:return`DEVICE_CLAIM_LIVE_OWNER`;case`owner-process-dead`:case`owner-daemon-superseded`:return`DEVICE_CLAIM_RECOVERY_PENDING`;case`owner-process-reused`:case`owner-state-dir-gone`:case`unknown`:case`inconsistent`:case`allocator-inconsistent`:return`DEVICE_CLAIM_OWNER_UNCERTAIN`}}function da(e){switch(e.kind){case`local-family`:return`ordinary`;case`managed-local`:return`allocator-held`;case`provider-runtime`:return`none`}}export{mr as $,hi as A,Jr as B,Ci as C,xi as D,bi as E,ri as F,Mr as G,Kr as H,ii as I,Lr as J,Fr as K,ni as L,li as M,si as N,gi as O,oi as P,br as Q,ei as R,Si as S,Oi as T,Pr as U,qr as V,Nr as W,G as X,Rr as Y,Ar as Z,Ri as _,xt as _t,ta as a,Nt as at,ki as b,st as bt,zi as c,Et as ct,Yi as d,Ot as dt,dr as et,Bi as f,bt as ft,Xi as g,St as gt,Wi as h,_t as ht,sa as i,M as it,ui as j,_i as k,Z as l,Tt as lt,Q as m,yt as mt,ca as n,sr as nt,Qi as o,Mt as ot,qi as p,vt as pt,Ir as q,na as r,I as rt,Zi as s,At as st,da as t,cr as tt,$ as u,Dt as ut,Ji as v,dt as vt,wi as w,Di as x,Ai as y,ut as yt,ti as z};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime.js";import{
|
|
1
|
+
import{r as e}from"./rolldown-runtime.js";import{G as t,N as n}from"./sdk-contracts.js";import{AsyncLocalStorage as r}from"node:async_hooks";var i=e({listDeviceInventory:()=>l,listLocalDeviceInventory:()=>d,readDeviceInventory:()=>u,readInstalledAppProbe:()=>c,shouldPropagateDeviceInventoryProbeError:()=>m,withDeviceInventoryContext:()=>s});const a=`device_inventory_context_unavailable`,o=new r;async function s(e,t){return await o.run(e,t)}function c(){return o.getStore()?.findInstalledApp}async function l(e){return await f(`providerFirst`,e)}async function u(e){let t=p(),n=await t.providerFirst.discoverWithSource(e,t.requestScope);return{devices:n.devices.map(e=>({...e})),source:n.source}}async function d(e){return await f(`localOnly`,e)}async function f(e,t){let n=p();return(await n[e].discover(t,n.requestScope)).map(e=>({...e}))}function p(){let e=o.getStore();if(!e)throw new n(`COMMAND_FAILED`,`Device inventory gateway is unavailable outside request execution`,{reason:a});return e}function m(e){return t(e)||e instanceof n&&e.code===`COMMAND_FAILED`&&e.details?.reason===a?!0:e instanceof Error&&e.name===`AbortError`}export{m as a,u as i,l as n,s as o,d as r,i as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{N as e}from"./sdk-contracts.js";import{i as t}from"./sdk-batch-runner.js";import{n}from"./app-inventory.js";import"./device.js";import{t as r}from"./request-cancellation.js";import{n as i,t as a}from"./ios-client.js";import{i as o}from"./snapshot.js";import s from"node:path";import c from"node:fs";import l from"node:os";import{setTimeout as u}from"node:timers/promises";function d(e){return e?.trim()||void 0}async function f(e,t){let n=await i({apiUrl:e.apiUrl,adbUrl:e.adbUrl,token:e.token,logLevel:`warn`}),r={platform:`android`,lease:e.lease,instanceId:e.instanceId,device:e.device,client:n,token:e.token,dependencies:t},a={exec:async(e,t)=>await v(r,e,t),text:async e=>{await n.setText(e.target,e.text)}};return a.reverse=await t.android.createPortReverse(a.exec),Object.assign(r,{adbProvider:a})}function p(e){return e.dependencies.android.createInteractor(e.device,e.adbProvider)}async function m(e,t,n,i,a,o){a?.throwIfAborted();let s=d(i?.packageNameHint);i?.relaunch&&s&&await t.dependencies.android.forceStopApp(async(e,n)=>await v(t,e,n),s,a);let c=await r(o,e.assets.getOrUpload({path:n,name:w(s,n)},{signal:a}),a);await r(o,t.client.sendAsset(c.signedDownloadUrl),a),a?.throwIfAborted();let l=s?await t.dependencies.android.inferAppName(s):void 0;return{...s?{packageName:s,launchTarget:s}:{},...l?{appName:l}:{}}}async function h(e,t){await e.adbProvider.reverse?.ensure({local:C(t.devicePort),remote:C(t.hostPort),ownerId:t.name})}async function g(e){await e.adbTunnelPromise?.catch(()=>{});let t=e.adbSerial;t&&(await _(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 _(e){let t=e.adbProvider.reverse;if(!t?.list)return;let n=await t.list().catch(()=>[]),r=new Set,i=[];for(let e of n)e.ownerId?r.add(e.ownerId):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 v(e,t,n){let{invocation:r,result:i}=await y(e,t,n);return await b(r,i,n?.allowFailure,e.dependencies)}async function y(e,t,n){let r=await x(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 b(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 x(e){if(e.adbSerial)return e.adbSerial;let t=e.adbTunnelPromise??S(e);e.adbTunnelPromise=t;try{return await t}catch(n){throw e.adbTunnelPromise===t&&(e.adbTunnelPromise=void 0),n}}async function S(e){let t=await e.client.startAdbTunnel(),n=`${t.address.address}:${t.address.port}`;return e.adbTunnel=t,e.adbSerial=n,n}function C(t){if(!Number.isInteger(t)||t<1||t>65535)throw new e(`INVALID_ARGS`,`Invalid Android tcp reverse port: ${t}`);return`tcp:${t}`}function w(e,t){let n=s.extname(t)||`.apk`;return`${e?.replaceAll(/[^a-zA-Z0-9_.-]+/g,`-`)||`android-app`}${n}`}async function T(e,t){let n=await a({apiUrl:e.apiUrl,token:e.token,logLevel:`warn`});return{platform:`ios`,lease:e.lease,instanceId:e.instanceId,device:e.device,client:n,token:e.token,dependencies:t}}async function E(e,t,n,i,a,o){a?.throwIfAborted();let s=await A(n,t.dependencies);try{a?.throwIfAborted();let n=await r(o,e.assets.getOrUpload({path:s.uploadPath,name:s.assetName},{signal:a}),a),c=(await D(t,n.signedDownloadUrl,{md5:n.md5,relaunch:i?.relaunch,appIdentifierHint:i?.appIdentifierHint},a,o)).appId;return{...c?{bundleId:c,launchTarget:c}:{},...s.appName?{appName:s.appName}:{}}}finally{await s.cleanup()}}async function D(t,n,i,a,o){a?.throwIfAborted();let s=await r(o,t.client.listApps(),a).catch(e=>{if(a?.aborted)throw e}),c=d((await r(o,t.client.installApp(n,{md5:i?.md5,launchMode:i?.relaunch?`RelaunchIfRunning`:`ForegroundIfRunning`}),a)).bundleId),l=d(i?.appIdentifierHint),f=[];for(let e of M){e>0&&await u(e,void 0,{signal:a}),f=await r(o,t.client.listApps(),a);let n=F({resultBundleId:c,requestedBundleId:l,beforeInstallApps:s,afterInstallApps:f});if(n)return{appId:n}}throw new e(`COMMAND_FAILED`,`Limrun iOS app installation could not be verified.`,{resultBundleId:c,requestedBundleId:l,installedUserApps:f.filter(L).map(e=>e.bundleId).sort()})}function O(e){return new k(e)}var k=class{session;constructor(e){this.session=e}async open(e,n){if(n?.url){await this.session.client.launchApp(await this.session.dependencies.ios.resolveAppAlias(e)),await this.session.client.openUrl(n.url);return}if(t(e)){await this.session.client.openUrl(e);return}await this.session.client.launchApp(await this.session.dependencies.ios.resolveAppAlias(e))}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(o(e))}async doubleTap(e,t){await this.session.client.performActions([{type:`tap`,x:e,y:t},{type:`wait`,durationMs:P},{type:`tap`,x:e,y:t}])}async longPress(e,t,n=N){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=>u(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(e,t){if(t&&t>0){for(let n of Array.from(e))await this.session.client.typeText(n,!1,{requireFocus:!1}),await u(t);return}await this.session.client.typeText(e,!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(s.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 R(`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(){throw R(`settings`,`Limrun iOS direct sessions do not expose settings changes yet.`)}};async function A(e,t){if(!(await c.promises.stat(e)).isDirectory())return{uploadPath:e,assetName:s.basename(e),appName:j(e),cleanup:async()=>{}};let n=await c.promises.mkdtemp(s.join(l.tmpdir(),`agent-device-limrun-ios-app-`)),r=s.join(n,`${s.basename(e)}.zip`);try{await t.host.archiveDirectory({sourceDirectory:s.dirname(e),entryName:s.basename(e),archivePath:r})}catch(e){throw await c.promises.rm(n,{recursive:!0,force:!0}),e}return{uploadPath:r,assetName:s.basename(r),appName:await t.ios.readBundleAppName(e)??j(e),cleanup:async()=>{await c.promises.rm(n,{recursive:!0,force:!0})}}}function j(e){return s.basename(e).replace(/\.(?:app|ipa|apk|aab|zip)$/i,``)||void 0}const M=[0,250],N=800,P=80;function F(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)??I(e.beforeInstallApps,e.afterInstallApps)}function I(e,t){if(!e)return;let n=new Set(e.map(e=>e.bundleId)),r=t.filter(e=>L(e)&&!n.has(e.bundleId));return r.length===1?r[0]?.bundleId:void 0}function L(e){return!e.bundleId.startsWith(`com.apple.`)&&!e.installType.toLowerCase().includes(`system`)}function R(t,n){throw new e(`UNSUPPORTED_OPERATION`,n,{command:t})}function z(e){return e.platform===`android`?B(e):V(e)}function B(e){let t=e.adbProvider.exec;return{platform:`android`,device:e.device,interactor:p(e),adb:e.adbProvider,listApps:async r=>await e.dependencies.android.listApps(t,n(r)),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),...H(e.client,e.token,e.dependencies.host),installRemoteApp:async t=>{await e.client.sendAsset(t)}}}function V(e){return{platform:`ios`,device:e.device,interactor:O(e),viewport:{width:e.client.deviceInfo.screenWidth,height:e.client.deviceInfo.screenHeight},listApps:async t=>(await e.client.listApps()).filter(e=>n(t)===`all`||L(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),...H(e.client,e.token,e.dependencies.host),installRemoteApp:async(t,n)=>await D(e,t,n),runSimctl:t=>e.client.simctl(t)}}function H(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{g as a,f as c,E as i,m as l,O as n,h as o,T as r,p as s,z as t};
|
|
1
|
+
import{N as e,z 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"./request-cancellation.js";import{n as a,t as o}from"./ios-client.js";import{i as s}from"./snapshot.js";import c from"node:path";import l from"node:fs";import u from"node:os";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,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),Object.assign(r,{adbProvider:i})}function m(e){return e.dependencies.android.createInteractor(e.device,e.adbProvider)}async function h(e,t,n,r,a,o){a?.throwIfAborted();let s=f(r?.packageNameHint);r?.relaunch&&s&&await t.dependencies.android.forceStopApp(async(e,n)=>await y(t,e,n),s,a);let c=await i(o,e.assets.getOrUpload({path:n,name:T(s,n)},{signal:a}),a);await i(o,t.client.sendAsset(c.signedDownloadUrl),a),a?.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=[];for(let e of n)e.ownerId?r.add(e.ownerId):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(t){if(!Number.isInteger(t)||t<1||t>65535)throw new e(`INVALID_ARGS`,`Invalid Android tcp reverse port: ${t}`);return`tcp:${t}`}function T(e,t){let n=c.extname(t)||`.apk`;return`${e?.replaceAll(/[^a-zA-Z0-9_.-]+/g,`-`)||`android-app`}${n}`}async function E(e,t){let n=await o({apiUrl:e.apiUrl,token:e.token,logLevel:`warn`});return{platform:`ios`,lease:e.lease,instanceId:e.instanceId,device:e.device,client:n,token:e.token,dependencies:t}}async function D(e,t,n,r,a,o){a?.throwIfAborted();let s=await j(n,t.dependencies);try{a?.throwIfAborted();let n=await i(o,e.assets.getOrUpload({path:s.uploadPath,name:s.assetName},{signal:a}),a),c=(await O(t,n.signedDownloadUrl,{md5:n.md5,relaunch:r?.relaunch,appIdentifierHint:r?.appIdentifierHint},a,o)).appId;return{...c?{bundleId:c,launchTarget:c}:{},...s.appName?{appName:s.appName}:{}}}finally{await s.cleanup()}}async function O(t,n,r,a,o){a?.throwIfAborted();let s=await i(o,t.client.listApps(),a).catch(e=>{if(a?.aborted)throw e}),c=f((await i(o,t.client.installApp(n,{md5:r?.md5,launchMode:r?.relaunch?`RelaunchIfRunning`:`ForegroundIfRunning`}),a)).bundleId),l=f(r?.appIdentifierHint),u=[];for(let e of N){e>0&&await d(e,void 0,{signal:a}),u=await i(o,t.client.listApps(),a);let n=I({resultBundleId:c,requestedBundleId:l,beforeInstallApps:s,afterInstallApps:u});if(n)return{appId:n}}throw new e(`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.session.client.launchApp(await this.session.dependencies.ios.resolveAppAlias(e)),await this.session.client.openUrl(t.url);return}if(n(e)){await this.session.client.openUrl(e);return}await this.session.client.launchApp(await this.session.dependencies.ios.resolveAppAlias(e))}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(e,n){if(n&&n>0){let r=0;try{for(let t of Array.from(e))await this.session.client.typeText(t,!1,{requireFocus:!1}),r+=1,await d(n)}catch(e){throw t(e,r)}return}await this.session.client.typeText(e,!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`);l.mkdirSync(c.dirname(e),{recursive:!0}),await l.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(){throw z(`settings`,`Limrun iOS direct sessions do not expose settings changes yet.`)}};async function j(e,t){if(!(await l.promises.stat(e)).isDirectory())return{uploadPath:e,assetName:c.basename(e),appName:M(e),cleanup:async()=>{}};let n=await l.promises.mkdtemp(c.join(u.tmpdir(),`agent-device-limrun-ios-app-`)),r=c.join(n,`${c.basename(e)}.zip`);try{await t.host.archiveDirectory({sourceDirectory:c.dirname(e),entryName:c.basename(e),archivePath:r})}catch(e){throw await l.promises.rm(n,{recursive:!0,force:!0}),e}return{uploadPath:r,assetName:c.basename(r),appName:await t.ios.readBundleAppName(e)??M(e),cleanup:async()=>{await l.promises.rm(n,{recursive:!0,force:!0})}}}function M(e){return c.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(t,n){throw new e(`UNSUPPORTED_OPERATION`,n,{command:t})}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/diagnostics.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{tt as e}from"./sdk-contracts.js";import t from"node:path";import n from"node:fs";import r from"node:crypto";import{AsyncLocalStorage as i}from"node:async_hooks";import a from"node:os";const o=new i;function s(){return r.randomBytes(8).toString(`hex`)}function c(){return`${Date.now().toString(36)}-${r.randomBytes(4).toString(`hex`)}`}async function l(e,t){let n={...e,diagnosticId:c(),events:[],liveWrittenEventCount:0,phaseCounts:new Map,sensitiveValues:new Set,ensuredDirectories:new Set};return await o.run(n,t)}function u(e){let t=o.getStore();t&&Object.assign(t,e)}function d(){let e=o.getStore();if(!e)return{};let{diagnosticId:t,requestId:n,session:r,command:i,debug:a,flushOnSuccess:s}=e;return{diagnosticId:t,requestId:n,session:r,command:i,debug:a,flushOnSuccess:s}}function f(e){if(!e)return;let t=o.getStore();t&&(t.sensitiveValues.add(e),t.sortedSensitiveValues=void 0)}function p(e){let t=o.getStore();if(!t)return 0;let n=0;for(let r of e)n+=t.phaseCounts.get(r)??0;return n}function m(e){let t=o.getStore();if(!t)return;let n={ts:new Date().toISOString(),level:e.level??`info`,phase:e.phase,session:t.session,requestId:t.requestId,command:t.command,durationMs:e.durationMs,data:e.data?v(t,e.data):void 0};if(t.events.push(n),t.phaseCounts.set(e.phase,(t.phaseCounts.get(e.phase)??0)+1),!t.debug&&!t.traceLogPath)return;let r=`${JSON.stringify(n)}\n`;try{t.debug&&t.logPath&&(x(t,t.logPath,r),t.liveWrittenEventCount=t.events.length),t.traceLogPath&&x(t,t.traceLogPath,r),t.debug&&!t.logPath&&!t.traceLogPath&&process.stderr.write(`[agent-device][diag] ${r}`)}catch{}}async function h(e,t,n){let r=Date.now();try{let i=await t();return m({level:`info`,phase:e,durationMs:Date.now()-r,data:n}),i}catch(t){throw m({level:`error`,phase:e,durationMs:Date.now()-r,data:{...n??{},error:t instanceof Error?t.message:String(t)}}),t}}function g(e={}){let r=o.getStore();if(!r||!e.force&&!r.debug&&!r.flushOnSuccess||r.events.length===0)return null;let i=_(r);try{if(r.logPath){let e=r.events.slice(r.liveWrittenEventCount);if(e.length>0){let t=e.map(e=>JSON.stringify(y(e,i)));x(r,r.logPath,`${t.join(`
|
|
2
2
|
`)}\n`)}let t=r.logRecord;return r.events=[],r.liveWrittenEventCount=0,{path:r.logPath,...t?{ref:t}:{}}}let e=b(r.session??`default`),o=new Date().toISOString().slice(0,10),s=t.join(a.homedir(),`.agent-device`,`logs`,e,o);n.mkdirSync(s,{recursive:!0});let c=new Date().toISOString().replaceAll(/[:.]/g,`-`),l=t.join(s,`${c}-${r.diagnosticId}.ndjson`),u=r.events.map(e=>JSON.stringify(y(e,i)));return n.writeFileSync(l,`${u.join(`
|
|
3
3
|
`)}\n`),r.events=[],{path:l}}catch{return null}}function _(e){return e.sortedSensitiveValues??=[...e.sensitiveValues].sort((e,t)=>t.length-e.length),e.sortedSensitiveValues}function v(t,n){return y(e(n),_(t))}function y(e,t){return typeof e==`string`?t.reduce((e,t)=>e.replaceAll(t,`[REDACTED]`),e):Array.isArray(e)?e.map(e=>y(e,t)):!e||typeof e!=`object`?e:Object.fromEntries(Object.entries(e).map(([e,n])=>[e,y(n,t)]))}function b(e){return e.replaceAll(/[^a-zA-Z0-9._-]/g,`_`)}function x(e,r,i){let a=t.dirname(r);e.ensuredDirectories.has(a)||(n.mkdirSync(a,{recursive:!0}),e.ensuredDirectories.add(a)),n.appendFileSync(r,i,`utf8`)}export{d as a,h as c,g as i,l,s as n,f as o,m as r,u as s,p as t};
|
package/dist/src/diagnostics2.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./diagnostics.js";export{};
|
|
1
|
+
import{r as e}from"./rolldown-runtime.js";import{r as t}from"./diagnostics.js";var n=e({emitDiagnostic:()=>t});export{n as t};
|