agent-device 0.21.22 → 0.21.23

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.
Files changed (58) hide show
  1. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.22.apk → agent-device-android-ime-helper-0.21.23.apk} +0 -0
  2. package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.23.apk.sha256 +1 -0
  3. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.22.manifest.json → agent-device-android-ime-helper-0.21.23.manifest.json} +4 -4
  4. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.23.apk +0 -0
  5. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.23.apk.sha256 +1 -0
  6. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.22.manifest.json → agent-device-android-snapshot-helper-0.21.23.manifest.json} +6 -6
  7. package/dist/src/android-input-ownership.js +1 -1
  8. package/dist/src/app-log-reconnect.js +1 -1
  9. package/dist/src/app-log-runtime2.js +3 -3
  10. package/dist/src/back-mode.js +1 -1
  11. package/dist/src/client-metro-companion.js +1 -1
  12. package/dist/src/client-metro.js +1 -1
  13. package/dist/src/client-options.js +3 -3
  14. package/dist/src/cloud-artifacts.d.ts +6 -0
  15. package/dist/src/code-signature-cache.js +1 -1
  16. package/dist/src/connection-runtime.js +1 -1
  17. package/dist/src/daemon-registration-owner.js +1 -1
  18. package/dist/src/device-session.js +3 -1
  19. package/dist/src/dispatch-resolve.js +1 -1
  20. package/dist/src/doctor-facade.js +1 -1
  21. package/dist/src/durable-capture-resource.js +1 -1
  22. package/dist/src/file.js +1 -1
  23. package/dist/src/helper.js +2 -2
  24. package/dist/src/ime-rebind.js +1 -0
  25. package/dist/src/ime-state.js +1 -0
  26. package/dist/src/instance-client.js +1 -1
  27. package/dist/src/internal/bin.js +1 -1
  28. package/dist/src/internal/daemon.js +1 -1
  29. package/dist/src/ios-client.js +4 -4
  30. package/dist/src/ios-snapshot-engine.js +1 -1
  31. package/dist/src/log-stream.js +33 -0
  32. package/dist/src/mechanics.js +16 -16
  33. package/dist/src/node-http.js +1 -0
  34. package/dist/src/owner-identity.js +1 -1
  35. package/dist/src/perf-runtime-plan.js +1 -1
  36. package/dist/src/platform-runtime-app-log-process.js +1 -1
  37. package/dist/src/platform-runtime-operation-host.js +1 -1
  38. package/dist/src/platform-runtime-screen-recording-process-host.js +1 -1
  39. package/dist/src/process.js +1 -1
  40. package/dist/src/proxy.js +2 -2
  41. package/dist/src/registry.js +1 -1
  42. package/dist/src/runner-client.js +1 -1
  43. package/dist/src/runner-disposal.js +1 -1
  44. package/dist/src/runner-operations-facade.js +1 -1
  45. package/dist/src/runner-start-budget.js +1 -1
  46. package/dist/src/runtime10.js +1 -1
  47. package/dist/src/screenshot-overlay-draw.js +1 -1
  48. package/dist/src/screenshot-runtime.js +1 -1
  49. package/dist/src/script.js +1 -1
  50. package/dist/src/sdk-batch.js +2 -2
  51. package/dist/src/sdk-contracts.d.ts +5 -4
  52. package/dist/src/store.js +1 -1
  53. package/package.json +11 -8
  54. package/server.json +2 -2
  55. package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.22.apk.sha256 +0 -1
  56. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.22.apk +0 -0
  57. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.22.apk.sha256 +0 -1
  58. package/dist/src/session-stream.js +0 -27
@@ -1,4 +1,4 @@
1
- import{P as e,it as t}from"./sdk-contracts.js";import{v as n}from"./sdk-batch-runner.js";import{a as r,c as i,r as a}from"./diagnostics.js";import"./diagnostics2.js";import{E as o,a as s,d as c,i as l,l as ee,n as te,w as ne}from"./sdk-device.js";import{$n as re,S as ie,er as ae,ln as u,m as oe,sn as se}from"./sdk-batch.js";import{t as ce}from"./recording-scope.js";import{a as le}from"./scroll-gesture.js";import{_ as d,c as ue,d as de,g as fe,h as pe,i as me,l as he,m as ge,o as _e,p as f,s as ve,u as p,y as ye}from"./script.js";import{C as be,D as xe,E as Se,F as Ce,M as we,O as Te,P as Ee,S as De,T as Oe,a as ke,b as Ae,d as je,i as Me,j as Ne,k as Pe,l as Fe,o as Ie,r as Le,s as Re,v as m,w as h,x as ze,y as Be}from"./provider-device-admission.js";import{n as g,t as _}from"./catalog.js";import{o as Ve,t as v}from"./back-mode.js";import{t as He}from"./session.js";import{r as Ue}from"./success-text.js";import{t as We}from"./click-button.js";import"./device.js";import{r as Ge,t as Ke}from"./device-rotation.js";import{A as qe}from"./owner-identity.js";import"./file.js";import{t as Je}from"./tv-remote.js";import{n as Ye,r as Xe,t as Ze}from"./session-paths.js";import{i as Qe,n as $e,r as et}from"./session-artifact-paths.js";import{i as tt,r as nt,t as rt}from"./session-repair-tombstone.js";import{t as it}from"./keyboard-actions.js";import{n as at,r as ot}from"./device-isolation.js";import{a as st,i as ct,r as lt}from"./device-inventory-context.js";import{AsyncLocalStorage as ut}from"node:async_hooks";import{createHash as dt}from"node:crypto";import y from"node:fs";import b from"node:path";import{StringDecoder as ft}from"node:string_decoder";function pt(e,t={}){let n=[e.command];return e.command===`snapshot`?de(n,e):e.command===`open`?me(n,e):e.command===`runtime`?ue(n,e,{includeAllPositionals:t.runtimeIncludeAllPositionals}):e.command===`record`?ve(n,e):e.command===`screenshot`?he(n,e):_e(n,e),n.join(` `)}function mt(e){return e.targetEvidences?[re(e.targetEvidences)]:e.targetEvidence?[ae(e.targetEvidence)]:[]}function x(e){return e?.scriptPublication??m}function ht(e,t){let n=x(e),r=typeof t.saveScript==`string`?Ze(t.saveScript):n.kind===`repair`?void 0:t.healedSiblingPath;e.scriptPublication=Ae(n,{requested:{path:r,force:t.force===!0},boundary:t.firstArm?e.actions.length:0,sourcePath:t.sourcePath})}function gt(e){e.scriptPublication=De(x(e))}function _t(e){e.scriptPublication=Se(x(e))}function vt(e,t){e.scriptPublication=xe(x(e),t)}function yt(e){e.scriptPublication=Be(x(e))}function bt(e,t){let n=x(e);return n.kind===`repair`&&n.closeReceipt===t}function xt(e){return x(e).kind===`repair`}function St(e){return Oe(x(e))}function S(e){return Te(x(e))}function Ct(e){return Pe(x(e))}function wt(e,t){if(t.flags?.noRecord||Pt(e,t))return;t.flags&&Fe(e,t.flags);let n=Et(t),r=kt(e,Dt(t,n));n&&Ot(e,n);let i={ts:Date.now(),command:r.command,positionals:r.positionals,runtime:r.runtime,flags:It(r.flags),result:r.result,...r.targetEvidence?{targetEvidence:r.targetEvidence}:{},...r.targetEvidences?{targetEvidences:r.targetEvidences}:{}};return e.actions.push(i),a({level:`debug`,phase:`record_action`,data:{command:t.command,session:e.name}}),i}function Tt(e,t,n,r,i,a){!t||!e.resolveCurrent(t)||e.recordAction(t,{command:r,positionals:a?.positionals??n.positionals??[],flags:a?.flags??n.flags??{},result:i??{}})}function Et(e){if(e.command!==`fill`||typeof e.flags.recordAs!=`string`)return;let t=Ce(e.flags.recordAs),n=Ee(t);return{literal:we({ts:0,command:e.command,positionals:e.positionals,flags:e.flags}),placeholder:n}}function Dt(e,t){if(!t)return e;let{literal:n,placeholder:r}=t;return{...e,positionals:jt(e.positionals,r),result:Le(e.result,n,r),targetEvidence:Me(e.targetEvidence,n,r)}}function Ot(e,t){t.literal.trim()&&(e.recordedFillLiterals??=new Map,!e.recordedFillLiterals.has(t.literal)&&e.recordedFillLiterals.set(t.literal,t.placeholder))}function kt(e,t){let n=e.recordedFillLiterals;if(!n||n.size===0)return t;let r=ke(t.result,n),i=(t.targetEvidenceMode??`action`)===`landmark`?At(t.targetEvidence,n):C(t.targetEvidence,n),a=t.targetEvidences?{source:C(t.targetEvidences.source,n),destination:C(t.targetEvidences.destination,n)}:t.targetEvidences;return{...t,result:r,targetEvidence:i,targetEvidences:a}}function At(e,t){return e&&(Re(e,t)?void 0:e)}function C(e,t){return!e||!Re(e,t)?e:{...Ie(e,t),verification:`unverifiable`}}function jt(e,t){let n=e[0];return n?.startsWith(`@`)?e.length>=3?[n,e[1],t]:[n,t]:e.length>=3&&Number.isFinite(Number(e[0]))&&Number.isFinite(Number(e[1]))?[e[0],e[1],t]:n===void 0?[t]:[n,t]}const Mt=new Set([`snapshot`,`get`,`is`,`find`]);function Nt(e){return e.internal?.replayPlanStep!==!0&&Mt.has(e.command)}function Pt(e,t){return!t.interactiveObservation||S(e)===void 0?!1:t.flags?.record!==!0}const Ft=Ve();function It(e){if(!e)return{};let t={};for(let n of Ft){let r=e[n];r!==void 0&&(t[n]=r)}return t}function w(e){return b.join(e,`idle-expiry.json`)}function Lt(e){let t;try{t=y.readFileSync(e,`utf8`)}catch{return}let n;try{n=JSON.parse(t)}catch{return}if(!(typeof n?.expiresAt!=`number`||!Number.isFinite(n.expiresAt))&&!(n.expiresAt<=Date.now())&&typeof n.owner==`string`&&!(!Rt(n.expiredAtMs)||!Rt(n.idleExpiryMs))&&(n.deviceKey===void 0||typeof n.deviceKey==`string`))return n}function Rt(e){return typeof e==`number`&&Number.isFinite(e)&&e>=0}function zt(t){let n=t.flatMap((e,t)=>e.command===`open`?[t]:[]);if(n.length!==1||n[0]!==0)throw new e(`COMMAND_FAILED`,`Cannot publish this session: an open-to-destination script requires exactly one initial recorded open.`,{retriable:!1,hint:`Close this session and start a fresh one with open <app> --save-script[=<path>].`});if(t.some(e=>e.command===`close`))throw new e(`COMMAND_FAILED`,`Cannot publish an active-session script containing close.`,{retriable:!1,hint:`Close this session and record the journey again from a fresh open --save-script session.`});let r=-1;for(let[e,n]of t.entries())ie({command:n.command,positionals:n.positionals,flags:n.flags})===`mutates-app`&&(r=e);if(!t.slice(r+1).some(Gt))throw new e(`COMMAND_FAILED`,`Cannot publish this session without a portable destination guard after the final mutating action.`,{retriable:!0,hint:`Record a selector-targeted wait on a labeled or id-bearing landmark, for example wait 'role="heading" label="Screen X"', so its recorded identity is captured, then retry session save-script.`})}function Bt(t){for(let n of t){if(Vt(n)){Ht(n);continue}let t=Kt(n),r=t??(n.command===`wait`?n.positionals[0]:void 0);if(r?.startsWith(`@`))throw new e(`COMMAND_FAILED`,`Cannot publish recorded step "${n.command} ${r}": the session-local ref was not converted to a portable selector.`,{retriable:!1,hint:`Close this session and record the journey again using selectors or resolvable refs.`});if(n.command===`find`&&ie(n)===`mutates-app`)throw new e(`COMMAND_FAILED`,`Cannot publish a recorded mutating find step because its target identity is not replay-verifiable.`,{retriable:!1,hint:`Close this session and record the journey again with an explicit selector-targeted click, press, fill, or focus action.`});let i=t;if(!(!i||!u(i)||n.targetEvidence))throw new e(`COMMAND_FAILED`,`Cannot publish recorded step "${n.command} ${i}": recording-time target identity evidence is missing.`,{retriable:!1,hint:`Close this session and record the journey again from open --save-script so target-v1 evidence is captured before each interaction.`})}}function Vt(e){return Ut(e)!==void 0}function Ht(t){let n=Ut(t);if(!n)return;let r=[n.source,n.destination];for(let n of r){if(n?.startsWith(`@`))throw new e(`COMMAND_FAILED`,`Cannot publish recorded drag endpoint "${n}": the session-local ref was not converted to a portable selector.`,{retriable:!1});if(!(!n||!u(n))&&!t.targetEvidences)throw new e(`COMMAND_FAILED`,`Cannot publish recorded drag endpoint "${n}": recording-time target identity evidence is missing.`,{retriable:!1,hint:`Close this session and record the journey again so targets-v1 evidence is captured for both drag endpoints.`})}}function Ut(e){return e.command===`gesture`?ye(e.positionals):void 0}function Wt(t,n){if(t instanceof e){if(t.details?.reason===`script_target_exists`)return new e(t.code,`A file already exists at ${String(t.details.path)}.`,{...t.details,retriable:!0,hint:`Retry session save-script with another path, or pass --force to replace the existing file. The session remains armed.`});let n=t.details?.retriable===!0;return new e(t.code,t.message,{...t.details,retriable:n,hint:t.details?.hint??(n?`Fix the recorded journey or target, then retry session save-script. The session remains armed.`:`Close this session and start a fresh one with open <app> --save-script[=<path>].`)})}let r=t instanceof Error?t.message:String(t);return new e(`COMMAND_FAILED`,`Failed to publish the active session script${n?` to ${n}`:``}: ${r}`,{retriable:!0,hint:`Check the target path and permissions, then retry session save-script. The session remains armed.`})}function Gt(e){if(e.command!==`wait`)return!1;let t=se(e.positionals);return t?.kind!==`selector`||!u(t.selectorExpression)?!1:e.targetEvidence?.verification===`verified`}function Kt(e){if(e.command===`get`)return e.positionals[1];if(fe(e.command)||e.command===`fill`){let[t,n]=e.positionals;return t!==void 0&&n!==void 0&&qt(t)&&qt(n)?void 0:t}}function qt(e){return e.trim().length>0&&Number.isFinite(Number(e))}function Jt(e){let t=e.scriptPublication??m;return t.kind===`repair`?t.status===`committed`||!h(t):!1}function Yt(e){return!be(e.scriptPublication??m)||Jt(e)}var Xt=class{sessionsDir;constructor(e){this.sessionsDir=e}write(e,t){let n=xt(e),r=t?.publication===`active`,i;try{if(Yt(e))return{written:!1};let a=Zt(e,{appendCompleteSentinel:n,activePublication:r});i=this.resolveScriptPath(e);let o=b.dirname(i);return y.existsSync(o)||y.mkdirSync(o,{recursive:!0}),en({scriptPath:i,script:a.script,force:t?.force}),n&&(e.scriptPublication=ze(e.scriptPublication??m)),{written:!0,path:i,actionCount:a.actionCount}}catch(t){return Qt({session:e,error:t,scriptPath:i,repairArmed:n,activePublication:r})}}resolveScriptPath(e){let t=Ne(e.scriptPublication??m);if(t)return Ze(t);let n=Xe(e.name),r=new Date(e.createdAt).toISOString().replaceAll(/[:.]/g,`-`);return b.join(this.sessionsDir,`${n}-${r}.ad`)}};function Zt(e,t){let n=tn(e,{strictPortableRefs:t.activePublication});return t.activePublication&&zt(n),{script:fn(e,n,t.appendCompleteSentinel),actionCount:n.length}}function Qt(t){let{session:n,error:r,scriptPath:i,repairArmed:o,activePublication:s}=t;if(a({level:`warn`,phase:`session_script_write_failed`,data:{session:n.name,path:i,error:r instanceof Error?r.message:String(r)}}),o)return{written:!1,error:$t(r,i)};if(s)return{written:!1,error:Wt(r,i)};if(r instanceof e)throw r;return{written:!1}}function $t(t,n){if(t instanceof e)return t;let r=t instanceof Error?t.message:String(t);return new e(`COMMAND_FAILED`,`Failed to write the healed script${n?` to ${n}`:``}: ${r}`,{hint:`The repair transaction completed but the healed .ad could not be published; check the target path and permissions, then retry close --save-script.`})}function en(t){let{scriptPath:n,script:r,force:i}=t;try{qe({destination:n,contents:r,publish:i?`replace`:`link-exclusive`})}catch(t){throw t.code===`EEXIST`?new e(`COMMAND_FAILED`,`A file already exists at ${n}; remove it, pass replay --save-script=<other-path>, or pass --force/--overwrite to replace it.`,{reason:`script_target_exists`,path:n}):t}}function tn(e,t={}){let n=S(e),r=n!==void 0,i=e.actions.slice(n??0),a=[];for(let n of i){if(n.command===`snapshot`)continue;let i=an(n);if(i){a.push(i);continue}(r||t.strictPortableRefs)&&nn(n);let o=dn(e,n);o&&a.push(o),a.push(n)}return t.strictPortableRefs&&Bt(a),a}function nn(t){let n=t.command===`gesture`?ye(t.positionals??[]):void 0;if(n){rn(n);return}if(!T(t.command))return;let r=t.command===`get`?t.positionals?.[1]:t.positionals?.[0];if(r?.startsWith(`@`))throw new e(`COMMAND_FAILED`,`Cannot write recorded step "${t.command} ${r}" to a script: it never resolved to a selector, so the ref would not resolve in a fresh replay session.`)}function rn(t){let n=[t.source,t.destination].find(e=>e.startsWith(`@`));if(n)throw new e(`COMMAND_FAILED`,`Cannot write recorded drag endpoint "${n}" to a script: it never resolved to a selector, so the ref would not resolve in a fresh replay session.`)}function an(e){let t=on(e);if(!(!t||!T(e.command)))return pe(e.command)||e.command===`hover`?{...e,positionals:[t]}:e.command===`longpress`?cn(e,t):e.command===`fill`?sn(e,t):ln(e,t)}function on(e){let t=Array.isArray(e.result?.selectorChain)&&e.result.selectorChain.every(e=>typeof e==`string`)?e.result.selectorChain:[];return t.length>0?t.join(` || `):void 0}function T(e){return fe(e)||e===`fill`||e===`get`}function sn(e,t){let n=we(e);return n.length>0?{...e,positionals:[t,n]}:void 0}function cn(e,t){let n=typeof e.result?.durationMs==`number`?String(e.result.durationMs):un(e.positionals??[]);return{...e,positionals:n?[t,n]:[t]}}function ln(e,t){let n=e.positionals?.[0];return n===`text`||n===`attrs`?{...e,positionals:[n,t]}:void 0}function un(e){let t=e.at(-1);if(!(e.length<=1||t===void 0||t.trim()===``))return Number.isFinite(Number(t))?t:void 0}function dn(e,t){if(!T(t.command))return;let n=t.result?.refLabel;if(typeof n!=`string`||n.trim().length===0)return;let r=n.trim();return{ts:t.ts,command:`snapshot`,positionals:[],flags:{platform:e.device.platform,snapshotInteractiveOnly:!0,snapshotScope:r},result:{scope:r}}}function fn(e,t,n){let r=[],i=e.device.kind?` kind=${e.device.kind}`:``;r.push(`context platform=${ne(e.device)} device=${ge(e.device.name)}${i} theme=unknown`);for(let e of t)e.flags?.noRecord||(r.push(...mt(e)),r.push(pn(e)));return n&&r.push(`# agent-device:heal-complete`),`${r.join(`
1
+ import{P as e,it as t}from"./sdk-contracts.js";import{v as n}from"./sdk-batch-runner.js";import{a as r,c as i,r as a}from"./diagnostics.js";import"./diagnostics2.js";import{E as o,a as s,d as c,i as l,l as ee,n as te,w as ne}from"./sdk-device.js";import{$n as re,S as ie,er as ae,ln as u,m as oe,sn as se}from"./sdk-batch.js";import{t as ce}from"./recording-scope.js";import{a as le}from"./scroll-gesture.js";import{_ as d,c as ue,d as de,g as fe,h as pe,i as me,l as he,m as ge,o as _e,p as f,s as ve,u as p,y as ye}from"./script.js";import{C as be,D as xe,E as Se,F as Ce,M as we,O as Te,P as Ee,S as De,T as Oe,a as ke,b as Ae,d as je,i as Me,j as Ne,k as Pe,l as Fe,o as Ie,r as Le,s as Re,v as m,w as h,x as ze,y as Be}from"./provider-device-admission.js";import{n as g,t as _}from"./catalog.js";import{o as Ve,t as v}from"./back-mode.js";import{t as He}from"./session.js";import{r as Ue}from"./success-text.js";import{t as We}from"./click-button.js";import"./device.js";import{r as Ge,t as Ke}from"./device-rotation.js";import{j as qe}from"./owner-identity.js";import"./file.js";import{t as Je}from"./tv-remote.js";import{n as Ye,r as Xe,t as Ze}from"./session-paths.js";import{i as Qe,n as $e,r as et}from"./session-artifact-paths.js";import{i as tt,r as nt,t as rt}from"./session-repair-tombstone.js";import{t as it}from"./keyboard-actions.js";import{n as at,r as ot}from"./device-isolation.js";import{a as st,i as ct,r as lt}from"./device-inventory-context.js";import{AsyncLocalStorage as ut}from"node:async_hooks";import{createHash as dt}from"node:crypto";import y from"node:fs";import b from"node:path";import{StringDecoder as ft}from"node:string_decoder";function pt(e,t={}){let n=[e.command];return e.command===`snapshot`?de(n,e):e.command===`open`?me(n,e):e.command===`runtime`?ue(n,e,{includeAllPositionals:t.runtimeIncludeAllPositionals}):e.command===`record`?ve(n,e):e.command===`screenshot`?he(n,e):_e(n,e),n.join(` `)}function mt(e){return e.targetEvidences?[re(e.targetEvidences)]:e.targetEvidence?[ae(e.targetEvidence)]:[]}function x(e){return e?.scriptPublication??m}function ht(e,t){let n=x(e),r=typeof t.saveScript==`string`?Ze(t.saveScript):n.kind===`repair`?void 0:t.healedSiblingPath;e.scriptPublication=Ae(n,{requested:{path:r,force:t.force===!0},boundary:t.firstArm?e.actions.length:0,sourcePath:t.sourcePath})}function gt(e){e.scriptPublication=De(x(e))}function _t(e){e.scriptPublication=Se(x(e))}function vt(e,t){e.scriptPublication=xe(x(e),t)}function yt(e){e.scriptPublication=Be(x(e))}function bt(e,t){let n=x(e);return n.kind===`repair`&&n.closeReceipt===t}function xt(e){return x(e).kind===`repair`}function St(e){return Oe(x(e))}function S(e){return Te(x(e))}function Ct(e){return Pe(x(e))}function wt(e,t){if(t.flags?.noRecord||Pt(e,t))return;t.flags&&Fe(e,t.flags);let n=Et(t),r=kt(e,Dt(t,n));n&&Ot(e,n);let i={ts:Date.now(),command:r.command,positionals:r.positionals,runtime:r.runtime,flags:It(r.flags),result:r.result,...r.targetEvidence?{targetEvidence:r.targetEvidence}:{},...r.targetEvidences?{targetEvidences:r.targetEvidences}:{}};return e.actions.push(i),a({level:`debug`,phase:`record_action`,data:{command:t.command,session:e.name}}),i}function Tt(e,t,n,r,i,a){!t||!e.resolveCurrent(t)||e.recordAction(t,{command:r,positionals:a?.positionals??n.positionals??[],flags:a?.flags??n.flags??{},result:i??{}})}function Et(e){if(e.command!==`fill`||typeof e.flags.recordAs!=`string`)return;let t=Ce(e.flags.recordAs),n=Ee(t);return{literal:we({ts:0,command:e.command,positionals:e.positionals,flags:e.flags}),placeholder:n}}function Dt(e,t){if(!t)return e;let{literal:n,placeholder:r}=t;return{...e,positionals:jt(e.positionals,r),result:Le(e.result,n,r),targetEvidence:Me(e.targetEvidence,n,r)}}function Ot(e,t){t.literal.trim()&&(e.recordedFillLiterals??=new Map,!e.recordedFillLiterals.has(t.literal)&&e.recordedFillLiterals.set(t.literal,t.placeholder))}function kt(e,t){let n=e.recordedFillLiterals;if(!n||n.size===0)return t;let r=ke(t.result,n),i=(t.targetEvidenceMode??`action`)===`landmark`?At(t.targetEvidence,n):C(t.targetEvidence,n),a=t.targetEvidences?{source:C(t.targetEvidences.source,n),destination:C(t.targetEvidences.destination,n)}:t.targetEvidences;return{...t,result:r,targetEvidence:i,targetEvidences:a}}function At(e,t){return e&&(Re(e,t)?void 0:e)}function C(e,t){return!e||!Re(e,t)?e:{...Ie(e,t),verification:`unverifiable`}}function jt(e,t){let n=e[0];return n?.startsWith(`@`)?e.length>=3?[n,e[1],t]:[n,t]:e.length>=3&&Number.isFinite(Number(e[0]))&&Number.isFinite(Number(e[1]))?[e[0],e[1],t]:n===void 0?[t]:[n,t]}const Mt=new Set([`snapshot`,`get`,`is`,`find`]);function Nt(e){return e.internal?.replayPlanStep!==!0&&Mt.has(e.command)}function Pt(e,t){return!t.interactiveObservation||S(e)===void 0?!1:t.flags?.record!==!0}const Ft=Ve();function It(e){if(!e)return{};let t={};for(let n of Ft){let r=e[n];r!==void 0&&(t[n]=r)}return t}function w(e){return b.join(e,`idle-expiry.json`)}function Lt(e){let t;try{t=y.readFileSync(e,`utf8`)}catch{return}let n;try{n=JSON.parse(t)}catch{return}if(!(typeof n?.expiresAt!=`number`||!Number.isFinite(n.expiresAt))&&!(n.expiresAt<=Date.now())&&typeof n.owner==`string`&&!(!Rt(n.expiredAtMs)||!Rt(n.idleExpiryMs))&&(n.deviceKey===void 0||typeof n.deviceKey==`string`))return n}function Rt(e){return typeof e==`number`&&Number.isFinite(e)&&e>=0}function zt(t){let n=t.flatMap((e,t)=>e.command===`open`?[t]:[]);if(n.length!==1||n[0]!==0)throw new e(`COMMAND_FAILED`,`Cannot publish this session: an open-to-destination script requires exactly one initial recorded open.`,{retriable:!1,hint:`Close this session and start a fresh one with open <app> --save-script[=<path>].`});if(t.some(e=>e.command===`close`))throw new e(`COMMAND_FAILED`,`Cannot publish an active-session script containing close.`,{retriable:!1,hint:`Close this session and record the journey again from a fresh open --save-script session.`});let r=-1;for(let[e,n]of t.entries())ie({command:n.command,positionals:n.positionals,flags:n.flags})===`mutates-app`&&(r=e);if(!t.slice(r+1).some(Gt))throw new e(`COMMAND_FAILED`,`Cannot publish this session without a portable destination guard after the final mutating action.`,{retriable:!0,hint:`Record a selector-targeted wait on a labeled or id-bearing landmark, for example wait 'role="heading" label="Screen X"', so its recorded identity is captured, then retry session save-script.`})}function Bt(t){for(let n of t){if(Vt(n)){Ht(n);continue}let t=Kt(n),r=t??(n.command===`wait`?n.positionals[0]:void 0);if(r?.startsWith(`@`))throw new e(`COMMAND_FAILED`,`Cannot publish recorded step "${n.command} ${r}": the session-local ref was not converted to a portable selector.`,{retriable:!1,hint:`Close this session and record the journey again using selectors or resolvable refs.`});if(n.command===`find`&&ie(n)===`mutates-app`)throw new e(`COMMAND_FAILED`,`Cannot publish a recorded mutating find step because its target identity is not replay-verifiable.`,{retriable:!1,hint:`Close this session and record the journey again with an explicit selector-targeted click, press, fill, or focus action.`});let i=t;if(!(!i||!u(i)||n.targetEvidence))throw new e(`COMMAND_FAILED`,`Cannot publish recorded step "${n.command} ${i}": recording-time target identity evidence is missing.`,{retriable:!1,hint:`Close this session and record the journey again from open --save-script so target-v1 evidence is captured before each interaction.`})}}function Vt(e){return Ut(e)!==void 0}function Ht(t){let n=Ut(t);if(!n)return;let r=[n.source,n.destination];for(let n of r){if(n?.startsWith(`@`))throw new e(`COMMAND_FAILED`,`Cannot publish recorded drag endpoint "${n}": the session-local ref was not converted to a portable selector.`,{retriable:!1});if(!(!n||!u(n))&&!t.targetEvidences)throw new e(`COMMAND_FAILED`,`Cannot publish recorded drag endpoint "${n}": recording-time target identity evidence is missing.`,{retriable:!1,hint:`Close this session and record the journey again so targets-v1 evidence is captured for both drag endpoints.`})}}function Ut(e){return e.command===`gesture`?ye(e.positionals):void 0}function Wt(t,n){if(t instanceof e){if(t.details?.reason===`script_target_exists`)return new e(t.code,`A file already exists at ${String(t.details.path)}.`,{...t.details,retriable:!0,hint:`Retry session save-script with another path, or pass --force to replace the existing file. The session remains armed.`});let n=t.details?.retriable===!0;return new e(t.code,t.message,{...t.details,retriable:n,hint:t.details?.hint??(n?`Fix the recorded journey or target, then retry session save-script. The session remains armed.`:`Close this session and start a fresh one with open <app> --save-script[=<path>].`)})}let r=t instanceof Error?t.message:String(t);return new e(`COMMAND_FAILED`,`Failed to publish the active session script${n?` to ${n}`:``}: ${r}`,{retriable:!0,hint:`Check the target path and permissions, then retry session save-script. The session remains armed.`})}function Gt(e){if(e.command!==`wait`)return!1;let t=se(e.positionals);return t?.kind!==`selector`||!u(t.selectorExpression)?!1:e.targetEvidence?.verification===`verified`}function Kt(e){if(e.command===`get`)return e.positionals[1];if(fe(e.command)||e.command===`fill`){let[t,n]=e.positionals;return t!==void 0&&n!==void 0&&qt(t)&&qt(n)?void 0:t}}function qt(e){return e.trim().length>0&&Number.isFinite(Number(e))}function Jt(e){let t=e.scriptPublication??m;return t.kind===`repair`?t.status===`committed`||!h(t):!1}function Yt(e){return!be(e.scriptPublication??m)||Jt(e)}var Xt=class{sessionsDir;constructor(e){this.sessionsDir=e}write(e,t){let n=xt(e),r=t?.publication===`active`,i;try{if(Yt(e))return{written:!1};let a=Zt(e,{appendCompleteSentinel:n,activePublication:r});i=this.resolveScriptPath(e);let o=b.dirname(i);return y.existsSync(o)||y.mkdirSync(o,{recursive:!0}),en({scriptPath:i,script:a.script,force:t?.force}),n&&(e.scriptPublication=ze(e.scriptPublication??m)),{written:!0,path:i,actionCount:a.actionCount}}catch(t){return Qt({session:e,error:t,scriptPath:i,repairArmed:n,activePublication:r})}}resolveScriptPath(e){let t=Ne(e.scriptPublication??m);if(t)return Ze(t);let n=Xe(e.name),r=new Date(e.createdAt).toISOString().replaceAll(/[:.]/g,`-`);return b.join(this.sessionsDir,`${n}-${r}.ad`)}};function Zt(e,t){let n=tn(e,{strictPortableRefs:t.activePublication});return t.activePublication&&zt(n),{script:fn(e,n,t.appendCompleteSentinel),actionCount:n.length}}function Qt(t){let{session:n,error:r,scriptPath:i,repairArmed:o,activePublication:s}=t;if(a({level:`warn`,phase:`session_script_write_failed`,data:{session:n.name,path:i,error:r instanceof Error?r.message:String(r)}}),o)return{written:!1,error:$t(r,i)};if(s)return{written:!1,error:Wt(r,i)};if(r instanceof e)throw r;return{written:!1}}function $t(t,n){if(t instanceof e)return t;let r=t instanceof Error?t.message:String(t);return new e(`COMMAND_FAILED`,`Failed to write the healed script${n?` to ${n}`:``}: ${r}`,{hint:`The repair transaction completed but the healed .ad could not be published; check the target path and permissions, then retry close --save-script.`})}function en(t){let{scriptPath:n,script:r,force:i}=t;try{qe({destination:n,contents:r,publish:i?`replace`:`link-exclusive`})}catch(t){throw t.code===`EEXIST`?new e(`COMMAND_FAILED`,`A file already exists at ${n}; remove it, pass replay --save-script=<other-path>, or pass --force/--overwrite to replace it.`,{reason:`script_target_exists`,path:n}):t}}function tn(e,t={}){let n=S(e),r=n!==void 0,i=e.actions.slice(n??0),a=[];for(let n of i){if(n.command===`snapshot`)continue;let i=an(n);if(i){a.push(i);continue}(r||t.strictPortableRefs)&&nn(n);let o=dn(e,n);o&&a.push(o),a.push(n)}return t.strictPortableRefs&&Bt(a),a}function nn(t){let n=t.command===`gesture`?ye(t.positionals??[]):void 0;if(n){rn(n);return}if(!T(t.command))return;let r=t.command===`get`?t.positionals?.[1]:t.positionals?.[0];if(r?.startsWith(`@`))throw new e(`COMMAND_FAILED`,`Cannot write recorded step "${t.command} ${r}" to a script: it never resolved to a selector, so the ref would not resolve in a fresh replay session.`)}function rn(t){let n=[t.source,t.destination].find(e=>e.startsWith(`@`));if(n)throw new e(`COMMAND_FAILED`,`Cannot write recorded drag endpoint "${n}" to a script: it never resolved to a selector, so the ref would not resolve in a fresh replay session.`)}function an(e){let t=on(e);if(!(!t||!T(e.command)))return pe(e.command)||e.command===`hover`?{...e,positionals:[t]}:e.command===`longpress`?cn(e,t):e.command===`fill`?sn(e,t):ln(e,t)}function on(e){let t=Array.isArray(e.result?.selectorChain)&&e.result.selectorChain.every(e=>typeof e==`string`)?e.result.selectorChain:[];return t.length>0?t.join(` || `):void 0}function T(e){return fe(e)||e===`fill`||e===`get`}function sn(e,t){let n=we(e);return n.length>0?{...e,positionals:[t,n]}:void 0}function cn(e,t){let n=typeof e.result?.durationMs==`number`?String(e.result.durationMs):un(e.positionals??[]);return{...e,positionals:n?[t,n]:[t]}}function ln(e,t){let n=e.positionals?.[0];return n===`text`||n===`attrs`?{...e,positionals:[n,t]}:void 0}function un(e){let t=e.at(-1);if(!(e.length<=1||t===void 0||t.trim()===``))return Number.isFinite(Number(t))?t:void 0}function dn(e,t){if(!T(t.command))return;let n=t.result?.refLabel;if(typeof n!=`string`||n.trim().length===0)return;let r=n.trim();return{ts:t.ts,command:`snapshot`,positionals:[],flags:{platform:e.device.platform,snapshotInteractiveOnly:!0,snapshotScope:r},result:{scope:r}}}function fn(e,t,n){let r=[],i=e.device.kind?` kind=${e.device.kind}`:``;r.push(`context platform=${ne(e.device)} device=${ge(e.device.name)}${i} theme=unknown`);for(let e of t)e.flags?.noRecord||(r.push(...mt(e)),r.push(pn(e)));return n&&r.push(`# agent-device:heal-complete`),`${r.join(`
2
2
  `)}\n`}function pn(e){return mn([e.command],e)||pt(e)}function mn(e,t){if(pe(t.command))return hn(e,t);if(t.command===`fill`)return gn(e,t);if(t.command===`get`)return _n(e,t)}function hn(e,t){let n=t.positionals?.[0];if(n){if(n.startsWith(`@`))return e.push(f(d(n))),E(e,t),p(e,t),e.join(` `);if(t.positionals.length===1)return e.push(f(n)),p(e,t),e.join(` `)}}function gn(e,t){let n=t.positionals?.[0];if(!n?.startsWith(`@`))return;e.push(f(d(n))),E(e,t);let r=t.positionals.slice(1).join(` `);return t.positionals.length>1&&e.push(f(r)),p(e,t),e.join(` `)}function _n(e,t){let n=t.positionals?.[0],r=t.positionals?.[1];if(!(!n||!r))return e.push(f(n)),e.push(f(d(r))),r.startsWith(`@`)&&E(e,t),e.join(` `)}function E(e,t){let n=t.result?.refLabel;typeof n==`string`&&n.trim().length>0&&e.push(f(n))}const vn=[`id`,`deviceId`,`device_id`,`serial`,`udid`,`device_udid`,`identifier`],yn={ios:`iOS`,ipados:`iPadOS`,tvos:`tvOS`,watchos:`watchOS`,visionos:`visionOS`,macos:`macOS`,apple:`Apple`,android:`Android`,linux:`Linux`,web:`Web`};function bn(e,t){let n=t??{};switch(e.command){case g.devices:return xn(n.devices);case g.apps:return Sn(n.apps,e.flags?.appsFilter);case g.boot:return Cn(`Booted`,n,!0);case g.shutdown:return Cn(`Shut down`,n,!1);case g.install:return wn(`Installed`,n);case g.reinstall:return wn(`Reinstalled`,n);case g.screenshot:return Tn(e,n);default:return{}}}function xn(e){if(!Array.isArray(e))return{};let t=e.flatMap(e=>{let t=Dn(e);return t?[t]:[]}),n=t.slice(0,5),r=Math.max(0,t.length-n.length),i=t.slice(0,3);return{summary:In(`Found ${t.length} ${Ln(`device`,t.length)}`,i.map(e=>Pn(e,!0)),Math.max(0,t.length-i.length)),details:{deviceCount:t.length,devices:n,...r>0?{omittedDeviceCount:r}:{}}}}function Sn(e,t){if(!Array.isArray(e))return{};let n=e.flatMap(e=>{let t=k(e);return t?[t]:[]}),r=n.slice(0,5),i=Math.max(0,n.length-r.length),a=n.slice(0,3);return{summary:In(`Found ${n.length} ${Ln(`app`,n.length)}`,a,Math.max(0,n.length-a.length)),details:{appCount:n.length,apps:r,...i>0?{omittedAppCount:i}:{},...t===`all`||t===`user-installed`?{filter:t}:{}}}}function Cn(e,t,n){let r=On(t);if(!r)return{};let i={device:r,...Nn(t),booted:n};return{summary:`${e} ${Pn(i,!1)}`,details:i}}function wn(e,t){let n=k(t.appName),r=k(t.bundleId),i=D(t,[`packageName`,`package`]),a=k(t.platform),o=k(t.launchTarget),s=D(t,[`bundleId`,`packageName`,`package`,`appId`,`launchTarget`]),c=Fn(n,s);if(!c)return{};let l={};return O(l,`appName`,n),O(l,`bundleId`,r),O(l,`packageName`,i),O(l,`platform`,a),o!==s&&O(l,`launchTarget`,o),{summary:`${e} ${c}`,details:l}}function Tn(e,t){let n=En(e,t);return n?{details:{requestedFileName:n}}:{}}function En(e,t){let n=F(e.meta?.clientArtifactPaths?.path)??F(t.path);if(n)return P(n)}function Dn(e){if(!n(e))return;let t=On(e);if(t)return{name:t,...Nn(e)}}function On(e){let t=D(e,[`name`,`deviceName`,`device`]);return!t||!kn(e,t)?t:jn(e)}function kn(e,t){let n=An(t);return vn.some(t=>{let r=k(e[t]);return r!==void 0&&An(r)===n})}function An(e){return e.toLowerCase()}function jn(e){let t=k(e.appleOs),n=k(e.platform),r=k(e.kind),i=Mn(t,n);return i&&(r===`simulator`||r===`emulator`)?`${i} ${r}`:i?`${i} device`:r===`simulator`?`Simulator`:r===`emulator`?`Emulator`:`Unnamed device`}function Mn(e,t){let n=e??t;if(!(!n||!Object.hasOwn(yn,n)))return yn[n]}function Nn(e){let t=k(e.platform),n=k(e.appleOs),r=k(e.kind),i=k(e.target);return{...t?{platform:t}:{},...n?{appleOs:n}:{},...r?{kind:r}:{},...i?{target:i}:{},...typeof e.booted==`boolean`?{booted:e.booted}:{}}}function Pn(e,t){let n=k(e.name)??k(e.device)??`device`,r=k(e.platform),i=k(e.appleOs),a=[r,i===r?void 0:i,k(e.kind),k(e.target),t&&typeof e.booted==`boolean`?e.booted?`booted`:`stopped`:void 0].filter(e=>!!e);return a.length>0?`${n} (${a.join(`, `)})`:n}function Fn(e,t){return e&&t&&e!==t?`${e} (${t})`:e??t}function D(e,t){for(let n of t){let t=k(e[n]);if(t)return t}}function O(e,t,n){n&&(e[t]=n)}function In(e,t,n){let r=[...t,...n>0?[`+${n} more`]:[]];return r.length>0?`${e}: ${r.join(`, `)}`:e}function Ln(e,t){return t===1?e:`${e}s`}function k(e){let t=F(e);if(!t)return;let n=t.trim(),r=Array.from(n);return r.length<=120?n:`${r.slice(0,119).join(``)}…`}function A(e){return k(e)}function j(e){return typeof e==`boolean`?e:void 0}function M(e,t){let n=A(e);return n&&t.includes(n)?n:void 0}function N(e){return Object.fromEntries(Object.entries(e).filter(([,e])=>e!==void 0))}function P(e){let t=F(e);return t?k(t.split(/[\\/]/).at(-1)):void 0}function F(e){if(typeof e==`string`)return e.trim().length>0?e:void 0}function I(e){return typeof e==`number`&&Number.isFinite(e)?e:void 0}const Rn=[`up`,`down`,`left`,`right`],zn=[`top`,`bottom`];function Bn(e){return`${e.command===g.reinstall?`Reinstalled`:`Installed`} ${Wn(e.result??{})??`app`}`}function Vn(e){let t=e.result??{};switch(e.command){case g.scroll:return Kn(t);case g.screenshot:return Yn(t);case g.home:return`Went home`;case g.back:return Zn(t);case g.appSwitcher:return`Opened app switcher`;case g.actionButton:return`Pressed Action Button`;case g.orientation:return $n(t);case g.fold:return Qn(t);case g.viewport:return er(t);case g.clipboard:return tr(t);case g.keyboard:return nr(t);case g.tvRemote:return ar(t);case g.gesture:return or(t);case g.swipe:return sr(t);case g.trace:return lr(`trace`,e);case g.record:return lr(`recording`,e);default:return}}function Hn(e){let t=e.result??{};switch(e.command){case g.scroll:return N({direction:M(t.direction,Rn),edge:M(t.edge,zn),passes:I(t.passes),amount:I(t.amount),pixels:I(t.pixels),durationMs:I(t.durationMs),x1:I(t.x1),y1:I(t.y1),x2:I(t.x2),y2:I(t.y2)});case g.screenshot:return N({requestedFileName:Xn(t)});case g.back:return N({mode:M(t.mode,v)});case g.orientation:return N({orientation:M(t.orientation,Ke)});case g.fold:return N({pose:M(t.pose,Ge)});case g.viewport:return N({width:I(t.width),height:I(t.height)});case g.clipboard:return N({action:M(t.action,[`read`,`write`])});case g.keyboard:return ir(t);case g.tvRemote:return N({button:M(t.button,Je),durationMs:I(t.durationMs)});case g.gesture:case g.swipe:return cr(t);case g.trace:case g.record:return N({action:M(t.action,[`start`,`stop`]),fileName:dr(e),showTouches:j(t.showTouches)});default:return{}}}function Un(e,t){if(e.command!==g.screenshot)return t;let n=En(e,t);return n?{...t,requestedFileName:n}:t}function Wn(e){let t=A(e.appName),n=fr(e,[`bundleId`,`packageName`,`appBundleId`,`launchTarget`]);return t&&n&&t!==n?`${t} (${n})`:t??n??Gn(e)}function Gn(e){let t=A(e.app);return t&&!t.includes(`/`)&&!t.includes(`\\`)?t:void 0}function Kn(e){let t=M(e.direction,Rn),n=M(e.edge,zn),r=I(e.passes);return n?qn(n,r):t?Jn(t,e):`Scrolled`}function qn(e,t){return t===0?`Already at ${e}`:t===void 0?`Scrolled to ${e}`:`Scrolled to ${e} in ${t} ${t===1?`pass`:`passes`}`}function Jn(e,t){let n=I(t.pixels);if(n!==void 0)return`Scrolled ${e} by ${n}px`;let r=I(t.amount);return r===void 0?`Scrolled ${e}`:`Scrolled ${e} by ${r}`}function Yn(e){let t=Xn(e);return t?`Captured screenshot ${t}`:`Captured screenshot`}function Xn(e){return P(e.requestedFileName)??P(e.path)}function Zn(e){return M(e.mode,v)===`system`?`Went back using system navigation`:`Went back`}function Qn(e){let t=M(e.pose,Ge);return t?`Folded to ${t}`:`Changed fold pose`}function $n(e){let t=M(e.orientation,Ke);return t?j(e.confirmed)===!1?`Requested ${t} (unconfirmed)`:`Rotated to ${t}`:`Changed orientation`}function er(e){let t=I(e.width),n=I(e.height);return t!==void 0&&n!==void 0?`Set viewport to ${t}×${n}`:`Changed viewport`}function tr(e){let t=M(e.action,[`read`,`write`]);return t===`read`?`Read clipboard`:t===`write`?`Updated clipboard`:`Used clipboard`}function nr(e){let t=F(e.action);if(!t||!it(t))return`Used keyboard`;if(t===`dismiss`)return rr(e);if(t===`enter`||t===`return`)return`Pressed keyboard return`;let n=j(e.visible);return n===void 0?`Inspected keyboard`:n?`Keyboard is visible`:`Keyboard is hidden`}function rr(e){return j(e.dismissed)===!1?`Keyboard was already hidden`:`Dismissed keyboard`}function ir(e){let t=F(e.action);return N({action:t&&it(t)?t:void 0,platform:M(e.platform,[`ios`,`android`]),visible:j(e.visible),wasVisible:j(e.wasVisible),dismissed:j(e.dismissed),attempts:I(e.attempts),mechanism:M(e.mechanism,[`dismissKey`])})}function ar(e){let t=M(e.button,Je);return t?`Pressed TV remote ${t}`:`Used TV remote`}function or(e){let t=M(e.kind,[`fling`,`pan`,`pinch`,`rotate`,`transform`]);return t?`Ran ${t} gesture`:`Ran gesture`}function sr(e){let t=I(e.count);return t!==void 0&&t>1?`Swiped ${t} times`:`Swiped`}function cr(e){return N({kind:M(e.kind,[`fling`,`pan`,`pinch`,`rotate`,`transform`]),durationMs:I(e.durationMs),pointerCount:I(e.pointerCount),x1:I(e.x1),y1:I(e.y1),x2:I(e.x2),y2:I(e.y2),count:I(e.count),pauseMs:I(e.pauseMs),pattern:M(e.pattern,[`one-way`,`ping-pong`]),scale:I(e.scale)})}function lr(e,t){let n=ur(e,M(t.result?.action,[`start`,`stop`])),r=dr(t);return r?`${n} ${r}`:n}function ur(e,t){return t===`start`?e===`trace`?`Started trace`:`Started recording`:t===`stop`?e===`trace`?`Stopped trace`:`Stopped recording`:e===`trace`?`Updated trace`:`Updated recording`}function dr(e){let t=e.result??{};return P(t.requestedFileName)??P(t.outPath)??P(t.path)??P(e.positionals[1])}function fr(e,t){for(let n of t){let t=A(e[n]);if(t)return t}}function pr(e){switch(e.command){case g.open:return`Opened ${L(e)??`session`}`;case g.close:return`Closed ${A(e.result?.session)??`session`}`;case g.click:case g.press:return`Tapped ${L(e)??`target`}`;case g.longPress:return`Long pressed ${L(e)??`target`}`;case g.hover:return`Hovered ${L(e)??`target`}`;case g.fill:return`Filled ${L(e)??`target`}`;case g.type:return`Typed text`;case g.install:case g.reinstall:case _.installSource:return Bn(e);default:return Vn(e)??`Ran ${e.command}`}}function mr(e){return N({command:e.command,positionals:Cr(e),flags:Fr(e),...hr(e),...gr(e),..._r(e),...Hn(e)})}function hr(e){if(!vr(e.command))return{};let t=e.result??{};return N({ref:H(t),targetLabel:L(e),selectorChainLength:jr(t.selectorChain)?.length,x:I(t.x),y:I(t.y),x2:I(t.x2),y2:I(t.y2),durationMs:I(t.durationMs)})}function gr(e){if(!yr(e.command))return{};let t=e.result??{};return N({platform:M(t.platform,s),target:M(t.target,te),appName:A(t.appName),appBundleId:A(t.appBundleId),bundleId:A(t.bundleId),packageName:A(t.packageName),launchTarget:A(t.launchTarget)})}function _r(e){let t=e.result??{};return e.command===g.snapshot?Array.isArray(t.nodes)?{nodeCount:t.nodes.length}:{}:e.command!==g.wait&&e.command!==g.find&&e.command!==g.get&&e.command!==g.is?{}:N({waitedMs:I(t.waitedMs),found:j(t.found)})}function vr(e){return e===g.click||e===g.press||e===g.longPress||e===g.hover||e===g.focus||e===g.fill}function yr(e){return e===g.open||e===g.install||e===g.reinstall||e===_.installSource}function L(e){let t=e.result??{};return br(t)??xr(t)??Sr(t)??kr(e.positionals[0])}function br(e){let t=H(e);if(t)return t.startsWith(`@`)?t:`@${t}`}function xr(e){let t=I(e.x),n=I(e.y);if(t!==void 0&&n!==void 0)return`(${t}, ${n})`}function Sr(e){return A(e.appName)??A(e.appBundleId)??A(e.bundleId)??A(e.packageName)}function Cr(e){if(e.positionals.length!==0)return e.command===g.type?[z(`text`)]:e.command===g.fill?wr(e):e.command===g.find?Tr(e):e.command===g.clipboard?Er(e):e.command===g.push?Dr(e,`app`,`payload`):e.command===g.triggerAppEvent?Dr(e,`event`,`payload`):e.positionals.map(R)}function wr(e){let t=z(`text`),n=e.result??{},r=H(n);if(r)return[`@${r}`,t];if(A(n.selector))return[z(`target`),t];let i=I(n.x),a=I(n.y);return i!==void 0&&a!==void 0?[String(i),String(a),t]:[t]}function Tr(e){let t=+!!Ar(e.positionals[0]);if(e.positionals[t]===void 0)return;let n=t+1,r=[...t===1?[String(e.positionals[0])]:[],z(`query`)],i=e.positionals[n];return i?i===`fill`||i===`type`?[...r,i,z(`text`)]:[...r,...e.positionals.slice(n).map(Or)]:r}function Er(e){let t=e.positionals[0]?.toLowerCase();return t===`read`?[`read`]:t===`write`?[`write`,z(`text`)]:e.positionals.map(R)}function Dr(e,t,n){let[r,i,...a]=e.positionals;return[...r?[z(t)]:[],...i?[z(n)]:[],...a.map(R)]}function Or(e){return e===`click`||e===`focus`||e===`exists`||e===`get`||e===`text`||e===`attrs`||e===`wait`?e:R(e)}function R(e){return kr(e)??z(`arg`)}function kr(e){if(!e)return;let t=e.trim();if(/^@[a-zA-Z0-9:_-]+$/.test(t))return t}function z(e){return`<${e}>`}function Ar(e){return e===`text`||e===`label`||e===`value`||e===`role`||e===`id`}function jr(e){return Array.isArray(e)&&e.every(e=>typeof e==`string`)?e:void 0}const Mr={enums:[{source:`platform`,values:l},{source:`target`,values:te}]},Nr={booleans:[{source:`settle`}],numbers:[{source:`settleQuietMs`}]},Pr={[g.open]:{booleans:[{source:`relaunch`},{source:`testIme`}],enums:[{source:`surface`,values:He}]},[g.click]:B(),[g.press]:B(),[g.longPress]:B(),[g.hover]:B(),[g.fill]:Lr(),[g.type]:Lr(),[g.scroll]:{numbers:[{source:`pixels`},{source:`durationMs`}]},[g.gesture]:Rr(),[g.swipe]:Rr(),[g.screenshot]:{booleans:[{source:`overlayRefs`},{source:`screenshotFullscreen`,output:`fullscreen`},{source:`screenshotNoStabilize`,output:`noStabilize`},{source:`screenshotNormalizeStatusBar`,output:`normalizeStatusBar`}],numbers:[{source:`screenshotPixelDensity`,output:`pixelDensity`},{source:`screenshotScale`,output:`scale`}]},[g.snapshot]:{booleans:[{source:`snapshotInteractiveOnly`,output:`interactiveOnly`},{source:`snapshotDiff`,output:`diff`},{source:`snapshotRaw`,output:`raw`},{source:`snapshotCustomActions`,output:`actions`},{source:`snapshotForceFull`,output:`forceFull`}],numbers:[{source:`snapshotDepth`,output:`depth`}]},[g.back]:{enums:[{source:`backMode`,output:`mode`,values:v}]},[g.record]:{booleans:[{source:`hideTouches`}],numbers:[{source:`fps`}],enums:[{source:`recordingScope`,output:`scope`,values:ce}]},[g.apps]:{enums:[{source:`appsFilter`,output:`filter`,values:[`user-installed`,`all`]}]},[g.boot]:{booleans:[{source:`headless`}]},[g.close]:{booleans:[{source:`shutdown`}]}};function Fr(e){let t=e.flags??{},n={},r=Object.hasOwn(Pr,e.command)?Pr[e.command]:void 0;return V(n,t,Mr),V(n,t,r),V(n,t,Ir(e.command)),Object.keys(n).length>0?n:void 0}function Ir(e){return oe(e)?Nr:void 0}function B(){return{booleans:[{source:`doubleTap`}],numbers:[{source:`count`},{source:`intervalMs`},{source:`holdMs`},{source:`jitterPx`}],enums:[{source:`clickButton`,values:We}]}}function Lr(){return{numbers:[{source:`delayMs`}]}}function Rr(){return{numbers:[{source:`pointerCount`},{source:`count`},{source:`pauseMs`}],enums:[{source:`pattern`,values:le}]}}function V(e,t,n){n&&(zr(e,t,n.booleans??[]),Br(e,t,n.numbers??[]),Vr(e,t,n.enums??[]))}function zr(e,t,n){for(let r of n)Hr(e,r.output??r.source,t[r.source])}function Br(e,t,n){for(let r of n)Ur(e,r.output??r.source,t[r.source])}function Vr(e,t,n){for(let r of n)Wr(e,r.output??r.source,t[r.source],r.values)}function H(e){let t=A(e.ref);if(!t)return;let n=t.startsWith(`@`)?t.slice(1):t;return/^[a-zA-Z0-9:_-]+$/.test(n)?n:void 0}function Hr(e,t,n){typeof n==`boolean`&&(e[t]=n)}function Ur(e,t,n){let r=I(n);r!==void 0&&(e[t]=r)}function Wr(e,t,n,r){let i=M(n,r);i!==void 0&&(e[t]=i)}const Gr=65536;function Kr(e){return dt(`sha256`).update(e,`utf8`).digest(`hex`).slice(0,32)}function U(e,t){let n=Xr(e);if(n===void 0)return!1;try{let e=Jr(t),r=Buffer.allocUnsafe(Gr),i=0;do if(i=y.readSync(n,r,0,r.length,null),!e.push(r.subarray(0,i)))return!0;while(i>0);return e.end(),!0}finally{y.closeSync(n)}}async function qr(e){let t=await Zr(e);if(t===void 0)return{lineCount:0,firstLineDigest:void 0};let n={lineCount:0,firstLineDigest:void 0};try{let e=Jr(e=>{n.lineCount===0&&(n.firstLineDigest=Kr(e)),n.lineCount+=1}),r=Buffer.allocUnsafe(Gr);for(;;){let{bytesRead:n}=await t.read(r,0,r.length,null);if(e.push(r.subarray(0,n)),n===0)break}return e.end(),n}finally{await t.close()}}function W(e){let t;return U(e,e=>(t=Kr(e),!1)),t}function Jr(e){let t=new ft(`utf8`),n=``,r=!1;return{push(i){if(r)return!1;let a=`${n}${t.write(i)}`,o=0;for(let t=a.indexOf(`
3
3
  `);t!==-1;t=a.indexOf(`
4
4
  `,o)){if(Yr(a.slice(o,t),e)===!1)return r=!0,!1;o=t+1}return n=a.slice(o),!0},end(){r||Yr(`${n}${t.end()}`,e)}}}function Yr(e,t){let n=e.endsWith(`\r`)?e.slice(0,-1):e;if(n.trim().length!==0)return t(n)}function Xr(e){try{return y.openSync(e,`r`)}catch(e){if(e.code===`ENOENT`)return;throw e}}async function Zr(e){try{return await y.promises.open(e,`r`)}catch(e){if(e.code===`ENOENT`)return;throw e}}const Qr=5242880;function $r(e=process.env){let t=e.AGENT_DEVICE_EVENT_LOG_MAX_BYTES?.trim();if(t===void 0||!/^\d+$/.test(t))return Qr;let n=Number(t);return Number.isSafeInteger(n)&&n>0?n:Qr}function G(e){return`${e}.1`}function K(e){return`${e}.window.json`}function ei(e){let t;for(let n=0;n<3;n+=1){let n=J(e);try{let t=ti(e);if(J(e)===n)return t}catch(r){if(t=r,J(e)===n)throw r}}throw t??q(e,`the window did not settle while reading`)}function ti(e){let t=G(e),n=X(e);if(n===`unverifiable`)throw q(e,`window file is invalid`);if(n===void 0)return ni(e,t);let r=n.at(-1);if(!r)throw q(e,`window file records no generation`);let i=ui(e),a=ri(e,r),o=[],s=ii({eventLogPath:e,rotatedPath:t,sidecar:n,activeStart:a,activeExists:i});return s!==void 0&&o.push({path:t,firstLineIndex:s}),i&&o.push({path:e,firstLineIndex:a}),{files:o,earliestCursor:o[0]?.firstLineIndex??a}}function ni(e,t){if(W(t)!==void 0)throw q(e,`a rotated event log exists with no window record`);return{files:ui(e)?[{path:e,firstLineIndex:0}]:[],earliestCursor:0}}function ri(e,t){let n=W(e);return n!==void 0&&n===t.firstLineDigest?t.firstLineIndex:t.firstLineIndex+t.lineCount}function ii(e){let{eventLogPath:t,rotatedPath:n,sidecar:r,activeStart:i,activeExists:a}=e,o=W(n);if(o===void 0)return;let s=r.find(e=>e.firstLineDigest===o);if(!s)throw q(t,`the rotated event log matches no window record`);let c=si(n);if(c!==s.lineCount)throw q(t,`the rotated event log holds ${c} lines, the window recorded ${s.lineCount}`);if(a&&s.firstLineIndex+s.lineCount!==i)throw q(t,`retained event log generations are not contiguous`);return s.firstLineIndex}async function ai(e,t){let n=di(e);if(!n||n.size<t)return!1;let r=X(e);if(r===`unverifiable`)return await y.promises.rename(e,G(e)),!0;let i=await qr(e);if(i.firstLineDigest!==void 0){let t=r??[],n=t.at(-1),a=n&&n.firstLineDigest===i.firstLineDigest?n:{firstLineIndex:n?n.firstLineIndex+n.lineCount:0,lineCount:i.lineCount,firstLineDigest:i.firstLineDigest};await li(e,(a===n?t:[...t,a]).slice(-2))}return await y.promises.rename(e,G(e)),!0}function oi(t,n){if(!(t>=n))throw new e(`COMMAND_FAILED`,`events cursor ${t} precedes the retained event log window; events before cursor ${n} were rotated out.`,{reason:`EVENT_LOG_CURSOR_EXPIRED`,cursor:t,earliestCursor:n,hint:`Resume with cursor ${n}, the oldest retained event; earlier events are no longer available.`})}function q(t,n){return new e(`COMMAND_FAILED`,`Session event log window cannot be verified: ${n}.`,{reason:`EVENT_LOG_WINDOW_UNVERIFIED`,path:t,hint:`Cursor positions for this session cannot be resolved. Delete ${t}, ${G(t)}, and ${K(t)} to restart the timeline, or read the files directly.`})}function si(e){let t=0;return U(e,()=>{t+=1}),t}function J(e){return[Y(K(e)),Y(e),Y(G(e))].join(`|`)}function Y(e){try{let t=y.lstatSync(e);return`${t.ino}:${t.size}:${t.mtimeMs}`}catch{return`absent`}}function X(e){let t;try{t=y.readFileSync(K(e),`utf8`)}catch(e){return e.code===`ENOENT`?void 0:`unverifiable`}try{let e=JSON.parse(t);if(!n(e)||e.version!==2)return`unverifiable`;let{generations:r}=e;if(!Array.isArray(r)||r.length===0)return`unverifiable`;let i=r.map(ci);return i.every(e=>e!==void 0)?i:`unverifiable`}catch{return`unverifiable`}}function ci(e){if(!n(e))return;let{firstLineIndex:t,lineCount:r,firstLineDigest:i}=e;if(!(!Number.isSafeInteger(t)||t<0)&&!(!Number.isSafeInteger(r)||r<0)&&typeof i==`string`&&i.length!==0)return{firstLineIndex:t,lineCount:r,firstLineDigest:i}}async function li(e,t){let n=K(e),r=`${n}.${process.pid}.tmp`;await y.promises.writeFile(r,JSON.stringify({version:2,generations:t}),`utf8`),await y.promises.rename(r,n)}function ui(e){return di(e)!==void 0}function di(t){try{let n=y.lstatSync(t);if(n.isSymbolicLink())throw new e(`COMMAND_FAILED`,`Session event log must not be a symbolic link: ${t}`);return n}catch(e){if(e.code===`ENOENT`)return;throw e}}const Z=new Map,fi=new Set;function pi(e){return b.join(e,`events.ndjson`)}function mi(e){return e.command!==g.events}function hi(e,n,r){let i=t({version:1,ts:r.ts??new Date().toISOString(),session:n,...r});_i(e,`${JSON.stringify(i)}\n`)}async function gi(e){await(e?Z.get(e):Promise.all(Z.values()))}function _i(e,t){let n=(Z.get(e)??Promise.resolve()).catch(()=>void 0).then(async()=>{await vi(e),await ai(e,$r()),await y.promises.appendFile(e,t,`utf8`)}).catch(t=>{a({level:`warn`,phase:`session_event_log_write_failed`,data:{path:e,error:t instanceof Error?t.message:String(t)}})}).finally(()=>{Z.get(e)===n&&Z.delete(e)});Z.set(e,n)}async function vi(e){let t=b.dirname(e);if(!fi.has(t))try{await y.promises.mkdir(t,{recursive:!0}),fi.add(t)}catch(t){throw a({level:`warn`,phase:`session_event_log_dir_failed`,data:{path:e,error:t instanceof Error?t.message:String(t)}}),t}}function yi(e,t,n){hi(e,t,{kind:`action.recorded`,requestId:r().requestId,command:n.command,summary:pr(n),details:mr(n)})}function bi(e){let{req:t}=e;return{kind:`request.started`,requestId:t.meta?.requestId??r().requestId,command:t.command,summary:`Started ${t.command}`}}function xi(e){let{req:t,response:n,durationMs:i}=e;if(n.ok){let e=bn(t,n.data);return{kind:`request.finished`,requestId:t.meta?.requestId??r().requestId,command:t.command,status:`ok`,summary:e.summary??`Finished ${t.command}`,details:{durationMs:i,...e.details}}}return{kind:`request.finished`,requestId:t.meta?.requestId??r().requestId,command:t.command,status:`error`,summary:`Failed ${t.command}: ${n.error.code}`,details:{durationMs:i,code:n.error.code,diagnosticId:n.error.diagnosticId}}}function Si(e,t={}){let n=wi(t.cursor),r=Ti(t.limit),i=ei(e);oi(n,i.earliestCursor);let a=Ci(i.files,n,r),o=a.lines.flatMap(e=>{let t=Ei(e);return t?[t]:[]});return{path:e,cursor:String(n),limit:r,events:o,...a.nextCursor===void 0?{}:{nextCursor:String(a.nextCursor)}}}function Ci(e,t,n){let r=[],i;for(let a of e){let e=a.firstLineIndex;if(U(a.path,a=>{if(e>=t+n)return i=t+n,!1;e>=t&&r.push(a),e+=1}),i!==void 0)break}return{lines:r,...i===void 0?{}:{nextCursor:i}}}function wi(t){if(t===void 0||t.trim()===``)return 0;let n=Number(t);if(Number.isInteger(n)&&n>=0)return n;throw new e(`INVALID_ARGS`,`events cursor must be a non-negative integer string.`)}function Ti(t){if(t===void 0||typeof t==`string`&&t.trim()===``)return 100;let n=typeof t==`string`?Number(t):t;if(Number.isInteger(n)&&n>=1&&n<=500)return n;throw new e(`INVALID_ARGS`,`events limit must be between 1 and 500.`)}function Ei(e){try{let t=Di(JSON.parse(e));return t?Oi(t):void 0}catch{return}}function Di(e){if(n(e)&&e.version===1&&typeof e.ts==`string`&&typeof e.session==`string`&&ki(e.kind))return e}function Oi(e){let t=n(e.details)?e.details:void 0;return{version:1,ts:e.ts,session:e.session,kind:e.kind,...typeof e.requestId==`string`?{requestId:e.requestId}:{},...typeof e.command==`string`?{command:e.command}:{},...Ai(e.status)?{status:e.status}:{},...typeof e.summary==`string`?{summary:e.summary}:{},...t?{details:t}:{}}}function ki(e){return e===`request.started`||e===`request.finished`||e===`action.recorded`}function Ai(e){return e===`ok`||e===`error`}const ji=36e5;var Mi=class{sessions=new Map;acceptingSessions=!0;runtimeHints=new Map;sessionsDir;scriptWriter;constructor(e){this.sessionsDir=e,this.scriptWriter=new Xt(e)}get(e){return this.sessions.get(e)?.current}closeAdmission(){this.acceptingSessions=!1}assertAdmissionOpen(t){if(!this.acceptingSessions)throw new e(`COMMAND_FAILED`,`Daemon is shutting down`,{reason:`daemon_shutting_down`,session:t})}assertPublishable(t){if(this.assertAdmissionOpen(t),this.sessions.has(t))throw new e(`COMMAND_FAILED`,`Session address is already occupied`,{reason:`session_address_occupied`,session:t})}publish(e,t){this.assertPublishable(e);let n={current:t};return this.sessions.set(e,n),this.clearIdleExpiryTombstone(e),this.captureRef(e,n)}resolveCurrent(e){let t=this.sessions.get(e.address);return t===e.lifetime?t.current:void 0}refresh(e){let t=this.sessions.get(e.address);return t===e.lifetime?this.captureRef(e.address,t):e}requireCurrent(t){let n=this.resolveCurrent(t);if(!n)throw new e(`COMMAND_FAILED`,`Session lifetime has ended`,{reason:`session_lifetime_ended`,session:t.address,hint:`Open a new session before retrying the command.`});return n}update(e,t){let n=this.requireCurrent(e),r=this.sessions.get(e.address),i=typeof t==`function`?t(n):t,a={...n,...i};return r.current=a,a}retire(e){return this.resolveCurrent(e)?(this.runtimeHints.delete(e.address),this.sessions.delete(e.address)):!1}captureRef(e,t){return Object.freeze({address:e,session:t.current,lifetime:t})}*values(){for(let e of this.sessions.values())yield e.current}toArray(){return Array.from(this.values())}lookup(e){let t=this.sessions.get(e);return t?this.captureRef(e,t):void 0}findByDevice(e){for(let[t,n]of this.sessions)if(n.current.device.id===e)return this.captureRef(t,n)}listRefs(){return Array.from(this.sessions,([e,t])=>this.captureRef(e,t))}getRuntimeHints(e){return this.runtimeHints.get(e)}setRuntimeHints(e,t){t?this.runtimeHints.set(e,t):this.runtimeHints.delete(e)}clearRuntimeHints(e){return this.requireCurrent(e),this.runtimeHints.delete(e.address)}recordAction(e,t){let n=wt(this.requireCurrent(e),t);n&&yi(this.resolveEventLogPath(e.address),e.address,n)}recordEvent(e,t){hi(this.resolveEventLogPath(e),e,t)}readEvents(e,t={}){return Si(this.resolveEventLogPath(e),t)}async flushEvents(e){await gi(e?this.resolveEventLogPath(e):void 0)}writeSessionLog(e,t){let n=this.requireCurrent(e),r=this.scriptWriter.write(n,t);return r.written&&a({level:`info`,phase:`session_script_written`,data:{session:n.name,path:r.path}}),r}finalizeRepairTeardown(e){let t=this.resolveCurrent(e);if(!t)return;this.recordRepairFinalizeCloseIfCommitting(e);let n=this.writeSessionLog(e,{force:je(t,void 0)});St(t)&&(!n.written&&n.error?this.writeRepairTombstone(e,ji,{code:String(n.error.code),message:n.error.message}):this.writeRepairTombstone(e))}recordRepairFinalizeCloseIfCommitting(e){let t=this.requireCurrent(e),n=t.scriptPublication??m;h(n)&&this.recordAction(e,{command:`close`,positionals:[],flags:{},result:{session:t.name,...Ue(`Closed: ${t.name}`)}})}writeRepairTombstone(e,t=ji,n){let r=this.resolveCurrent(e);if(r)try{let i=this.resolveSessionDir(e.address);y.mkdirSync(i,{recursive:!0});let a={owner:e.address,reapedAt:Date.now(),expiresAt:Date.now()+t,...Ct(r)?{sourcePath:Ct(r)}:{},...n?{commitFailure:n}:{}};y.writeFileSync(this.repairTombstonePath(e.address),`${JSON.stringify(a)}\n`)}catch(t){a({level:`warn`,phase:`repair_tombstone_write_failed`,data:{session:e.address,error:t instanceof Error?t.message:String(t)}})}}readRepairTombstone(e){return nt(this.repairTombstonePath(e),e)}clearRepairTombstone(e){rt(this.repairTombstonePath(e),e)}noteSessionActivity(e,t=Date.now()){let n=this.get(e);n&&(n.lastActivityAtMs=t)}writeIdleExpiryTombstone(e,t){try{y.mkdirSync(this.resolveSessionDir(e),{recursive:!0}),y.writeFileSync(w(this.resolveSessionDir(e)),`${JSON.stringify(t)}\n`)}catch(t){a({level:`warn`,phase:`idle_expiry_tombstone_write_failed`,data:{session:e,error:t instanceof Error?t.message:String(t)}})}}readIdleExpiryTombstone(e){if(!Ye(e))return;let t=Lt(w(this.resolveSessionDir(e)));return t?.owner===e?t:void 0}clearIdleExpiryTombstone(e){try{y.rmSync(w(this.resolveSessionDir(e)),{force:!0})}catch(t){a({level:`warn`,phase:`idle_expiry_tombstone_clear_failed`,data:{session:e,error:t instanceof Error?t.message:String(t)}})}}repairTombstonePath(e){return tt(this.resolveSessionDir(e))}defaultTracePath(e){let t=Xe(e.name),n=new Date().toISOString().replaceAll(/[:.]/g,`-`);return b.join(this.sessionsDir,`${t}-${n}.trace.log`)}resolveSessionDir(e){return Qe(this.sessionsDir,e)}resolveDaemonStateDir(){return b.dirname(this.sessionsDir)}ensureSessionDir(e){let t=this.resolveSessionDir(e);return y.mkdirSync(t,{recursive:!0}),t}resolveAppLogPath(e){return $e(this.sessionsDir,e)}resolveAppLogPidPath(e){return et(this.sessionsDir,e)}resolveEventLogPath(e){return pi(this.resolveSessionDir(e))}};async function Q(e){let{resolveInventoryDeviceSelection:t}=await import(`./device-selection-resolver.js`).then(e=>e.t);return await t(e)}const $=new ut;function Ni(t,n){return!ee(n)&&t instanceof e&&t.code===`DEVICE_NOT_FOUND`}function Pi(e,t){return!ee(e)&&(!e.platform||e.platform===`apple`||e.platform===`ios`)&&e.target!==`desktop`&&(!t||t.kind===`device`)}async function Fi(e,t={}){return(await Ii(e,t)).device}async function Ii(e,t={}){let n={...zi(e),androidAvdSelection:t.androidAvdSelection??`running-only`},{iosSimulatorSetPath:r,...a}=n,o=Ui(n,t),s={platform:n.platform,target:e.target,cacheHit:!1};return await i(`resolve_target_device`,async()=>{let e=Vi(o);if(e)return s.cacheHit=!0,e;let i=await ct(n),l=[...i.devices];if(c(a.platform)&&i.source===`local`){let e=await Li(l,a,{simulatorSetPath:r,appleSimulatorAppTarget:t.appleSimulatorAppTarget});return Hi(o,e)}return Hi(o,await Q({devices:l,selector:a,source:i.source}))},s)}async function Li(t,n,r){let i;try{i=await Q({devices:t,selector:n,source:`local`,appleSimulatorAppTarget:r.appleSimulatorAppTarget})}catch(e){if(!Ni(e,n))throw e}let a=await Ri(n,r,i?.device);if(a)return a;if(i)return i;throw new e(`DEVICE_NOT_FOUND`,`No devices found`,{selector:n})}async function Ri(e,t,n){if(Pi(e,n))try{return await Q({devices:await lt({platform:e.platform??`ios`,target:e.target,iosSimulatorSetPath:t.simulatorSetPath,kind:`simulator`}),selector:e,source:`local`})}catch(e){if(st(e))throw e;return}}function zi(t){let n=t.platform;if(t.target&&!n)throw new e(`INVALID_ARGS`,`Device target selector requires --platform. Use --platform ios|macos|android|vega|linux|apple with --target mobile|tv|desktop.`);let r=o({simulatorSetPath:ot(t.iosSimulatorDeviceSet),platform:n,target:t.target}),i=at(t.androidDeviceAllowlist);return{platform:n,target:t.target,deviceName:t.device,udid:t.udid,serial:t.serial,leaseId:t.leaseId,leaseProvider:t.leaseProvider,deviceKey:t.deviceKey,clientId:t.clientId,iosSimulatorSetPath:r,androidSerialAllowlist:i?Array.from(i).sort():void 0}}async function Bi(e){return $.getStore()?await e():await $.run(new Map,e)}function Vi(e){let t=$.getStore()?.get(e);if(t)return{...t,device:{...t.device}}}function Hi(e,t){return $.getStore()?.set(e,{...t,device:{...t.device}}),t}function Ui(e,t){let{appleSimulatorAppTarget:n,...r}=t;return JSON.stringify({request:e,options:r})}export{St as _,Mi as a,S as b,mi as c,Nt as d,Tt as f,xt as g,bt as h,Bi as i,Cr as l,ht as m,Fi as n,xi as o,yt as p,Ii as r,bi as s,zi as t,Un as u,_t as v,gt as x,vt as y};
@@ -1 +1 @@
1
- import{p as e}from"./sdk-device.js";import{f as t}from"./owner-identity.js";import"./process.js";import{n}from"./toolchain-probe.js";import{a as r}from"./runner-client.js";import{C as i}from"./runner-disposal.js";async function a(){let e=await n(`xcodebuild`,[`-version`]);return e?s({selectedPath:await n(`xcode-select`,[`-p`]),versionLine:e}):u()}async function o(n,a){if(!(!e(n)||n.kind!==`simulator`)&&!(t()!==`darwin`||a.isProviderDevice(n)))return a.emitProgress(`Checking iOS runner build cache (${n.name})...`),await i(n)?{id:`ios-runner-cache`,status:`pass`,summary:`iOS runner artifact cached; first open skips the runner build`}:(r(n,{}),a.emitProgress(`Warming iOS runner build cache in the background (${n.name})...`),{id:`ios-runner-cache`,status:`pass`,summary:`iOS runner build started in the background; the first open gets faster once it completes`,hint:"Run `agent-device prepare ios-runner` to wait for a fully warmed runner instead."})}function s(e){return{id:`toolchain`,status:c(e),summary:l(e),evidence:{selectedPath:e.selectedPath??null,xcodeVersion:e.versionLine??null}}}function c(e){return e.versionLine?`pass`:`info`}function l(e){return e.versionLine?e.selectedPath?`Apple toolchain: ${e.versionLine}; xcode-select ${e.selectedPath}.`:`Apple toolchain: ${e.versionLine}; xcode-select path unavailable.`:`Apple toolchain: xcodebuild version check failed.`}function u(){return{id:`toolchain`,status:`info`,summary:`Apple toolchain: xcodebuild version check failed.`,hint:`Install/select Xcode and complete first launch/license setup if xcodebuild reports it.`,command:`xcodebuild -version`}}export{o as appleRunnerWarmupCheck,a as appleToolchainCheck};
1
+ import{p as e}from"./sdk-device.js";import{f as t}from"./owner-identity.js";import"./process.js";import{n}from"./toolchain-probe.js";import{a as r}from"./runner-client.js";import{O as i}from"./runner-disposal.js";async function a(){let e=await n(`xcodebuild`,[`-version`]);return e?s({selectedPath:await n(`xcode-select`,[`-p`]),versionLine:e}):u()}async function o(n,a){if(!(!e(n)||n.kind!==`simulator`)&&!(t()!==`darwin`||a.isProviderDevice(n)))return a.emitProgress(`Checking iOS runner build cache (${n.name})...`),await i(n)?{id:`ios-runner-cache`,status:`pass`,summary:`iOS runner artifact cached; first open skips the runner build`}:(r(n,{}),a.emitProgress(`Warming iOS runner build cache in the background (${n.name})...`),{id:`ios-runner-cache`,status:`pass`,summary:`iOS runner build started in the background; the first open gets faster once it completes`,hint:"Run `agent-device prepare ios-runner` to wait for a fully warmed runner instead."})}function s(e){return{id:`toolchain`,status:c(e),summary:l(e),evidence:{selectedPath:e.selectedPath??null,xcodeVersion:e.versionLine??null}}}function c(e){return e.versionLine?`pass`:`info`}function l(e){return e.versionLine?e.selectedPath?`Apple toolchain: ${e.versionLine}; xcode-select ${e.selectedPath}.`:`Apple toolchain: ${e.versionLine}; xcode-select path unavailable.`:`Apple toolchain: xcodebuild version check failed.`}function u(){return{id:`toolchain`,status:`info`,summary:`Apple toolchain: xcodebuild version check failed.`,hint:`Install/select Xcode and complete first launch/license setup if xcodebuild reports it.`,command:`xcodebuild -version`}}export{o as appleRunnerWarmupCheck,a as appleToolchainCheck};
@@ -1 +1 @@
1
- import{P as e}from"./sdk-contracts.js";import{r as t}from"./diagnostics.js";import"./diagnostics2.js";import{M as n,P as r,j as i}from"./sdk-device.js";import{en as a}from"./sdk-batch.js";import{k as o}from"./owner-identity.js";import{i as s}from"./verified-file.js";import"./file.js";import{r as c}from"./session-paths.js";import{i as l,n as u,t as d}from"./durable-resource.js";import f from"node:crypto";import p from"node:fs";import m from"node:path";function h(t){let n=t.read(t.resolveCurrent()??t.initialSession),r=()=>{if(t.assertAdmissionOpen(),t.read(t.requireCurrent()))throw new e(`COMMAND_FAILED`,`Session capture resource has changed`,{reason:`session_resource_changed`,session:t.address})};return Object.freeze({address:t.address,sessionDir:t.sessionDir,read:()=>{let e=t.resolveCurrent();return e!==void 0&&(n=t.read(e)),n},assertAdoptable:r,canPersist:()=>{let e=t.resolveCurrent();return e!==void 0&&t.read(e)===void 0},adopt:e=>{r(),t.write(e),n=e},clear:e=>{let r=t.resolveCurrent();if(r===void 0)return`retired`;let i=t.read(r);return n=i,i?.handle!==e.handle||i.envelope.fence.token!==e.envelope.fence.token||i.envelope.fence.generation!==e.envelope.fence.generation?`resource-changed`:(t.write(void 0),n=void 0,`cleared`)}})}function g(e,t,n){return h({address:t.address,sessionDir:e.resolveSessionDir(t.address),initialSession:t.session,resolveCurrent:()=>e.resolveCurrent(t),requireCurrent:()=>e.requireCurrent(t),assertAdmissionOpen:()=>e.assertAdmissionOpen(t.address),...n})}function ee(e,t){return g(e,t,{read:e=>e.audioProbe,write:n=>{e.update(t,{audioProbe:n})}})}function te(e,t){return g(e,t,{read:e=>e.perfCapture,write:n=>{e.update(t,{perfCapture:n})}})}function _(e,t){return g(e,t,{read:e=>e.screenRecording,write:n=>{e.update(t,{screenRecording:n})}})}function v(t,n,r){let i,a=()=>{if(i)throw t.requireCurrent(i.ref),new e(`COMMAND_FAILED`,`Recording draft has already been published`,{reason:`session_resource_changed`,session:n});t.assertPublishable(n)},o=Object.freeze({address:n,sessionDir:t.resolveSessionDir(n),read:()=>i?.binding.read(),assertAdoptable:a,canPersist:()=>!i&&t.lookup(n)===void 0,adopt:o=>{if(a(),r.screenRecording)throw new e(`COMMAND_FAILED`,`Recording draft already owns a resource`,{reason:`session_resource_changed`,session:n});let s=t.publish(n,r),c=_(t,s);c.adopt(o),i=Object.freeze({ref:s,binding:c})},clear:e=>i?.binding.clear(e)??`retired`});return Object.freeze({binding:o,requireRef:()=>{if(!i)throw TypeError(`Screen recording did not publish its session`);return i.ref}})}function y(e){return e.length===0?e:e[0].toUpperCase()+e.slice(1)}function b(e){return e.replaceAll(`-`,`_`)}async function x(e,t,n){let r={kind:`pending`};try{t.binding.assertAdoptable();let i=T(w(e,t),`active`);e.store.write(n,i),r={kind:`persisted`},t.throwIfCanceled();let a=t.pendingHandle.transfer();r={kind:`transferred`,handle:a},t.binding.adopt({handle:a,envelope:i})}catch(i){throw await ne(e,t,n,r,i),i}}async function ne(e,t,n,r,i){let a=t.binding.canPersist(),o=r.kind!==`pending`||a&&ie(e,t,n),s=re(e,t,n,await S(t,r));t.reportUndurableCleanup(t.device,!o&&s.cleanupError===void 0||s.confirmed?{confirmed:!0}:{confirmed:!1,reason:s.cleanupError instanceof Error?s.cleanupError.message:`The durable cleanup transition could not be confirmed`}),s.cleanupError!==void 0&&ce(e,t,i,s.cleanupError)}function re(e,n,r,i){try{return{confirmed:se(e,r,n.fence,i),cleanupError:i}}catch(r){return t({level:`error`,phase:`${b(e.resourceKind)}_pending_adoption_transition_failed`,data:{session:n.binding.address,transitionError:r instanceof Error?r.message:String(r)}}),{confirmed:!1,cleanupError:i??r}}}async function S(e,t){try{t.kind===`transferred`?await t.handle[Symbol.asyncDispose]():await e.pendingHandle[Symbol.asyncDispose]();return}catch(e){return e}}function ie(e,n,r){try{return e.store.write(r,ae(e,n)),!0}catch(i){try{return e.store.write(r,C(e,n,{version:0,body:{reason:`runtime-contract-invalid`}})),!0}catch(r){return t({level:`error`,phase:`${b(e.resourceKind)}_runtime_contract_tombstone_failed`,data:{session:n.binding.address,descriptorError:i instanceof Error?i.message:String(i),persistenceError:r instanceof Error?r.message:String(r)}}),!1}}}function ae(e,t){try{return T(w(e,t),`active`)}catch{return C(e,t,t.envelope.descriptor)}}function C(e,t,n){return u({resourceKind:e.resourceKind,sessionId:t.binding.address,device:i(t.device),owner:t.owner,fence:t.fence,lifecycle:`open`,descriptor:n,metadata:{phase:`runtime-contract-invalid`,runtimeContractInvalid:!0}})}function w(t,n){let r=l(n.envelope);if(r.status===`decoded`&&oe(r.envelope,n,t.resourceKind))return r.envelope;throw new e(`COMMAND_FAILED`,`${y(t.displayName)} runtime returned an incoherent durable envelope`,{reason:`runtime-contract-invalid`,hint:`Retain the runtime diagnostics and report the selected device and owner.`})}function oe(e,t,n){return e.resourceKind===n&&e.sessionId===t.binding.address&&r(e.device,i(t.device))&&a(e.owner)===a(t.owner)&&e.fence.token===t.fence.token&&e.fence.generation===t.fence.generation&&e.lifecycle===`open`}function se(e,t,n,r){let i=e.store.read(t);return i.status!==`decoded`||i.envelope.fence.token!==n.token||i.envelope.fence.generation!==n.generation?!1:(e.store.write(t,{...i.envelope,lifecycle:r===void 0?`completed`:`open`,metadata:{...i.envelope.metadata??{},phase:r===void 0?`completed`:`cleanup-pending`,cleanupStatus:r===void 0?`cleaned`:`cleanup-pending`}}),!0)}function ce(e,n,r,i){t({level:`error`,phase:`${b(e.resourceKind)}_pending_adoption_cleanup_failed`,data:{session:n.binding.address,primaryError:r instanceof Error?r.message:String(r),cleanupError:i instanceof Error?i.message:String(i)}})}function T(e,t){return Object.freeze({...e,lifecycle:`open`,metadata:{...e.metadata??{},phase:t}})}async function E(e){e.scope.signal.throwIfAborted();let t=new AbortController,n={...e.scope,signal:AbortSignal.any([e.scope.signal,t.signal])},r=()=>{},i=new Promise((e,t)=>{r=t}),a=()=>{},o=new Promise((t,n)=>{let r=()=>{try{e.scope.signal.throwIfAborted()}catch(e){n(e)}};if(e.scope.signal.aborted){r();return}e.scope.signal.addEventListener(`abort`,r,{once:!0}),a=()=>e.scope.signal.removeEventListener(`abort`,r)}),s=setTimeout(()=>{let n=new k(e.displayName,e.deadlineMs);t.abort(n),r(n)},e.deadlineMs);s.unref?.();let c=le(e,n),l,u=c.then(e=>(l??={kind:`acquisition`},e),e=>{throw l??={kind:`acquisition-error`},e}),d=i.catch(e=>{throw l??={kind:`deadline`,error:e},e}),f=o.catch(e=>{throw l??={kind:`cancellation`,error:e},e});try{return await Promise.race([u,d,f])}finally{if(clearTimeout(s),a(),l?.kind===`deadline`||l?.kind===`cancellation`){let t=l.error;c.then(n=>D(e,n,t),()=>{}).catch(()=>{})}else c.catch(()=>{})}}async function D(e,t,n){try{t.reattached.status===`active`&&await O(e,t.reattached.handle,`late_handle_cleanup_failed`,n)}finally{await O(e,t.control,`late_control_cleanup_failed`,n)}}async function le(e,t){let n,r;try{return n=await e.acquireControl(e.envelope,t),t.signal.throwIfAborted(),r=await n.reattach(e.envelope),t.signal.throwIfAborted(),{control:n,reattached:r}}catch(t){try{r?.status===`active`&&await O(e,r.handle,`late_handle_cleanup_failed`,t)}finally{n&&await O(e,n,`late_control_cleanup_failed`,t)}throw t}}async function O(e,t,n,r){try{await t[Symbol.asyncDispose]()}catch(t){e.onLateCleanupFailure(n,t,r)}}var k=class extends Error{deadlineMs;constructor(e,t){super(`${y(e)} recovery exceeded its ${t}ms deadline`),this.name=`DurableCaptureRecoveryDeadlineError`,this.deadlineMs=t}};const A=new Map;async function j(e){return await de(e.resourcePath,async()=>{let t=e.store.read(e.resourcePath);if(t.status!==`decoded`)throw M(e.store,t.status===`missing`?`${e.store.displayName} resource record is missing`:`${e.store.displayName} resource record is unreattachable: ${t.message}`);if(!ue(t.envelope.fence,e.expected))throw M(e.store,`${e.store.displayName} resource ownership fence was lost`);let n=t.envelope;return await e.run({get envelope(){return n},transition(t,r={}){return n=Object.freeze({...n,lifecycle:t,...r.descriptor===void 0?{}:{descriptor:r.descriptor},...r.metadata===void 0?{}:{metadata:r.metadata}}),e.store.write(e.resourcePath,n),n}})})}function ue(e,t){return e.token===t.token&&e.generation===t.generation}async function de(e,t){let n=A.get(e)??Promise.resolve(),r,i=new Promise(e=>{r=e}),a=n.catch(()=>{}).then(()=>i);A.set(e,a),await n.catch(()=>{});try{return await t()}finally{r(),A.get(e)===a&&A.delete(e)}}function M(t,n){return new e(`COMMAND_FAILED`,n,{reason:`ownership-fence-lost`,retriable:!1,hint:`Use the current ${t.displayName.toLowerCase()} resource owner or retain the recovery record for manual recovery.`})}async function fe(t,n,r){let i=n.binding.read();if(!i)throw new e(`INVALID_ARGS`,t.messages.noActive);try{let e=await N(t,{handle:i.handle,fence:i.envelope.fence,resourcePath:r,intent:n.intent});return n.binding.clear(i),e}catch(e){let a=t.store.read(r);throw a.status===`decoded`&&a.envelope.lifecycle===`completed`&&n.binding.clear(i),e}}async function N(e,t){return await j({store:e.store,resourcePath:t.resourcePath,expected:t.fence,run:async n=>{W(n);let r=pe(n),i;try{i=await t.handle.finish(r)}catch(r){throw await P(e,n,t,r,t.intent),r}if(i.status===`completed`)return U(e,n,i),i.result;U(e,n,i);let a=H(e,i);throw await P(e,n,t,a,t.intent),a}})}async function P(e,t,n,r,i){if(i===`capture`&&e.failedFinishPolicy===`preserve-retry-material`){I(e,n,r);return}let a;try{a=await n.handle.forceCleanup()}catch(i){L(e,n,r,i,F(t,i));return}try{B(t,a)}catch(t){L(e,n,r,a.status===`cleanup-pending`?a.message??a.reason:`cleanup returned ${a.status}`,t);return}d(a)||L(e,n,r,a.message)}function F(e,t){try{B(e,{status:`cleanup-pending`,reason:`cleanup-unconfirmed`,message:R(t)});return}catch(e){return e}}function I(e,n,r){t({level:`error`,phase:`${b(e.resourceKind)}_finish_evidence_preserved`,data:{resourcePath:n.resourcePath,finishError:R(r),failedFinishPolicy:e.failedFinishPolicy}})}function L(e,n,r,i,a){t({level:`error`,phase:`${b(e.resourceKind)}_finish_cleanup_failed`,data:{resourcePath:n.resourcePath,finishError:R(r),cleanupError:i===void 0?`cleanup could not be confirmed`:R(i),...a===void 0?{}:{transitionError:R(a)}}})}function R(e){return e instanceof Error?e.message:String(e)}async function z(e,t){let n=t.binding.read();n&&(V(e,await j({store:e.store,resourcePath:t.resourcePath,expected:n.envelope.fence,run:async e=>{W(e);let t=await n.handle.forceCleanup();return B(e,t),t}})),t.binding.clear(n))}function B(e,t){e.transition(d(t)?`completed`:`open`,{metadata:{...e.envelope.metadata??{},phase:d(t)?`completed`:`cleanup-pending`,cleanupStatus:t.status,...t.status===`cleanup-pending`?{cleanupPendingReason:t.reason,...t.message?{cleanupPendingMessage:t.message}:{}}:{}}})}function V(e,t){if(!d(t))throw H(e,t)}function H(t,n){return new e(`COMMAND_FAILED`,n.message??`${y(t.displayName)} cleanup could not be confirmed`,{reason:n.reason,retriable:n.reason!==`ownership-fence-lost`,hint:t.messages.cleanupPendingHint})}function U(e,t,n){if(n.status===`completed`){t.transition(`completed`,{metadata:{...t.envelope.metadata??{},...e.completionMetadata(n.result),phase:`completed`}});return}B(t,n)}function pe(e){return Object.freeze({learned:e.envelope.metadata,record:t=>{e.transition(`open`,{metadata:{...e.envelope.metadata??{},...t}})}})}function W(e){e.transition(`open`,{metadata:{...e.envelope.metadata??{},phase:`completing`}})}async function me(e){let t=e.definition.store.list(e.sessionsDir),n=[];for(let r of t)n.push(await G(e,r));return{scanned:t.length,recovered:n.filter(e=>e===`recovered`).length,retained:n.filter(e=>e===`retained`).length}}async function G(e,t){let n=K(e,t);if(n.status!==`recoverable`)return n.status;try{return await he(e,t,n.envelope,e.perRecordDeadlineMs??5e3)?`recovered`:`retained`}catch(n){return Y(e,n instanceof k?`timed_out`:`failed`,t,{error:n instanceof Error?n.message:String(n),...n instanceof k?{deadlineMs:n.deadlineMs}:{}}),`retained`}}function K(e,t){let n=e.definition.store.read(t);if(n.status===`unreattachable`)return Y(e,`record_unreattachable`,t,{reason:n.reason,message:n.message,version:n.version}),{status:`retained`};if(n.status===`missing`||n.envelope.lifecycle===`completed`)return{status:`ignored`};let r=e.definition.store.resolvePath(e.resolveSessionDir(n.envelope.sessionId));return m.resolve(t)===m.resolve(r)?{status:`recoverable`,envelope:n.envelope}:(Y(e,`session_path_mismatch`,t,{envelopeSessionId:n.envelope.sessionId,canonicalPath:r}),{status:`retained`})}async function he(e,t,n,r){return await ge(e,t,n,await E({displayName:e.definition.displayName,envelope:n,scope:e.scope,deadlineMs:r,acquireControl:e.acquireControl,onLateCleanupFailure:(n,r,i)=>Y(e,n,t,{error:r instanceof Error?r.message:String(r),primaryError:i instanceof Error?i.message:String(i)})}))}async function ge(e,t,n,r){try{switch(r.reattached.status){case`active`:{let i=r.reattached.handle,a=await j({store:e.definition.store,resourcePath:t,expected:n.fence,run:async e=>{_e(e);let t=await i.forceCleanup();return B(e,t),t}});return d(a)}case`completed`:return await q(e,t,n,{...e.definition.completionMetadata(r.reattached.result)}),!0;case`missing`:return await q(e,t,n,{recoveryStatus:`already-missing`}),!0;case`unreattachable`:{if(!J(r.reattached.reason))return Y(e,`retained`,t,{reason:r.reattached.reason,message:r.reattached.message}),!1;let i=await r.control.cleanup(n);return await j({store:e.definition.store,resourcePath:t,expected:n.fence,run:async e=>B(e,i)}),d(i)}}}finally{await r.control[Symbol.asyncDispose]()}}async function q(e,t,n,r){await j({store:e.definition.store,resourcePath:t,expected:n.fence,run:async e=>{e.transition(`completed`,{metadata:{...e.envelope.metadata??{},phase:`completed`,...r}})}})}function _e(e){e.transition(`open`,{metadata:{...e.envelope.metadata??{},phase:`completing`}})}function J(e){switch(e){case`descriptor-invalid`:case`descriptor-version-unsupported`:case`ownership-fence-lost`:return!1;case`owner-unavailable`:case`transport-not-reattachable`:return!0}}function Y(e,n,r,i){let a={phase:`${b(e.definition.resourceKind)}_recovery_${n}`,resourcePath:r,data:i};e.onDiagnostic?e.onDiagnostic(a):t({level:`warn`,phase:a.phase,data:{resourcePath:r,...i}})}async function ve(t,n){let r=t.store.read(n.resourcePath);if(r.status!==`decoded`||r.envelope.lifecycle!==`open`)throw ye(t,r.status);let i=r.envelope,a=await E({displayName:t.displayName,envelope:i,scope:n.scope,deadlineMs:n.deadlineMs??5e3,acquireControl:n.acquireControl,onLateCleanupFailure:(e,r,i)=>n.scope.diagnostics.emit({level:`error`,phase:`${b(t.resourceKind)}_recovery_${e}`,data:{resourcePath:n.resourcePath,error:X(r),primaryError:X(i)}})});try{switch(a.reattached.status){case`active`:return await N(t,{handle:a.reattached.handle,fence:i.fence,resourcePath:n.resourcePath,intent:`capture`});case`completed`:{let e=a.reattached.result;return await j({store:t.store,resourcePath:n.resourcePath,expected:i.fence,run:async n=>{U(t,n,{status:`completed`,result:e,alreadyCompleted:!0})}}),e}case`missing`:throw new e(`COMMAND_FAILED`,`${y(t.displayName)} is missing`,{reason:`resource-missing`,hint:t.messages.cleanupPendingHint});case`unreattachable`:if(J(a.reattached.reason)){let e=await a.control.cleanup(i);await j({store:t.store,resourcePath:n.resourcePath,expected:i.fence,run:async t=>B(t,e)}),V(t,e)}throw new e(`COMMAND_FAILED`,a.reattached.message??`${y(t.displayName)} cannot be reattached`,{reason:a.reattached.reason,hint:t.messages.cleanupPendingHint})}}finally{await a.control[Symbol.asyncDispose]()}}function ye(t,n){return new e(`INVALID_ARGS`,n===`missing`?t.messages.noActive:`${y(t.displayName)} recovery record is not open`)}function X(e){return e instanceof Error?e.message:String(e)}function be(e){Se(e.fileName);let t=t=>m.join(t,e.fileName);return Object.freeze({resourceKind:e.resourceKind,displayName:e.displayName,resolvePath:t,read(t){let n,r;try{if(n=s(t),n===void 0)return{status:`missing`};r=JSON.parse(p.readFileSync(n,`utf8`))}catch(t){return Q(t)?{status:`missing`}:Z(we(t,e.displayName))}finally{n!==void 0&&p.closeSync(n)}return xe(l(r),e.resourceKind)},write(e,t){let n=m.dirname(e);p.mkdirSync(n,{recursive:!0}),o({destination:e,contents:`${JSON.stringify(t)}\n`})},list(e){let n;try{n=p.readdirSync(e,{withFileTypes:!0})}catch{return[]}return n.filter(e=>e.isDirectory()).map(n=>t(m.join(e,n.name))).filter(Ce).sort()}})}function xe(e,t){return e.status===`decoded`?e.envelope.resourceKind===t?{status:`decoded`,envelope:e.envelope}:Z(`Expected ${t} resource record, received ${e.envelope.resourceKind}`):e}function Se(e){if(e.length===0||m.basename(e)!==e)throw TypeError(`Durable capture resource fileName must be one file name`)}function Ce(e){try{return p.lstatSync(e),!0}catch(e){return!Q(e)}}function Z(e){return{status:`unreattachable`,reason:`descriptor-invalid`,message:e}}function Q(e){return typeof e==`object`&&!!e&&`code`in e&&e.code===`ENOENT`}function we(e,t){return e instanceof Error?e.message:`${t} resource record is invalid`}function Te(e,t){t.admissionLedger.assertStartAllowed(t.device),Ee(e,t.resourcePath,t.device);let n=e.store.read(t.resourcePath);return Object.freeze({token:f.randomUUID(),generation:n.status===`decoded`?n.envelope.fence.generation+1:1})}function Ee(t,r,a){let o=n(i(a));for(let i of t.store.list(m.dirname(m.dirname(r)))){let a=t.store.read(i);if(a.status===`unreattachable`)throw new e(`COMMAND_FAILED`,`${y($(t.displayName))} ${t.displayName} recovery record is unreattachable: ${a.message}`,{reason:a.reason,retriable:!1,hint:`Retain the corrupt or future-version ${t.displayName} manifest for manual recovery; no replacement capture is safe.`});if(a.status===`decoded`&&a.envelope.lifecycle!==`completed`&&(i===r||n(a.envelope.device)===o))throw new e(`COMMAND_FAILED`,`${y($(t.displayName))} ${t.displayName} resource for this device has not reached a confirmed terminal state`,{reason:`cleanup-unconfirmed`,hint:`Retry exact-owner cleanup using the existing ${t.displayName} manifest before starting a replacement.`})}}function $(e){return/^[aeiou]/i.test(e)?`an`:`a`}function De(e){let t=(t,n)=>e.store.resolvePath(t.resolveSessionDir(n)),n=t=>({definition:e,resolveSessionDir:e=>m.join(t.sessionsDir,c(e)),...t});return Object.freeze({store:e.store,resourcePath:t,createNextFence(t){return Te(e,t)},adoptStarted(t){return x(e,{...t,reportUndurableCleanup:(e,n)=>{n.confirmed?t.admissionLedger.clearUndurableCleanup(e):t.admissionLedger.blockUndurableCleanup(e,n.reason)}},e.store.resolvePath(t.binding.sessionDir))},finishLive(t){return fe(e,t,e.store.resolvePath(t.binding.sessionDir))},finishRecovered(t){return ve(e,t)},forceCleanupLive(t){return z(e,{...t,resourcePath:e.store.resolvePath(t.binding.sessionDir)})},recoverAll(e){return me(n(e))},recoverOne(e,t){return G(n(e),t)}})}export{g as a,ee as i,be as n,te as o,v as r,_ as s,De as t};
1
+ import{P as e}from"./sdk-contracts.js";import{r as t}from"./diagnostics.js";import"./diagnostics2.js";import{M as n,P as r,j as i}from"./sdk-device.js";import{en as a}from"./sdk-batch.js";import{A as o}from"./owner-identity.js";import{i as s}from"./verified-file.js";import"./file.js";import{r as c}from"./session-paths.js";import{i as l,n as u,t as d}from"./durable-resource.js";import f from"node:crypto";import p from"node:fs";import m from"node:path";function h(t){let n=t.read(t.resolveCurrent()??t.initialSession),r=()=>{if(t.assertAdmissionOpen(),t.read(t.requireCurrent()))throw new e(`COMMAND_FAILED`,`Session capture resource has changed`,{reason:`session_resource_changed`,session:t.address})};return Object.freeze({address:t.address,sessionDir:t.sessionDir,read:()=>{let e=t.resolveCurrent();return e!==void 0&&(n=t.read(e)),n},assertAdoptable:r,canPersist:()=>{let e=t.resolveCurrent();return e!==void 0&&t.read(e)===void 0},adopt:e=>{r(),t.write(e),n=e},clear:e=>{let r=t.resolveCurrent();if(r===void 0)return`retired`;let i=t.read(r);return n=i,i?.handle!==e.handle||i.envelope.fence.token!==e.envelope.fence.token||i.envelope.fence.generation!==e.envelope.fence.generation?`resource-changed`:(t.write(void 0),n=void 0,`cleared`)}})}function g(e,t,n){return h({address:t.address,sessionDir:e.resolveSessionDir(t.address),initialSession:t.session,resolveCurrent:()=>e.resolveCurrent(t),requireCurrent:()=>e.requireCurrent(t),assertAdmissionOpen:()=>e.assertAdmissionOpen(t.address),...n})}function ee(e,t){return g(e,t,{read:e=>e.audioProbe,write:n=>{e.update(t,{audioProbe:n})}})}function te(e,t){return g(e,t,{read:e=>e.perfCapture,write:n=>{e.update(t,{perfCapture:n})}})}function _(e,t){return g(e,t,{read:e=>e.screenRecording,write:n=>{e.update(t,{screenRecording:n})}})}function v(t,n,r){let i,a=()=>{if(i)throw t.requireCurrent(i.ref),new e(`COMMAND_FAILED`,`Recording draft has already been published`,{reason:`session_resource_changed`,session:n});t.assertPublishable(n)},o=Object.freeze({address:n,sessionDir:t.resolveSessionDir(n),read:()=>i?.binding.read(),assertAdoptable:a,canPersist:()=>!i&&t.lookup(n)===void 0,adopt:o=>{if(a(),r.screenRecording)throw new e(`COMMAND_FAILED`,`Recording draft already owns a resource`,{reason:`session_resource_changed`,session:n});let s=t.publish(n,r),c=_(t,s);c.adopt(o),i=Object.freeze({ref:s,binding:c})},clear:e=>i?.binding.clear(e)??`retired`});return Object.freeze({binding:o,requireRef:()=>{if(!i)throw TypeError(`Screen recording did not publish its session`);return i.ref}})}function y(e){return e.length===0?e:e[0].toUpperCase()+e.slice(1)}function b(e){return e.replaceAll(`-`,`_`)}async function x(e,t,n){let r={kind:`pending`};try{t.binding.assertAdoptable();let i=T(w(e,t),`active`);e.store.write(n,i),r={kind:`persisted`},t.throwIfCanceled();let a=t.pendingHandle.transfer();r={kind:`transferred`,handle:a},t.binding.adopt({handle:a,envelope:i})}catch(i){throw await ne(e,t,n,r,i),i}}async function ne(e,t,n,r,i){let a=t.binding.canPersist(),o=r.kind!==`pending`||a&&ie(e,t,n),s=re(e,t,n,await S(t,r));t.reportUndurableCleanup(t.device,!o&&s.cleanupError===void 0||s.confirmed?{confirmed:!0}:{confirmed:!1,reason:s.cleanupError instanceof Error?s.cleanupError.message:`The durable cleanup transition could not be confirmed`}),s.cleanupError!==void 0&&ce(e,t,i,s.cleanupError)}function re(e,n,r,i){try{return{confirmed:se(e,r,n.fence,i),cleanupError:i}}catch(r){return t({level:`error`,phase:`${b(e.resourceKind)}_pending_adoption_transition_failed`,data:{session:n.binding.address,transitionError:r instanceof Error?r.message:String(r)}}),{confirmed:!1,cleanupError:i??r}}}async function S(e,t){try{t.kind===`transferred`?await t.handle[Symbol.asyncDispose]():await e.pendingHandle[Symbol.asyncDispose]();return}catch(e){return e}}function ie(e,n,r){try{return e.store.write(r,ae(e,n)),!0}catch(i){try{return e.store.write(r,C(e,n,{version:0,body:{reason:`runtime-contract-invalid`}})),!0}catch(r){return t({level:`error`,phase:`${b(e.resourceKind)}_runtime_contract_tombstone_failed`,data:{session:n.binding.address,descriptorError:i instanceof Error?i.message:String(i),persistenceError:r instanceof Error?r.message:String(r)}}),!1}}}function ae(e,t){try{return T(w(e,t),`active`)}catch{return C(e,t,t.envelope.descriptor)}}function C(e,t,n){return u({resourceKind:e.resourceKind,sessionId:t.binding.address,device:i(t.device),owner:t.owner,fence:t.fence,lifecycle:`open`,descriptor:n,metadata:{phase:`runtime-contract-invalid`,runtimeContractInvalid:!0}})}function w(t,n){let r=l(n.envelope);if(r.status===`decoded`&&oe(r.envelope,n,t.resourceKind))return r.envelope;throw new e(`COMMAND_FAILED`,`${y(t.displayName)} runtime returned an incoherent durable envelope`,{reason:`runtime-contract-invalid`,hint:`Retain the runtime diagnostics and report the selected device and owner.`})}function oe(e,t,n){return e.resourceKind===n&&e.sessionId===t.binding.address&&r(e.device,i(t.device))&&a(e.owner)===a(t.owner)&&e.fence.token===t.fence.token&&e.fence.generation===t.fence.generation&&e.lifecycle===`open`}function se(e,t,n,r){let i=e.store.read(t);return i.status!==`decoded`||i.envelope.fence.token!==n.token||i.envelope.fence.generation!==n.generation?!1:(e.store.write(t,{...i.envelope,lifecycle:r===void 0?`completed`:`open`,metadata:{...i.envelope.metadata??{},phase:r===void 0?`completed`:`cleanup-pending`,cleanupStatus:r===void 0?`cleaned`:`cleanup-pending`}}),!0)}function ce(e,n,r,i){t({level:`error`,phase:`${b(e.resourceKind)}_pending_adoption_cleanup_failed`,data:{session:n.binding.address,primaryError:r instanceof Error?r.message:String(r),cleanupError:i instanceof Error?i.message:String(i)}})}function T(e,t){return Object.freeze({...e,lifecycle:`open`,metadata:{...e.metadata??{},phase:t}})}async function E(e){e.scope.signal.throwIfAborted();let t=new AbortController,n={...e.scope,signal:AbortSignal.any([e.scope.signal,t.signal])},r=()=>{},i=new Promise((e,t)=>{r=t}),a=()=>{},o=new Promise((t,n)=>{let r=()=>{try{e.scope.signal.throwIfAborted()}catch(e){n(e)}};if(e.scope.signal.aborted){r();return}e.scope.signal.addEventListener(`abort`,r,{once:!0}),a=()=>e.scope.signal.removeEventListener(`abort`,r)}),s=setTimeout(()=>{let n=new k(e.displayName,e.deadlineMs);t.abort(n),r(n)},e.deadlineMs);s.unref?.();let c=le(e,n),l,u=c.then(e=>(l??={kind:`acquisition`},e),e=>{throw l??={kind:`acquisition-error`},e}),d=i.catch(e=>{throw l??={kind:`deadline`,error:e},e}),f=o.catch(e=>{throw l??={kind:`cancellation`,error:e},e});try{return await Promise.race([u,d,f])}finally{if(clearTimeout(s),a(),l?.kind===`deadline`||l?.kind===`cancellation`){let t=l.error;c.then(n=>D(e,n,t),()=>{}).catch(()=>{})}else c.catch(()=>{})}}async function D(e,t,n){try{t.reattached.status===`active`&&await O(e,t.reattached.handle,`late_handle_cleanup_failed`,n)}finally{await O(e,t.control,`late_control_cleanup_failed`,n)}}async function le(e,t){let n,r;try{return n=await e.acquireControl(e.envelope,t),t.signal.throwIfAborted(),r=await n.reattach(e.envelope),t.signal.throwIfAborted(),{control:n,reattached:r}}catch(t){try{r?.status===`active`&&await O(e,r.handle,`late_handle_cleanup_failed`,t)}finally{n&&await O(e,n,`late_control_cleanup_failed`,t)}throw t}}async function O(e,t,n,r){try{await t[Symbol.asyncDispose]()}catch(t){e.onLateCleanupFailure(n,t,r)}}var k=class extends Error{deadlineMs;constructor(e,t){super(`${y(e)} recovery exceeded its ${t}ms deadline`),this.name=`DurableCaptureRecoveryDeadlineError`,this.deadlineMs=t}};const A=new Map;async function j(e){return await de(e.resourcePath,async()=>{let t=e.store.read(e.resourcePath);if(t.status!==`decoded`)throw M(e.store,t.status===`missing`?`${e.store.displayName} resource record is missing`:`${e.store.displayName} resource record is unreattachable: ${t.message}`);if(!ue(t.envelope.fence,e.expected))throw M(e.store,`${e.store.displayName} resource ownership fence was lost`);let n=t.envelope;return await e.run({get envelope(){return n},transition(t,r={}){return n=Object.freeze({...n,lifecycle:t,...r.descriptor===void 0?{}:{descriptor:r.descriptor},...r.metadata===void 0?{}:{metadata:r.metadata}}),e.store.write(e.resourcePath,n),n}})})}function ue(e,t){return e.token===t.token&&e.generation===t.generation}async function de(e,t){let n=A.get(e)??Promise.resolve(),r,i=new Promise(e=>{r=e}),a=n.catch(()=>{}).then(()=>i);A.set(e,a),await n.catch(()=>{});try{return await t()}finally{r(),A.get(e)===a&&A.delete(e)}}function M(t,n){return new e(`COMMAND_FAILED`,n,{reason:`ownership-fence-lost`,retriable:!1,hint:`Use the current ${t.displayName.toLowerCase()} resource owner or retain the recovery record for manual recovery.`})}async function fe(t,n,r){let i=n.binding.read();if(!i)throw new e(`INVALID_ARGS`,t.messages.noActive);try{let e=await N(t,{handle:i.handle,fence:i.envelope.fence,resourcePath:r,intent:n.intent});return n.binding.clear(i),e}catch(e){let a=t.store.read(r);throw a.status===`decoded`&&a.envelope.lifecycle===`completed`&&n.binding.clear(i),e}}async function N(e,t){return await j({store:e.store,resourcePath:t.resourcePath,expected:t.fence,run:async n=>{W(n);let r=pe(n),i;try{i=await t.handle.finish(r)}catch(r){throw await P(e,n,t,r,t.intent),r}if(i.status===`completed`)return U(e,n,i),i.result;U(e,n,i);let a=H(e,i);throw await P(e,n,t,a,t.intent),a}})}async function P(e,t,n,r,i){if(i===`capture`&&e.failedFinishPolicy===`preserve-retry-material`){I(e,n,r);return}let a;try{a=await n.handle.forceCleanup()}catch(i){L(e,n,r,i,F(t,i));return}try{B(t,a)}catch(t){L(e,n,r,a.status===`cleanup-pending`?a.message??a.reason:`cleanup returned ${a.status}`,t);return}d(a)||L(e,n,r,a.message)}function F(e,t){try{B(e,{status:`cleanup-pending`,reason:`cleanup-unconfirmed`,message:R(t)});return}catch(e){return e}}function I(e,n,r){t({level:`error`,phase:`${b(e.resourceKind)}_finish_evidence_preserved`,data:{resourcePath:n.resourcePath,finishError:R(r),failedFinishPolicy:e.failedFinishPolicy}})}function L(e,n,r,i,a){t({level:`error`,phase:`${b(e.resourceKind)}_finish_cleanup_failed`,data:{resourcePath:n.resourcePath,finishError:R(r),cleanupError:i===void 0?`cleanup could not be confirmed`:R(i),...a===void 0?{}:{transitionError:R(a)}}})}function R(e){return e instanceof Error?e.message:String(e)}async function z(e,t){let n=t.binding.read();n&&(V(e,await j({store:e.store,resourcePath:t.resourcePath,expected:n.envelope.fence,run:async e=>{W(e);let t=await n.handle.forceCleanup();return B(e,t),t}})),t.binding.clear(n))}function B(e,t){e.transition(d(t)?`completed`:`open`,{metadata:{...e.envelope.metadata??{},phase:d(t)?`completed`:`cleanup-pending`,cleanupStatus:t.status,...t.status===`cleanup-pending`?{cleanupPendingReason:t.reason,...t.message?{cleanupPendingMessage:t.message}:{}}:{}}})}function V(e,t){if(!d(t))throw H(e,t)}function H(t,n){return new e(`COMMAND_FAILED`,n.message??`${y(t.displayName)} cleanup could not be confirmed`,{reason:n.reason,retriable:n.reason!==`ownership-fence-lost`,hint:t.messages.cleanupPendingHint})}function U(e,t,n){if(n.status===`completed`){t.transition(`completed`,{metadata:{...t.envelope.metadata??{},...e.completionMetadata(n.result),phase:`completed`}});return}B(t,n)}function pe(e){return Object.freeze({learned:e.envelope.metadata,record:t=>{e.transition(`open`,{metadata:{...e.envelope.metadata??{},...t}})}})}function W(e){e.transition(`open`,{metadata:{...e.envelope.metadata??{},phase:`completing`}})}async function me(e){let t=e.definition.store.list(e.sessionsDir),n=[];for(let r of t)n.push(await G(e,r));return{scanned:t.length,recovered:n.filter(e=>e===`recovered`).length,retained:n.filter(e=>e===`retained`).length}}async function G(e,t){let n=K(e,t);if(n.status!==`recoverable`)return n.status;try{return await he(e,t,n.envelope,e.perRecordDeadlineMs??5e3)?`recovered`:`retained`}catch(n){return Y(e,n instanceof k?`timed_out`:`failed`,t,{error:n instanceof Error?n.message:String(n),...n instanceof k?{deadlineMs:n.deadlineMs}:{}}),`retained`}}function K(e,t){let n=e.definition.store.read(t);if(n.status===`unreattachable`)return Y(e,`record_unreattachable`,t,{reason:n.reason,message:n.message,version:n.version}),{status:`retained`};if(n.status===`missing`||n.envelope.lifecycle===`completed`)return{status:`ignored`};let r=e.definition.store.resolvePath(e.resolveSessionDir(n.envelope.sessionId));return m.resolve(t)===m.resolve(r)?{status:`recoverable`,envelope:n.envelope}:(Y(e,`session_path_mismatch`,t,{envelopeSessionId:n.envelope.sessionId,canonicalPath:r}),{status:`retained`})}async function he(e,t,n,r){return await ge(e,t,n,await E({displayName:e.definition.displayName,envelope:n,scope:e.scope,deadlineMs:r,acquireControl:e.acquireControl,onLateCleanupFailure:(n,r,i)=>Y(e,n,t,{error:r instanceof Error?r.message:String(r),primaryError:i instanceof Error?i.message:String(i)})}))}async function ge(e,t,n,r){try{switch(r.reattached.status){case`active`:{let i=r.reattached.handle,a=await j({store:e.definition.store,resourcePath:t,expected:n.fence,run:async e=>{_e(e);let t=await i.forceCleanup();return B(e,t),t}});return d(a)}case`completed`:return await q(e,t,n,{...e.definition.completionMetadata(r.reattached.result)}),!0;case`missing`:return await q(e,t,n,{recoveryStatus:`already-missing`}),!0;case`unreattachable`:{if(!J(r.reattached.reason))return Y(e,`retained`,t,{reason:r.reattached.reason,message:r.reattached.message}),!1;let i=await r.control.cleanup(n);return await j({store:e.definition.store,resourcePath:t,expected:n.fence,run:async e=>B(e,i)}),d(i)}}}finally{await r.control[Symbol.asyncDispose]()}}async function q(e,t,n,r){await j({store:e.definition.store,resourcePath:t,expected:n.fence,run:async e=>{e.transition(`completed`,{metadata:{...e.envelope.metadata??{},phase:`completed`,...r}})}})}function _e(e){e.transition(`open`,{metadata:{...e.envelope.metadata??{},phase:`completing`}})}function J(e){switch(e){case`descriptor-invalid`:case`descriptor-version-unsupported`:case`ownership-fence-lost`:return!1;case`owner-unavailable`:case`transport-not-reattachable`:return!0}}function Y(e,n,r,i){let a={phase:`${b(e.definition.resourceKind)}_recovery_${n}`,resourcePath:r,data:i};e.onDiagnostic?e.onDiagnostic(a):t({level:`warn`,phase:a.phase,data:{resourcePath:r,...i}})}async function ve(t,n){let r=t.store.read(n.resourcePath);if(r.status!==`decoded`||r.envelope.lifecycle!==`open`)throw ye(t,r.status);let i=r.envelope,a=await E({displayName:t.displayName,envelope:i,scope:n.scope,deadlineMs:n.deadlineMs??5e3,acquireControl:n.acquireControl,onLateCleanupFailure:(e,r,i)=>n.scope.diagnostics.emit({level:`error`,phase:`${b(t.resourceKind)}_recovery_${e}`,data:{resourcePath:n.resourcePath,error:X(r),primaryError:X(i)}})});try{switch(a.reattached.status){case`active`:return await N(t,{handle:a.reattached.handle,fence:i.fence,resourcePath:n.resourcePath,intent:`capture`});case`completed`:{let e=a.reattached.result;return await j({store:t.store,resourcePath:n.resourcePath,expected:i.fence,run:async n=>{U(t,n,{status:`completed`,result:e,alreadyCompleted:!0})}}),e}case`missing`:throw new e(`COMMAND_FAILED`,`${y(t.displayName)} is missing`,{reason:`resource-missing`,hint:t.messages.cleanupPendingHint});case`unreattachable`:if(J(a.reattached.reason)){let e=await a.control.cleanup(i);await j({store:t.store,resourcePath:n.resourcePath,expected:i.fence,run:async t=>B(t,e)}),V(t,e)}throw new e(`COMMAND_FAILED`,a.reattached.message??`${y(t.displayName)} cannot be reattached`,{reason:a.reattached.reason,hint:t.messages.cleanupPendingHint})}}finally{await a.control[Symbol.asyncDispose]()}}function ye(t,n){return new e(`INVALID_ARGS`,n===`missing`?t.messages.noActive:`${y(t.displayName)} recovery record is not open`)}function X(e){return e instanceof Error?e.message:String(e)}function be(e){Se(e.fileName);let t=t=>m.join(t,e.fileName);return Object.freeze({resourceKind:e.resourceKind,displayName:e.displayName,resolvePath:t,read(t){let n,r;try{if(n=s(t),n===void 0)return{status:`missing`};r=JSON.parse(p.readFileSync(n,`utf8`))}catch(t){return Q(t)?{status:`missing`}:Z(we(t,e.displayName))}finally{n!==void 0&&p.closeSync(n)}return xe(l(r),e.resourceKind)},write(e,t){let n=m.dirname(e);p.mkdirSync(n,{recursive:!0}),o({destination:e,contents:`${JSON.stringify(t)}\n`})},list(e){let n;try{n=p.readdirSync(e,{withFileTypes:!0})}catch{return[]}return n.filter(e=>e.isDirectory()).map(n=>t(m.join(e,n.name))).filter(Ce).sort()}})}function xe(e,t){return e.status===`decoded`?e.envelope.resourceKind===t?{status:`decoded`,envelope:e.envelope}:Z(`Expected ${t} resource record, received ${e.envelope.resourceKind}`):e}function Se(e){if(e.length===0||m.basename(e)!==e)throw TypeError(`Durable capture resource fileName must be one file name`)}function Ce(e){try{return p.lstatSync(e),!0}catch(e){return!Q(e)}}function Z(e){return{status:`unreattachable`,reason:`descriptor-invalid`,message:e}}function Q(e){return typeof e==`object`&&!!e&&`code`in e&&e.code===`ENOENT`}function we(e,t){return e instanceof Error?e.message:`${t} resource record is invalid`}function Te(e,t){t.admissionLedger.assertStartAllowed(t.device),Ee(e,t.resourcePath,t.device);let n=e.store.read(t.resourcePath);return Object.freeze({token:f.randomUUID(),generation:n.status===`decoded`?n.envelope.fence.generation+1:1})}function Ee(t,r,a){let o=n(i(a));for(let i of t.store.list(m.dirname(m.dirname(r)))){let a=t.store.read(i);if(a.status===`unreattachable`)throw new e(`COMMAND_FAILED`,`${y($(t.displayName))} ${t.displayName} recovery record is unreattachable: ${a.message}`,{reason:a.reason,retriable:!1,hint:`Retain the corrupt or future-version ${t.displayName} manifest for manual recovery; no replacement capture is safe.`});if(a.status===`decoded`&&a.envelope.lifecycle!==`completed`&&(i===r||n(a.envelope.device)===o))throw new e(`COMMAND_FAILED`,`${y($(t.displayName))} ${t.displayName} resource for this device has not reached a confirmed terminal state`,{reason:`cleanup-unconfirmed`,hint:`Retry exact-owner cleanup using the existing ${t.displayName} manifest before starting a replacement.`})}}function $(e){return/^[aeiou]/i.test(e)?`an`:`a`}function De(e){let t=(t,n)=>e.store.resolvePath(t.resolveSessionDir(n)),n=t=>({definition:e,resolveSessionDir:e=>m.join(t.sessionsDir,c(e)),...t});return Object.freeze({store:e.store,resourcePath:t,createNextFence(t){return Te(e,t)},adoptStarted(t){return x(e,{...t,reportUndurableCleanup:(e,n)=>{n.confirmed?t.admissionLedger.clearUndurableCleanup(e):t.admissionLedger.blockUndurableCleanup(e,n.reason)}},e.store.resolvePath(t.binding.sessionDir))},finishLive(t){return fe(e,t,e.store.resolvePath(t.binding.sessionDir))},finishRecovered(t){return ve(e,t)},forceCleanupLive(t){return z(e,{...t,resourcePath:e.store.resolvePath(t.binding.sessionDir)})},recoverAll(e){return me(n(e))},recoverOne(e,t){return G(n(e),t)}})}export{g as a,ee as i,be as n,te as o,v as r,_ as s,De as t};
package/dist/src/file.js CHANGED
@@ -1 +1 @@
1
- import{J as e,P as t}from"./sdk-contracts.js";import{r as n}from"./diagnostics.js";import{A as r,a as i,r as a,t as o}from"./owner-identity.js";import{t as s}from"./timeouts.js";import c from"node:crypto";import l from"node:fs";import u from"node:path";const d=`owner.json`,f=`.lock`;async function p(e){let t=await e.acquire();try{let n=await e.task();return await t(),n}catch(e){throw await t().catch(()=>void 0),e}}const m=new Set,h=c.randomUUID();function g(e){let t;try{t=l.lstatSync(e)}catch(t){return I(t)===`ENOENT`?{state:l.existsSync(M(e))?`publishing`:`absent`}:{state:`unproven`,reason:`owner-unreadable`}}if(!t.isDirectory())return{state:`unproven`,reason:`non-directory`};let n=L(u.join(e,d));if(n.kind===`unreadable`)return{state:`unproven`,reason:`owner-unreadable`};if(n.kind===`unwritten`)return l.existsSync(M(e))?{state:`publishing`}:{state:`unproven`,reason:`owner-unwritten`};let{pid:r,startTime:i,acquiredAtMs:a}=n.owner;return{state:`held`,owner:{pid:r,startTime:i,acquiredAtMs:a},liveness:o({owner:n.owner})}}function _(e){let{lockDirPath:t}=e;l.mkdirSync(u.dirname(t),{recursive:!0});let n=x(u.join(t,d));if(n.kind===`live`)return{status:`busy`,inspection:n.inspection};if(!N(t))return{status:`busy`,inspection:g(t)};let r=v(t,()=>y(e,n),e=>{e.status===`acquired`&&m.delete(e.claimToken)});return r.status===`acquired`?{status:`acquired`,acquisition:r.acquisition}:{status:r.status,inspection:r.inspection??g(t)}}function v(t,r,i){let a;try{a=r()}catch(r){try{F(t)}catch(r){n({level:`warn`,phase:`process_lock_guard_release_failed`,data:{lockDirPath:t,error:e(r)}})}throw r}try{F(t)}catch(e){throw i(a),e}return a}function y(e,t){let{lockDirPath:n}=e,r=u.join(n,d),i=S(n,r);if(i.kind===`unproven`)return{status:`unproven`,inspection:i.inspection};if(i.kind===`owner`){if(t.kind!==`reclaimable`||!C(i.owner,t.owner))return{status:`busy`};if(k(n,r,i.owner)!==`removed`)return{status:`unproven`}}return b(e,r)}function b(e,t){let{lockDirPath:n,owner:r}=e;try{l.mkdirSync(n)}catch(e){if(I(e)!==`EEXIST`)throw e;return{status:`unproven`}}let i=c.randomUUID(),a={...r,claimToken:i,claimIssuerId:h};try{O(t,a)}catch(e){try{l.rmdirSync(n)}catch{}throw e}return m.add(i),{status:`acquired`,claimToken:i,acquisition:E(e,a)}}function x(e){let t=L(e);if(t.kind!==`owner`)return{kind:`none`};let n=o({owner:t.owner});if(V(n)&&!H(t.owner)){let{pid:e,startTime:r,acquiredAtMs:i}=t.owner;return{kind:`live`,inspection:{state:`held`,owner:{pid:e,startTime:r,acquiredAtMs:i},liveness:n}}}return{kind:`reclaimable`,owner:t.owner}}function S(e,t){let n;try{n=l.lstatSync(e)}catch(e){return I(e)===`ENOENT`?{kind:`absent`}:{kind:`unproven`,inspection:{state:`unproven`,reason:`owner-unreadable`}}}if(!n.isDirectory())return{kind:`unproven`,inspection:{state:`unproven`,reason:`non-directory`}};let r=L(t);return r.kind===`owner`?{kind:`owner`,owner:r.owner}:{kind:`unproven`,inspection:{state:`unproven`,reason:r.kind===`unwritten`?`owner-unwritten`:`owner-unreadable`}}}function C(e,t){return e.pid===t.pid&&e.startTime===t.startTime&&e.acquiredAtMs===t.acquiredAtMs&&e.claimToken===t.claimToken&&e.claimIssuerId===t.claimIssuerId}async function w(e){return(await T(e)).release}async function T(e){let n=Date.now()+(e.timeoutMs??3e4),r=e.pollMs??100;do{let t=_(e);if(t.status===`acquired`)return t.acquisition;let i=n-Date.now();if(i<=0)break;await s(Math.min(r,i))}while(Date.now()<n);let i=L(u.join(e.lockDirPath,d));throw new t(`COMMAND_FAILED`,`Timed out waiting for ${e.description??`process lock`}`,{lockDirPath:e.lockDirPath,reason:`process_lock_timeout`,...B(e.lockDirPath,i),inspection:g(e.lockDirPath),hint:D(e.lockDirPath)})}function E(e,r){let{lockDirPath:i}=e,a=u.join(i,d),o=!0,s=!1;return Object.freeze({assertHeld(){if(!o||A(i,r)!==`owned`)throw new t(`COMMAND_FAILED`,`Process lock acquisition is no longer held`,{lockDirPath:i,ownerOwnershipLost:!0})},async release(){if(s)return;o=!1,m.delete(r.claimToken);let c=A(i,r);if(c===`absent`||c===`not-owner`){s=!0;return}let l=`unverified`;if(await P(i))try{l=k(i,a,r)}finally{F(i)}if(l!==`unverified`){s=!0;return}throw n({level:`warn`,phase:`process_lock_release_unverified`,data:{lockDirPath:i,description:e.description,ownerReleaseUnverified:!0}}),new t(`COMMAND_FAILED`,`Cannot verify ownership of ${e.description??`process lock`}`,{lockDirPath:i,ownerReleaseUnverified:!0,hint:D(i)})}})}function D(e){return`Restore process inspection or stop the verified owner, then retry. Remove ${e} and ${M(e)} only after confirming all users of this state directory have stopped.`}function O(e,t){r({destination:e,contents:JSON.stringify(t)})}function k(e,t,n){let r=A(e,n);return r===`owned`?j(e,t,n):r===`absent`?`removed`:r}function A(e,t){let n=L(u.join(e,d));return n.kind===`unreadable`?`unverified`:n.kind===`unwritten`?l.existsSync(e)?`unverified`:`absent`:i(n.owner,t)&&n.owner.claimToken===t.claimToken?`owned`:`not-owner`}function j(e,t,n){try{if(l.readdirSync(e).some(e=>e!==d))return`unverified`}catch(e){return I(e)===`ENOENT`?`removed`:`unverified`}try{l.unlinkSync(t)}catch(e){if(I(e)!==`ENOENT`)return`unverified`}try{return l.rmdirSync(e),`removed`}catch(e){if(I(e)===`ENOENT`)return`removed`;try{r({destination:t,contents:JSON.stringify(n),publish:`link-exclusive`})}catch{}return`unverified`}}function M(e){return`${e.endsWith(f)?e.slice(0,-5):e}.reclaim${f}`}function N(e){let t;try{t=l.openSync(M(e),`wx`,384)}catch(e){if(I(e)!==`EEXIST`)throw e;return!1}return l.closeSync(t),!0}async function P(e){let t=Date.now()+5e3;for(;!N(e);){if(Date.now()>=t)return!1;await s(5)}return!0}function F(e){try{l.unlinkSync(M(e))}catch(n){throw new t(`COMMAND_FAILED`,`Process lock mutation guard release could not be confirmed.`,{reason:`process_lock_guard_release_failed`,lockDirPath:e,hint:D(e)},n)}}function I(e){return e?.code}function L(e){let t;try{t=l.readFileSync(e,`utf8`)}catch(e){return e?.code===`ENOENT`?{kind:`unwritten`}:{kind:`unreadable`}}let n=R(t);return n?{kind:`owner`,owner:n}:{kind:`unreadable`}}function R(e){let t;try{t=JSON.parse(e)}catch{return null}if(typeof t!=`object`||!t)return null;let n=t;for(let[e,t]of Object.entries(z))if(!t(n[e]))return null;return{pid:n.pid,startTime:typeof n.startTime==`string`?n.startTime:null,acquiredAtMs:n.acquiredAtMs,claimToken:typeof n.claimToken==`string`?n.claimToken:null,claimIssuerId:typeof n.claimIssuerId==`string`?n.claimIssuerId:void 0}}const z={pid:a,acquiredAtMs:e=>typeof e==`number`&&Number.isFinite(e),startTime:e=>e==null||typeof e==`string`};function B(e,t){let n=Date.now(),r;try{r=Math.max(0,Math.round(n-l.statSync(e).mtimeMs))}catch{}return{...r===void 0?{}:{lockAgeMs:r},...t.kind===`owner`?{ownerPid:t.owner.pid,ownerStartTime:t.owner.startTime,ownerAgeMs:Math.max(0,Math.round(n-t.owner.acquiredAtMs)),ownerLiveness:o({owner:t.owner})}:t.kind===`unreadable`?{ownerRecordUnreadable:!0}:{}}}function V(e){return e!==`owner-process-dead`&&e!==`owner-process-reused`}function H(e){return e.pid!==process.pid||e.claimToken===null||e.claimIssuerId!==h?!1:!m.has(e.claimToken)}export{p as a,_ as i,T as n,g as r,w as t};
1
+ import{J as e,P as t}from"./sdk-contracts.js";import{r as n}from"./diagnostics.js";import{a as r,j as i,r as a,t as o}from"./owner-identity.js";import{t as s}from"./timeouts.js";import c from"node:crypto";import l from"node:fs";import u from"node:path";const d=`owner.json`,f=`.lock`;async function p(e){let t=await e.acquire();try{let n=await e.task();return await t(),n}catch(e){throw await t().catch(()=>void 0),e}}const m=new Set,h=c.randomUUID();function g(e){let t;try{t=l.lstatSync(e)}catch(t){return I(t)===`ENOENT`?{state:l.existsSync(M(e))?`publishing`:`absent`}:{state:`unproven`,reason:`owner-unreadable`}}if(!t.isDirectory())return{state:`unproven`,reason:`non-directory`};let n=L(u.join(e,d));if(n.kind===`unreadable`)return{state:`unproven`,reason:`owner-unreadable`};if(n.kind===`unwritten`)return l.existsSync(M(e))?{state:`publishing`}:{state:`unproven`,reason:`owner-unwritten`};let{pid:r,startTime:i,acquiredAtMs:a}=n.owner;return{state:`held`,owner:{pid:r,startTime:i,acquiredAtMs:a},liveness:o({owner:n.owner})}}function _(e){let{lockDirPath:t}=e;l.mkdirSync(u.dirname(t),{recursive:!0});let n=x(u.join(t,d));if(n.kind===`live`)return{status:`busy`,inspection:n.inspection};if(!N(t))return{status:`busy`,inspection:g(t)};let r=v(t,()=>y(e,n),e=>{e.status===`acquired`&&m.delete(e.claimToken)});return r.status===`acquired`?{status:`acquired`,acquisition:r.acquisition}:{status:r.status,inspection:r.inspection??g(t)}}function v(t,r,i){let a;try{a=r()}catch(r){try{F(t)}catch(r){n({level:`warn`,phase:`process_lock_guard_release_failed`,data:{lockDirPath:t,error:e(r)}})}throw r}try{F(t)}catch(e){throw i(a),e}return a}function y(e,t){let{lockDirPath:n}=e,r=u.join(n,d),i=S(n,r);if(i.kind===`unproven`)return{status:`unproven`,inspection:i.inspection};if(i.kind===`owner`){if(t.kind!==`reclaimable`||!C(i.owner,t.owner))return{status:`busy`};if(k(n,r,i.owner)!==`removed`)return{status:`unproven`}}return b(e,r)}function b(e,t){let{lockDirPath:n,owner:r}=e;try{l.mkdirSync(n)}catch(e){if(I(e)!==`EEXIST`)throw e;return{status:`unproven`}}let i=c.randomUUID(),a={...r,claimToken:i,claimIssuerId:h};try{O(t,a)}catch(e){try{l.rmdirSync(n)}catch{}throw e}return m.add(i),{status:`acquired`,claimToken:i,acquisition:E(e,a)}}function x(e){let t=L(e);if(t.kind!==`owner`)return{kind:`none`};let n=o({owner:t.owner});if(V(n)&&!H(t.owner)){let{pid:e,startTime:r,acquiredAtMs:i}=t.owner;return{kind:`live`,inspection:{state:`held`,owner:{pid:e,startTime:r,acquiredAtMs:i},liveness:n}}}return{kind:`reclaimable`,owner:t.owner}}function S(e,t){let n;try{n=l.lstatSync(e)}catch(e){return I(e)===`ENOENT`?{kind:`absent`}:{kind:`unproven`,inspection:{state:`unproven`,reason:`owner-unreadable`}}}if(!n.isDirectory())return{kind:`unproven`,inspection:{state:`unproven`,reason:`non-directory`}};let r=L(t);return r.kind===`owner`?{kind:`owner`,owner:r.owner}:{kind:`unproven`,inspection:{state:`unproven`,reason:r.kind===`unwritten`?`owner-unwritten`:`owner-unreadable`}}}function C(e,t){return e.pid===t.pid&&e.startTime===t.startTime&&e.acquiredAtMs===t.acquiredAtMs&&e.claimToken===t.claimToken&&e.claimIssuerId===t.claimIssuerId}async function w(e){return(await T(e)).release}async function T(e){let n=Date.now()+(e.timeoutMs??3e4),r=e.pollMs??100;do{let t=_(e);if(t.status===`acquired`)return t.acquisition;let i=n-Date.now();if(i<=0)break;await s(Math.min(r,i))}while(Date.now()<n);let i=L(u.join(e.lockDirPath,d));throw new t(`COMMAND_FAILED`,`Timed out waiting for ${e.description??`process lock`}`,{lockDirPath:e.lockDirPath,reason:`process_lock_timeout`,...B(e.lockDirPath,i),inspection:g(e.lockDirPath),hint:D(e.lockDirPath)})}function E(e,r){let{lockDirPath:i}=e,a=u.join(i,d),o=!0,s=!1;return Object.freeze({assertHeld(){if(!o||A(i,r)!==`owned`)throw new t(`COMMAND_FAILED`,`Process lock acquisition is no longer held`,{lockDirPath:i,ownerOwnershipLost:!0})},async release(){if(s)return;o=!1,m.delete(r.claimToken);let c=A(i,r);if(c===`absent`||c===`not-owner`){s=!0;return}let l=`unverified`;if(await P(i))try{l=k(i,a,r)}finally{F(i)}if(l!==`unverified`){s=!0;return}throw n({level:`warn`,phase:`process_lock_release_unverified`,data:{lockDirPath:i,description:e.description,ownerReleaseUnverified:!0}}),new t(`COMMAND_FAILED`,`Cannot verify ownership of ${e.description??`process lock`}`,{lockDirPath:i,ownerReleaseUnverified:!0,hint:D(i)})}})}function D(e){return`Restore process inspection or stop the verified owner, then retry. Remove ${e} and ${M(e)} only after confirming all users of this state directory have stopped.`}function O(e,t){i({destination:e,contents:JSON.stringify(t)})}function k(e,t,n){let r=A(e,n);return r===`owned`?j(e,t,n):r===`absent`?`removed`:r}function A(e,t){let n=L(u.join(e,d));return n.kind===`unreadable`?`unverified`:n.kind===`unwritten`?l.existsSync(e)?`unverified`:`absent`:r(n.owner,t)&&n.owner.claimToken===t.claimToken?`owned`:`not-owner`}function j(e,t,n){try{if(l.readdirSync(e).some(e=>e!==d))return`unverified`}catch(e){return I(e)===`ENOENT`?`removed`:`unverified`}try{l.unlinkSync(t)}catch(e){if(I(e)!==`ENOENT`)return`unverified`}try{return l.rmdirSync(e),`removed`}catch(e){if(I(e)===`ENOENT`)return`removed`;try{i({destination:t,contents:JSON.stringify(n),publish:`link-exclusive`})}catch{}return`unverified`}}function M(e){return`${e.endsWith(f)?e.slice(0,-5):e}.reclaim${f}`}function N(e){let t;try{t=l.openSync(M(e),`wx`,384)}catch(e){if(I(e)!==`EEXIST`)throw e;return!1}return l.closeSync(t),!0}async function P(e){let t=Date.now()+5e3;for(;!N(e);){if(Date.now()>=t)return!1;await s(5)}return!0}function F(e){try{l.unlinkSync(M(e))}catch(n){throw new t(`COMMAND_FAILED`,`Process lock mutation guard release could not be confirmed.`,{reason:`process_lock_guard_release_failed`,lockDirPath:e,hint:D(e)},n)}}function I(e){return e?.code}function L(e){let t;try{t=l.readFileSync(e,`utf8`)}catch(e){return e?.code===`ENOENT`?{kind:`unwritten`}:{kind:`unreadable`}}let n=R(t);return n?{kind:`owner`,owner:n}:{kind:`unreadable`}}function R(e){let t;try{t=JSON.parse(e)}catch{return null}if(typeof t!=`object`||!t)return null;let n=t;for(let[e,t]of Object.entries(z))if(!t(n[e]))return null;return{pid:n.pid,startTime:typeof n.startTime==`string`?n.startTime:null,acquiredAtMs:n.acquiredAtMs,claimToken:typeof n.claimToken==`string`?n.claimToken:null,claimIssuerId:typeof n.claimIssuerId==`string`?n.claimIssuerId:void 0}}const z={pid:a,acquiredAtMs:e=>typeof e==`number`&&Number.isFinite(e),startTime:e=>e==null||typeof e==`string`};function B(e,t){let n=Date.now(),r;try{r=Math.max(0,Math.round(n-l.statSync(e).mtimeMs))}catch{}return{...r===void 0?{}:{lockAgeMs:r},...t.kind===`owner`?{ownerPid:t.owner.pid,ownerStartTime:t.owner.startTime,ownerAgeMs:Math.max(0,Math.round(n-t.owner.acquiredAtMs)),ownerLiveness:o({owner:t.owner})}:t.kind===`unreadable`?{ownerRecordUnreadable:!0}:{}}}function V(e){return e!==`owner-process-dead`&&e!==`owner-process-reused`}function H(e){return e.pid!==process.pid||e.claimToken===null||e.claimIssuerId!==h?!1:!m.has(e.claimToken)}export{p as a,_ as i,T as n,g as r,w as t};
@@ -1,2 +1,2 @@
1
- import{r as e}from"./rolldown-runtime.js";import{P as t}from"./sdk-contracts.js";import{O as n,b as r,f as i}from"./owner-identity.js";import{s as a,u as o}from"./exec.js";import"./command.js";import"./process.js";import{D as s,c,f as l,g as u,h as d,n as f,o as ee,r as te,t as p,w as m,y as h}from"./host-file.js";import{a as g,i as _,n as v}from"./tool-provider.js";import{createHash as ne}from"node:crypto";import y from"node:path";import{fileURLToPath as re}from"node:url";var b=e({MACOS_HELPER_REFUSAL_REASONS:()=>A,macOsClickScheduleMs:()=>J,quitMacOsApp:()=>U,resolveFrontmostMacOsApp:()=>H,resolveMacOsHelperPackageRootFrom:()=>j,runMacOsAlertAction:()=>G,runMacOsFillAction:()=>Z,runMacOsPermissionAction:()=>W,runMacOsPressAction:()=>Y,runMacOsReadTextAction:()=>q,runMacOsScreenshotAction:()=>$,runMacOsScrollAction:()=>Q,runMacOsSnapshotAction:()=>K,runMacOsTypeAction:()=>X,startMacOsAudioProbeProcess:()=>z});const x=`agent-device-macos-helper`,S=`AGENT_DEVICE_MACOS_HELPER_BIN`,C=y.join(l(),`.agent-device`,`macos-helper`,`current`),w=y.join(C,`manifest.json`),T=/^[A-Za-z0-9_-]+(?:\.[A-Za-z0-9_-]+)+$/;function E(e){let n=e.trim();if(!T.test(n))throw new t(`INVALID_ARGS`,`macOS bundle id must use reverse-DNS form like com.example.App`,{bundleId:e});return n}function D(e,t){t.bundleId&&e.push(`--bundle-id`,E(t.bundleId)),t.surface&&e.push(`--surface`,t.surface)}function O(e,t){t===`app`&&r(`AGENT_DEVICE_MACOS_GHOST_CURSOR`)?.trim()!==`0`&&e.push(`--ghost-cursor`)}function k(e){return e.includes(`--ghost-cursor`)?1e3:0}const A=[`background-pointer-gesture`,`no-accessible-target`,`no-settable-text-input`,`no-scroll-bar`];function j(e){let n=y.dirname(e);for(;;){let e=y.join(n,`apple`,`macos-helper`);if(c(y.join(e,`Package.swift`)))return e;let t=y.dirname(n);if(t===n)break;n=t}throw new t(`COMMAND_FAILED`,`Unable to locate macOS helper package root`,{modulePath:e})}function M(){return j(re(import.meta.url))}function N(){return y.join(M(),`.build`,`release`,x)}function ie(){return y.join(C,x)}async function P(e){let t=await u(e,{withFileTypes:!0});return(await Promise.all(t.map(async t=>{let n=y.join(e,t.name);return t.isDirectory()?t.name===`.build`?[]:await P(n):!t.isFile()||!t.name.endsWith(`.swift`)&&t.name!==`Package.swift`?[]:[n]}))).flat().sort()}async function F(e){let t=await P(e),n=ne(`sha256`);for(let r of t)n.update(y.relative(e,r)),n.update(`\0`),n.update(await d(r)),n.update(`\0`);let r=await g(`swift`,[`--version`],{allowFailure:!0,cwd:e,timeoutMs:1e4});return n.update(`swift-version`),n.update(`\0`),n.update(r.stdout||r.stderr||`exit:${r.exitCode}`),n.update(`\0`),n.digest(`hex`)}async function I(){try{let e=JSON.parse(await h(w));return typeof e.fingerprint==`string`?e.fingerprint:null}catch{return null}}async function L(){let e=await a(r(S),S);if(e)return e;let t=M(),i=await F(t),o=ie();try{if(await I()===i)return await p(o),o}catch{}let c=N();n(`agent-device: building macOS helper (first run or helper update)
2
- `),await g(`swift`,[`build`,`-c`,`release`,`--package-path`,t],{cwd:t,timeoutMs:12e4}),await ee(C);let l=`${o}.tmp`;return await te(c,l),await m(l,o),await f(o,493),await s(w,`${JSON.stringify({fingerprint:i},null,2)}\n`),o}async function R(){let e=r(S)?.trim();if(e){let t=await a(e,S);if(t)return t}if(v())return x;if(i()!==`darwin`)throw new t(`UNSUPPORTED_PLATFORM`,`macOS helper is only available on macOS`);return await L()}async function z(e){let t=await R();return o(t,[`audio-probe`,`--duration-ms`,String(e.durationMs),`--bucket-ms`,String(e.bucketMs),`--out`,e.statusPath],{allowFailure:!0,captureOutput:!0})}const B=3e4;async function V(e,n={}){let r={allowFailure:!0,timeoutMs:n.timeoutMs??B,signal:n.signal,kill:{signal:`SIGTERM`,graceMs:1e3}},i=_().macosHelper,a=i?x:await R(),o=i?await i.run(e,r):await g(a,e,r),s=o.stdout.trim(),c=null;if(s)try{c=JSON.parse(s)}catch{c=null}if(o.exitCode===0&&c?.ok)return c.data;let l=c&&!c.ok?c.error?.message??`macOS helper exited with code ${o.exitCode}`:s||o.stderr.trim()||`macOS helper exited with code ${o.exitCode}`;throw new t(`COMMAND_FAILED`,l,{helperPath:a,args:e,stdout:o.stdout,stderr:o.stderr,exitCode:o.exitCode,...c&&!c.ok?c.error?.details:{}})}async function H(){return await V([`app`,`frontmost`])}async function U(e){return await V([`app`,`quit`,`--bundle-id`,E(e)])}async function W(e,t){return await V([`permission`,e,t])}async function G(e,t={}){let n=[`alert`,e];return D(n,t),await V(n)}async function K(e,t={}){let n=[`snapshot`,`--surface`,e];return D(n,t),await V(n,{signal:t.signal})}async function q(e,t,n){let r=[`read`,`--x`,String(e),`--y`,String(t)];return D(r,n),await V(r,{signal:n.signal})}function J(e){let t=e.holdMs&&e.holdMs>0?Math.max(e.holdMs,40):60,n=Math.max(e.clicks??1,1),r=Math.max(e.intervalMs??120,0);return n*(e.doubleClick?2*t+80:t)+(n-1)*r}async function Y(e,t,n){let r=[`press`,`--x`,String(e),`--y`,String(t)];n.holdMs&&n.holdMs>0&&r.push(`--hold-ms`,String(n.holdMs));let i=n.clicks??1;return i>1&&(r.push(`--clicks`,String(i)),n.intervalMs!==void 0&&r.push(`--interval-ms`,String(Math.max(n.intervalMs,0)))),n.doubleClick&&r.push(`--double-click`),D(r,n),O(r,n.surface),await V(r,{signal:n.signal,timeoutMs:J(n)+B+k(r)})}async function X(e,t){let n=[`type`,`--text`,e];return t.delayMs&&t.delayMs>0&&n.push(`--delay-ms`,String(t.delayMs)),D(n,{bundleId:t.bundleId}),O(n,`app`),await V(n,{signal:t.signal,timeoutMs:B+k(n)+e.length*(t.delayMs??0)})}async function Z(e,t,n,r){let i=[`fill`,`--x`,String(e),`--y`,String(t),`--text`,n];return D(i,{bundleId:r.bundleId}),O(i,`app`),await V(i,{signal:r.signal,timeoutMs:B+k(i)})}async function Q(e,t){let n=[`scroll`,`--direction`,e];return t.amount!==void 0&&n.push(`--amount`,String(t.amount)),t.pixels!==void 0&&n.push(`--pixels`,String(t.pixels)),D(n,{bundleId:t.bundleId}),O(n,`app`),await V(n,{signal:t.signal,timeoutMs:B+k(n)})}async function $(e,t){let n=[`screenshot`,`--out`,e];return D(n,t),await V(n,{signal:t.signal})}export{G as a,Y as c,X as d,z as f,H as i,$ as l,b as n,Z as o,U as r,W as s,A as t,Q as u};
1
+ import{r as e}from"./rolldown-runtime.js";import{P as t}from"./sdk-contracts.js";import{b as n,f as r,k as i}from"./owner-identity.js";import{s as a,u as o}from"./exec.js";import"./command.js";import"./process.js";import{D as s,c,f as l,g as u,h as d,n as f,o as ee,r as te,t as p,w as m,y as h}from"./host-file.js";import{a as g,i as _,n as v}from"./tool-provider.js";import{createHash as ne}from"node:crypto";import y from"node:path";import{fileURLToPath as re}from"node:url";var b=e({MACOS_HELPER_REFUSAL_REASONS:()=>A,macOsClickScheduleMs:()=>J,quitMacOsApp:()=>U,resolveFrontmostMacOsApp:()=>H,resolveMacOsHelperPackageRootFrom:()=>j,runMacOsAlertAction:()=>G,runMacOsFillAction:()=>Z,runMacOsPermissionAction:()=>W,runMacOsPressAction:()=>Y,runMacOsReadTextAction:()=>q,runMacOsScreenshotAction:()=>$,runMacOsScrollAction:()=>Q,runMacOsSnapshotAction:()=>K,runMacOsTypeAction:()=>X,startMacOsAudioProbeProcess:()=>z});const x=`agent-device-macos-helper`,S=`AGENT_DEVICE_MACOS_HELPER_BIN`,C=y.join(l(),`.agent-device`,`macos-helper`,`current`),w=y.join(C,`manifest.json`),T=/^[A-Za-z0-9_-]+(?:\.[A-Za-z0-9_-]+)+$/;function E(e){let n=e.trim();if(!T.test(n))throw new t(`INVALID_ARGS`,`macOS bundle id must use reverse-DNS form like com.example.App`,{bundleId:e});return n}function D(e,t){t.bundleId&&e.push(`--bundle-id`,E(t.bundleId)),t.surface&&e.push(`--surface`,t.surface)}function O(e,t){t===`app`&&n(`AGENT_DEVICE_MACOS_GHOST_CURSOR`)?.trim()!==`0`&&e.push(`--ghost-cursor`)}function k(e){return e.includes(`--ghost-cursor`)?1e3:0}const A=[`background-pointer-gesture`,`no-accessible-target`,`no-settable-text-input`,`no-scroll-bar`];function j(e){let n=y.dirname(e);for(;;){let e=y.join(n,`apple`,`macos-helper`);if(c(y.join(e,`Package.swift`)))return e;let t=y.dirname(n);if(t===n)break;n=t}throw new t(`COMMAND_FAILED`,`Unable to locate macOS helper package root`,{modulePath:e})}function M(){return j(re(import.meta.url))}function N(){return y.join(M(),`.build`,`release`,x)}function ie(){return y.join(C,x)}async function P(e){let t=await u(e,{withFileTypes:!0});return(await Promise.all(t.map(async t=>{let n=y.join(e,t.name);return t.isDirectory()?t.name===`.build`?[]:await P(n):!t.isFile()||!t.name.endsWith(`.swift`)&&t.name!==`Package.swift`?[]:[n]}))).flat().sort()}async function F(e){let t=await P(e),n=ne(`sha256`);for(let r of t)n.update(y.relative(e,r)),n.update(`\0`),n.update(await d(r)),n.update(`\0`);let r=await g(`swift`,[`--version`],{allowFailure:!0,cwd:e,timeoutMs:1e4});return n.update(`swift-version`),n.update(`\0`),n.update(r.stdout||r.stderr||`exit:${r.exitCode}`),n.update(`\0`),n.digest(`hex`)}async function I(){try{let e=JSON.parse(await h(w));return typeof e.fingerprint==`string`?e.fingerprint:null}catch{return null}}async function L(){let e=await a(n(S),S);if(e)return e;let t=M(),r=await F(t),o=ie();try{if(await I()===r)return await p(o),o}catch{}let c=N();i(`agent-device: building macOS helper (first run or helper update)
2
+ `),await g(`swift`,[`build`,`-c`,`release`,`--package-path`,t],{cwd:t,timeoutMs:12e4}),await ee(C);let l=`${o}.tmp`;return await te(c,l),await m(l,o),await f(o,493),await s(w,`${JSON.stringify({fingerprint:r},null,2)}\n`),o}async function R(){let e=n(S)?.trim();if(e){let t=await a(e,S);if(t)return t}if(v())return x;if(r()!==`darwin`)throw new t(`UNSUPPORTED_PLATFORM`,`macOS helper is only available on macOS`);return await L()}async function z(e){let t=await R();return o(t,[`audio-probe`,`--duration-ms`,String(e.durationMs),`--bucket-ms`,String(e.bucketMs),`--out`,e.statusPath],{allowFailure:!0,captureOutput:!0})}const B=3e4;async function V(e,n={}){let r={allowFailure:!0,timeoutMs:n.timeoutMs??B,signal:n.signal,kill:{signal:`SIGTERM`,graceMs:1e3}},i=_().macosHelper,a=i?x:await R(),o=i?await i.run(e,r):await g(a,e,r),s=o.stdout.trim(),c=null;if(s)try{c=JSON.parse(s)}catch{c=null}if(o.exitCode===0&&c?.ok)return c.data;let l=c&&!c.ok?c.error?.message??`macOS helper exited with code ${o.exitCode}`:s||o.stderr.trim()||`macOS helper exited with code ${o.exitCode}`;throw new t(`COMMAND_FAILED`,l,{helperPath:a,args:e,stdout:o.stdout,stderr:o.stderr,exitCode:o.exitCode,...c&&!c.ok?c.error?.details:{}})}async function H(){return await V([`app`,`frontmost`])}async function U(e){return await V([`app`,`quit`,`--bundle-id`,E(e)])}async function W(e,t){return await V([`permission`,e,t])}async function G(e,t={}){let n=[`alert`,e];return D(n,t),await V(n)}async function K(e,t={}){let n=[`snapshot`,`--surface`,e];return D(n,t),await V(n,{signal:t.signal})}async function q(e,t,n){let r=[`read`,`--x`,String(e),`--y`,String(t)];return D(r,n),await V(r,{signal:n.signal})}function J(e){let t=e.holdMs&&e.holdMs>0?Math.max(e.holdMs,40):60,n=Math.max(e.clicks??1,1),r=Math.max(e.intervalMs??120,0);return n*(e.doubleClick?2*t+80:t)+(n-1)*r}async function Y(e,t,n){let r=[`press`,`--x`,String(e),`--y`,String(t)];n.holdMs&&n.holdMs>0&&r.push(`--hold-ms`,String(n.holdMs));let i=n.clicks??1;return i>1&&(r.push(`--clicks`,String(i)),n.intervalMs!==void 0&&r.push(`--interval-ms`,String(Math.max(n.intervalMs,0)))),n.doubleClick&&r.push(`--double-click`),D(r,n),O(r,n.surface),await V(r,{signal:n.signal,timeoutMs:J(n)+B+k(r)})}async function X(e,t){let n=[`type`,`--text`,e];return t.delayMs&&t.delayMs>0&&n.push(`--delay-ms`,String(t.delayMs)),D(n,{bundleId:t.bundleId}),O(n,`app`),await V(n,{signal:t.signal,timeoutMs:B+k(n)+e.length*(t.delayMs??0)})}async function Z(e,t,n,r){let i=[`fill`,`--x`,String(e),`--y`,String(t),`--text`,n];return D(i,{bundleId:r.bundleId}),O(i,`app`),await V(i,{signal:r.signal,timeoutMs:B+k(i)})}async function Q(e,t){let n=[`scroll`,`--direction`,e];return t.amount!==void 0&&n.push(`--amount`,String(t.amount)),t.pixels!==void 0&&n.push(`--pixels`,String(t.pixels)),D(n,{bundleId:t.bundleId}),O(n,`app`),await V(n,{signal:t.signal,timeoutMs:B+k(n)})}async function $(e,t){let n=[`screenshot`,`--out`,e];return D(n,t),await V(n,{signal:t.signal})}export{G as a,Y as c,X as d,z as f,H as i,$ as l,b as n,Z as o,U as r,W as s,A as t,Q as u};
@@ -0,0 +1 @@
1
+ import{K as e}from"./sdk-contracts.js";import{a as t,d as n,h as r,o as i}from"./adb-executor.js";import{S as a,l as o,m as s,n as c,o as l,u}from"./ime-state.js";async function d(o){let d=c(o);return d?await l(d.stateDir,o.id,async()=>{if(c(o)!==d)return{kind:`not-owned`};let l=t(o),{manifest:m}=await a(i(o));r({level:`warn`,phase:`android_test_ime_rebind`,data:{device:o.id}}),d.rebindUnconfirmed=!0;let h=`record-write`;try{if(!await s(l))return f(o.id,h);h=`command-failed`;for(let e of[`disable`,`enable`,`set`])if((await n(l,[`ime`,e,m.serviceComponent],{allowFailure:!0,timeoutMs:1e4})).exitCode!==0)return f(o.id,h);h=`read-failed`;let e=await u(l);return e===m.serviceComponent?(d.rebindUnconfirmed=!await p(l,o.id),{kind:`confirmed`}):f(o.id,e?`helper-not-selected`:`read-failed`)}catch(t){if(e(t))throw t}return f(o.id,h)}):{kind:`not-owned`}}function f(e,t){return r({level:`warn`,phase:`android_test_ime_rebind_failed`,data:{device:e,cause:t}}),{kind:`unconfirmed`,cause:t}}async function p(e,t){let n=await o(e);return n||r({level:`warn`,phase:`android_test_ime_rebind_record_clear_failed`,data:{device:t}}),n}export{d as rebindAndroidTestIme};
@@ -0,0 +1 @@
1
+ import{J as e,P as t}from"./sdk-contracts.js";import{d as n,g as r,h as i}from"./adb-executor.js";import{c as a,n as o}from"./adb-failure.js";import{t as s}from"./keyed-lock.js";function c(e,n,r){if(typeof e!=`number`||!Number.isInteger(e))throw new t(`INVALID_ARGS`,`Android ${r} manifest ${n} must be an integer.`);return e}function l(e,n,r,i){if(e!==r)throw new t(`INVALID_ARGS`,`Android ${i} manifest ${n} must be "${r}".`);return r}function u(e,n,r){if(typeof e!=`string`||e.length===0)throw new t(`INVALID_ARGS`,`Android ${r} manifest ${n} is required.`);return e}function d(e,n){let r=u(e,`sha256`,n).trim().toLowerCase();if(r.length!==64||!/^[0-9a-f]+$/.test(r))throw new t(`INVALID_ARGS`,`Android ${n} manifest sha256 must be a 64-character hex string.`);return r}const f=`com.callstack.agentdevice.imehelper`,p=`com.callstack.agentdevice.imehelper/.TestInputMethodService`,m=`android-ime-helper-v1`,h=p;async function g(e){return e.imeHelperArtifact??await _()}async function _(){return await r().resolveHelperArtifact({helperDirName:`ime-helper`,manifestFileName:e=>`agent-device-android-ime-helper-${e}.manifest.json`,parseManifest:y,unavailableMessage:`Android test IME text entry requires the bundled Android IME helper artifact, but it was not found or could not be read`})}const v=`IME helper`;function y(e){if(!e||typeof e!=`object`||Array.isArray(e))throw new t(`INVALID_ARGS`,`Android IME helper manifest must be an object.`);let n=e;return{name:l(n.name,`name`,`android-ime-helper`,v),version:u(n.version,`version`,v),assetName:u(n.assetName,`assetName`,v),sha256:d(n.sha256,v),packageName:l(n.packageName,`packageName`,f,v),versionCode:c(n.versionCode,`versionCode`,v),serviceComponent:l(n.serviceComponent,`serviceComponent`,p,v),broadcastProtocol:l(n.broadcastProtocol,`broadcastProtocol`,m,v)}}const b=new Set;async function x(e){return await r().ensureHelperInstalled({cache:b,installTimeoutMs:3e4,helperLabel:`Android IME helper`},e)}function S(){b.clear()}function C(e){return`${e.platform}:${e.id}`}function w(e){return e===f}async function T(e,t,n){await D(e,t,`com.callstack.agentdevice.imehelper.ACTION_INPUT_TEXT_B64`,{text:Buffer.from(n,`utf8`).toString(`base64`)})}async function E(e,t){await D(e,t,`com.callstack.agentdevice.imehelper.ACTION_CLEAR_TEXT`,{})}async function D(e,t,r,i){let s=[`am`,`broadcast`,`-p`,t,`-a`,r];s.push(`--es`,`protocol`,m);for(let[e,t]of Object.entries(i))s.push(`--es`,e,t);try{let i=await n(e,s,{allowFailure:!0,timeoutMs:1e4});if(i.exitCode!==0)throw o(`Android IME helper broadcast failed`,i,{action:r,packageName:t})}catch(e){throw a(e)}}const O=`agent_device_ime_helper_previous_ime`,k=`agent_device_ime_helper_rebind_displaced`,A=`secure`,j=`default_input_method`,M={previousIme:O,rebindDisplaced:k,defaultInputMethod:j};async function N(e){let t=await n(e,[`settings`,`get`,A,j],{allowFailure:!0,timeoutMs:5e3});return U(t.exitCode===0?t.stdout:``)}async function P(e){return await H(e,O)||void 0}async function F(e,t){return(await n(e,[`settings`,`put`,A,O,t],{allowFailure:!0,timeoutMs:5e3})).exitCode===0&&await P(e)===t}async function I(e){await n(e,[`settings`,`delete`,A,O],{allowFailure:!0,timeoutMs:5e3})}async function L(e){let t=await H(e,O),n=await H(e,k);if(t===void 0||n===void 0)return{kind:`unreadable`};let r=n===`1`;return t?{kind:`owned`,previousIme:t,rebindDisplaced:r}:{kind:`absent`,rebindDisplaced:r}}async function R(e){return(await n(e,[`settings`,`put`,A,k,`1`],{allowFailure:!0,timeoutMs:5e3})).exitCode===0&&await H(e,k)===`1`}async function z(e){return await n(e,[`settings`,`delete`,A,k],{allowFailure:!0,timeoutMs:5e3}),await H(e,k)===``}async function B(t,n,r){try{(n?await F(t,n):await V(t))||i({level:`warn`,phase:`android_test_ime_record_rollback_failed`,data:{device:r,hadPriorRecord:n!==void 0}})}catch(t){i({level:`warn`,phase:`android_test_ime_record_rollback_failed`,data:{device:r,hadPriorRecord:n!==void 0,error:e(t).message}})}}async function V(e){return await I(e),await P(e)===void 0}async function H(e,t){let r=await n(e,[`settings`,`get`,A,t],{allowFailure:!0,timeoutMs:5e3});return r.exitCode===0?U(r.stdout):void 0}function U(e){let t=e.trim();return!t||t===`null`?``:t}const W=new Map,G=new Map;function K(e){return W.has(C(e))}function q(e){return W.get(C(e))}function J(e,t,n){return s(G,`${e}:${t}`,n)}function Y(){W.clear()}function X(e,t,n=`/state`){let r=C(e);t?W.set(r,{stateDir:n,rebindUnconfirmed:!1}):W.delete(r)}export{T as C,g as S,l as T,x as _,X as a,S as b,I as c,L as d,B as f,E as g,h,Y as i,z as l,R as m,q as n,J as o,F as p,K as r,M as s,W as t,N as u,C as v,c as w,_ as x,w as y};
@@ -1 +1 @@
1
- import{r as e}from"./rolldown-runtime.js";import{a as t,b as n,c as r,f as i,i as a,m as o,n as s,p as c,r as l,s as u,t as d,u as f}from"./session-stream.js";import{execFile as p}from"node:child_process";import m from"fs";import{Readable as h}from"stream";import g from"os";import _ from"path";import v from"crypto";const y=/^[0-9a-f]{64}$/i,b=/^[0-9a-f]{32}$/i;function x(e){return v.createHash(`sha256`).update(e).digest(`hex`).slice(0,32)}function S(e,t){let n=t*e.blockSize;return{offset:n,length:Math.min(e.blockSize,e.fileSize-n)}}async function C(e){return await new Promise((t,n)=>{let r=v.createHash(`sha256`),i=m.createReadStream(e);i.on(`data`,e=>r.update(e)),i.on(`error`,n),i.on(`end`,()=>t(r.digest(`hex`)))})}function w(e,t){if(!e||typeof e!=`object`)throw Error(`Invalid seed signature: expected an object`);let n=e;if(n.version!==1)throw Error(`Unsupported seed signature version: ${String(n.version)}`);if(!Number.isSafeInteger(n.blockSize)||n.blockSize<=0)throw Error(`Invalid seed signature blockSize`);if(!Number.isSafeInteger(n.fileSize)||n.fileSize<0)throw Error(`Invalid seed signature fileSize`);if(typeof n.sha256!=`string`||!y.test(n.sha256)||n.sha256.toLowerCase()!==t.toLowerCase())throw Error(`Seed signature sha256 does not match the requested seed`);if(!Array.isArray(n.blocks))throw Error(`Invalid seed signature blocks`);let r=Math.ceil(n.fileSize/n.blockSize);if(n.blocks.length!==r)throw Error(`Invalid seed signature block count: got ${n.blocks.length}, expected ${r}`);let i=n.blocks.map((e,t)=>{if(!e||!Number.isInteger(e.w)||e.w<0||e.w>4294967295||typeof e.s!=`string`||!b.test(e.s))throw Error(`Invalid seed signature block at index ${t}`);return{w:e.w,s:e.s.toLowerCase()}});return{version:n.version,blockSize:n.blockSize,fileSize:n.fileSize,sha256:n.sha256.toLowerCase(),blocks:i}}async function T(e,t,r){let i=await n.fetch(e,{method:`GET`,headers:{Authorization:`Bearer ${t}`}});if(!i.ok){let e=await i.text();throw Error(`Seed signature download failed: ${i.status} ${e}`)}return w(await i.json(),r)}async function E(e,t,n,r){let i=0;for(;i<n;){let{bytesRead:a}=await e.read(t,i,n-i,r+i);if(a<=0)throw Error(`Unexpected EOF at offset ${r+i}`);i+=a}}async function D(e,t,n,r,i){let a=n.blockSize,o=await m.promises.open(e.path,`r`);try{if(e.size<a||i.size===0)return;let s=Buffer.allocUnsafe(a);await E(o,s,a,0);let c=0,l=0;for(let e=0;e<a;e++){let t=s[e];c=c+t&65535,l=l+(a-e)*t&65535}let u=0,d=0,f,p=async t=>{f??=Buffer.allocUnsafe(a),await E(o,f,a,d);let s=x(f);for(let a of t)i.has(a)&&n.blocks[a].s===s&&(r.set(a,{sourcePath:e.path,sourceOffset:d}),i.delete(a))},m=t.get(l*65536+c);m?.some(e=>i.has(e))&&await p(m);let h=Buffer.allocUnsafe(1048576),g=a;for(;g<e.size&&i.size>0;){let n=Math.min(h.byteLength,e.size-g),{bytesRead:r}=await o.read(h,0,n,g);if(r<=0)break;for(let e=0;e<r&&i.size>0;e++){let n=s[u],r=h[e];s[u]=r,u++,u===a&&(u=0),c=c-n+r&65535,l=l-(a*n&65535)+c&65535,d++,m=t.get(l*65536+c),m?.some(e=>i.has(e))&&await p(m)}g+=r}}finally{await o.close()}}async function O(e){let t=[];for(let n of e){let e=await m.promises.stat(n).catch(()=>void 0);e?.isFile()&&t.push({path:n,size:e.size})}return t}async function k(e,t,n){for(let r of e){let e=await m.promises.open(r.path,`r`),i=Buffer.allocUnsafe(t.blockSize);try{for(let a=0;a<t.blocks.length;a++){if(n.has(a))continue;let o=S(t,a);o.offset+o.length>r.size||(await E(e,i,o.length,o.offset),x(i.subarray(0,o.length))===t.blocks[a].s&&n.set(a,{sourcePath:r.path,sourceOffset:o.offset}))}}finally{await e.close()}}}async function A(e,t,n){if(t.fileSize===0||t.fileSize%t.blockSize===0)return;let r=t.blocks.length-1;if(n.has(r))return;let i=S(t,r),a=t.blocks[r].s,o=Buffer.allocUnsafe(i.length);for(let t of e){if(t.size<i.length)continue;let e=t.size-i.length;if(e===i.offset)continue;let s=await m.promises.open(t.path,`r`);try{if(await E(s,o,i.length,e),x(o)===a){n.set(r,{sourcePath:t.path,sourceOffset:e});return}}finally{await s.close()}}}function j(e,t){let n=0;for(let r=0;r<e.blocks.length;r++)t.has(r)||(n+=S(e,r).length);return(e.blocks.length===0?1:t.size/e.blocks.length)>=.8&&n<=33554432}async function M(e,t,n){let r=Math.floor(t.fileSize/t.blockSize),i=new Set,a=new Map;for(let e=0;e<r;e++){if(n.has(e))continue;i.add(e);let r=t.blocks[e].w,o=a.get(r)??[];o.push(e),a.set(r,o)}for(let r of e){if(i.size===0)return;await D(r,a,t,n,i)}}async function N(e,t){let n=await O(e),r=new Map;return await k(n,t,r),await A(n,t,r),j(t,r)||await M(n,t,r),r}function P(e,t){let n=[],r;for(let i=0;i<=e.blocks.length;i++){let a=i<e.blocks.length&&!t.has(i);if(a&&r===void 0)r=i;else if(!a&&r!==void 0){let t=S(e,r),a=S(e,i-1);n.push({start:t.offset,end:a.offset+a.length-1}),r=void 0}}return n}async function F(e,t,n){let r=new Map;try{for(let[i,a]of n){let n=r.get(a.sourcePath);n||(n=await m.promises.open(a.sourcePath,`r`),r.set(a.sourcePath,n));let o=S(t,i),s=Buffer.allocUnsafe(o.length);await E(n,s,o.length,a.sourceOffset),await I(e,s,o.offset)}}finally{await Promise.all([...r.values()].map(e=>e.close()))}}async function I(e,t,n){let r=0;for(;r<t.byteLength;){let{bytesWritten:i}=await e.write(t,r,t.byteLength-r,n+r);if(i<=0)throw Error(`Unable to write reconstructed seed at offset ${n+r}`);r+=i}}async function L(e,t,r,i,a,o){let s=await n.fetch(e,{method:`GET`,headers:{Authorization:`Bearer ${t}`,Range:`bytes=${r.start}-${r.end}`}});if(s.status!==206||!s.body){let e=await s.text();throw Error(`Seed range download failed: ${s.status} ${e}`)}let c=`bytes ${r.start}-${r.end}/${i}`;if(s.headers.get(`content-range`)!==c)throw Error(`Invalid Content-Range for seed: ${s.headers.get(`content-range`)??`<missing>`}`);let l=r.end-r.start+1,u=0,d=h.fromWeb(s.body);for await(let e of d){let t=Buffer.isBuffer(e)?e:Buffer.from(e);if(u+t.byteLength>l)throw Error(`Seed range response exceeded the requested length`);await I(a,t,r.start+u),u+=t.byteLength,o(t.byteLength)}if(u!==l)throw Error(`Seed range response was truncated: got ${u}, expected ${l}`)}async function R(e){let t=e.expectedSha256.toLowerCase(),n=await T(e.signatureUrl,e.token,t),r=await N([...new Set(e.sourcePaths.map(e=>_.resolve(e)))],n),i=P(n,r),a=i.reduce((e,t)=>e+t.end-t.start+1,0),o=0;e.onProgress?.(0,a),await m.promises.mkdir(_.dirname(e.outputPath),{recursive:!0});let s=`${e.outputPath}.reconstruct-${process.pid}-${v.randomBytes(6).toString(`hex`)}`,c=await m.promises.open(s,`wx`),l=!1,u=!1;try{await c.truncate(n.fileSize),await F(c,n,r);for(let t of i)await L(e.seedUrl,e.token,t,n.fileSize,c,t=>{o+=t,e.onProgress?.(o,a)});await c.close(),l=!0;let d=await C(s);if(d!==t)throw Error(`Reconstructed seed SHA-256 mismatch: got ${d}, expected ${t}`);await m.promises.rm(e.outputPath,{force:!0}),await m.promises.rename(s,e.outputPath),u=!0}finally{l||await c.close().catch(()=>void 0),u||await m.promises.rm(s,{force:!0})}return{downloadedBytes:o,totalDownloadBytes:a,matchedBlocks:r.size}}function z(e){return`${e}/sync/state`}function B(e,t){return`${e}/sync/seeds/${encodeURIComponent(t)}`}async function V(e){return await new Promise((t,n)=>{let r=v.createHash(`sha256`),i=m.createReadStream(e);i.on(`data`,e=>r.update(e)),i.on(`error`,n),i.on(`end`,()=>t(r.digest(`hex`)))})}async function H(e,t){let r=await n.fetch(z(e),{method:`GET`,headers:{Authorization:`Bearer ${t}`}});if(!r.ok){let e=await r.text();throw Error(`Failed to fetch Android sync state: ${r.status} ${e}`)}return await r.json()}async function ee(e,t,n,i,a,o){let s=_.basename(e),c=_.join(t,s),l=await H(n,i).catch(e=>{a(`debug`,`android sync state unavailable: ${e instanceof Error?e.message:String(e)}`)});if(!l)return;let u=new Set;for(let e of l.roots??[])for(let t of e.files??[])t.path===s&&typeof t.sha256==`string`&&u.add(t.sha256.toLowerCase());let d=[...l.seeds??[]].filter(e=>typeof e.sha256==`string`&&/^[0-9a-f]{64}$/i.test(e.sha256)).sort((e,t)=>(t.mtime??0)-(e.mtime??0));for(let e of d)u.add(e.sha256.toLowerCase());let f;if(m.existsSync(c)){let e=(await V(c)).toLowerCase();if(u.has(e))return;a(`debug`,`local basis ${e} unknown to instance; re-seeding basis cache`),f=c}let p=(await V(e)).toLowerCase();if(u.has(p)){await m.promises.mkdir(_.dirname(c),{recursive:!0}),await m.promises.copyFile(e,c),a(`debug`,`seeded Android basis cache from local APK already known to instance: ${p}`);return}let h=d[0];if(!h){f&&await m.promises.rm(f,{force:!0});return}let g=B(n,h.sha256);try{let t=await R({signatureUrl:`${g}.sig`,seedUrl:g,token:i,sourcePaths:f?[e,f]:[e],outputPath:c,expectedSha256:h.sha256,...o?{onProgress:o}:{}});a(`debug`,`reconstructed Android basis seed ${h.sha256}: matched=${t.matchedBlocks} downloaded=${t.downloadedBytes}`)}catch(e){a(`debug`,`basis seed reconstruction unavailable; downloading full seed: ${e instanceof Error?e.message:String(e)}`),o?.(0,h.size??0),await r(g,i,c,o),a(`debug`,`seeded Android basis cache from full instance seed: ${h.sha256}`)}}var U=e({RecordingQuality:()=>K,createInstanceClient:()=>q});function W(e){let t=new URL(e);return t.protocol=t.protocol===`https:`?`wss:`:`ws:`,t.search=``,t.hash=``,t.pathname=`${t.pathname.replace(/\/$/,``)}/ws`,t.toString().replace(/\/$/,``)}function te(e){return`${e}/files?path=%2Fdata%2Flocal%2Ftmp%2Frecordings%2Fvideo_recording.mp4`}function G(e,t){if(!Number.isInteger(t)||t<0)throw Error(`${e} must be a non-negative integer Kbps value`)}async function ne(e){if(!(await m.promises.stat(e).catch(()=>null))?.isFile())throw Error(`APK file not found: ${e}`);let t=await m.promises.open(e,`r`);try{let n=Buffer.alloc(4),{bytesRead:r}=await t.read(n,0,4,0);if(r<4||n[0]!==80||n[1]!==75)throw Error(`File is not an APK/ZIP archive: ${e}`)}finally{await t.close()}}var K;(function(e){e[e.Q5=5]=`Q5`,e[e.Q6=6]=`Q6`,e[e.Q7=7]=`Q7`,e[e.Q8=8]=`Q8`,e[e.Q9=9]=`Q9`,e[e.Q10=10]=`Q10`})(K||={});function re(e){return e.map(e=>`'${e.replace(/'/g,`'\\''`)}'`).join(` `)}async function q(e){let h=`${W(e.apiUrl)}?token=${e.token}`,y=e.apiUrl,b=e.logLevel??`info`,x=e.maxReconnectAttempts??6,S=e.reconnectDelay??1e3,C=e.maxReconnectDelay??3e4,w,T=`connecting`,E=0,D,O=!1,k,A=new Map,j=new Map,M=new Map,N=new Set,P={debug:(...e)=>{b===`debug`&&console.log(`[Endpoint]`,...e)},info:(...e)=>{(b===`info`||b===`debug`)&&console.log(`[Endpoint]`,...e)},warn:(...e)=>{(b===`warn`||b===`info`||b===`debug`)&&console.warn(`[Endpoint]`,...e)},error:(...e)=>{b!==`none`&&console.error(`[Endpoint]`,...e)}},F=e=>{T!==e&&(T=e,P.debug(`Connection state changed to: ${e}`),N.forEach(t=>{try{t(e)}catch(e){P.error(`Error in connection state callback:`,e)}}))},I=e=>{A.forEach(t=>{clearTimeout(t.timeout),t.reject(Error(e))}),A.clear(),j.forEach(t=>{t.forEach(t=>{clearTimeout(t.timeout),t.reject(Error(e))})}),j.clear()},L=()=>{D&&=(clearTimeout(D),void 0),R&&=(clearInterval(R),void 0),w&&=(w.removeAllListeners(),(w.readyState===c.default.OPEN||w.readyState===c.default.CONNECTING)&&w.close(),void 0)},R,z=0,B=Math.random().toString(36).substring(2,15)+Math.random().toString(36).substring(2,15);return new Promise((V,H)=>{let U=!1,W=e=>(z+=1,`${e}-${Date.now()}-${z}`),K=(e,t)=>{let n=A.get(e);if(!n){P.debug(`Received response for unknown/already-settled request: ${e}`);return}clearTimeout(n.timeout),A.delete(e),n.resolve(t)},q=(e,t)=>{let n=A.get(e);if(!n){P.debug(`Received error for unknown/already-settled request: ${e}`);return}clearTimeout(n.timeout),A.delete(e),n.reject(t)},J=e=>{if(`message`in e&&typeof e.message==`string`)return e.message;if(`error`in e&&typeof e.error==`string`&&e.error)return e.error;if(`error`in e&&e.error&&typeof e.error==`object`){let t=e.error;return typeof t.message==`string`&&t.message?t.message:typeof t.code==`string`&&t.code?t.code:`Server returned ${String(e.type)} with an error payload but no error message/code`}},ie=e=>{if(!(`type`in e)||typeof e.type!=`string`)return!1;switch(e.type){case`screenshotResult`:case`getElementTreeResult`:case`findElementResult`:case`tapResult`:case`setTextResult`:case`pressKeyResult`:case`scrollScreenResult`:case`scrollElementResult`:case`openUrlResult`:case`launchAppResult`:case`terminateAppResult`:case`watchAppResult`:case`unwatchAppResult`:case`listAppsResult`:case`playOnMicrophoneResult`:case`cameraControlResult`:case`adbShellResult`:case`setWifiBandwidthResult`:case`startRecordingResult`:case`stopRecordingResult`:case`startAppLogCaptureResult`:case`stopAppLogCaptureResult`:case`startEventCaptureResult`:case`stopEventCaptureResult`:return`id`in e&&typeof e.id==`string`;default:return!1}},Y=async(e,t,n=3e4)=>{if(!w||w.readyState!==c.default.OPEN)return Promise.reject(Error(`WebSocket is not connected or connection is not open.`));let r=W(`ts-client`),i=Object.keys(t).length>0?{type:e,id:r,...t,payload:t}:{type:e,id:r};return new Promise((t,a)=>{let o=setTimeout(()=>{A.has(r)&&(A.delete(r),a(Error(`Request ${e} timed out`)))},n);A.set(r,{resolve:e=>t(e),reject:e=>a(e),timeout:o}),w.send(JSON.stringify(i),e=>{e&&(clearTimeout(o),A.delete(r),a(e))})})},ae=()=>{if(O){P.debug(`Skipping reconnection (intentional disconnect)`);return}if(f(k??``)){P.debug(`Skipping reconnection (non-retryable error)`);return}if(E>=x){P.error(`Max reconnection attempts (${x}) reached. Giving up.`,k?`Last error: ${k}`:``),F(`disconnected`);return}let e=Math.min(S*2**E,C);E++,P.debug(`Scheduling reconnection attempt ${E} in ${e}ms...`),F(`reconnecting`),D=setTimeout(()=>{P.debug(`Attempting to reconnect (attempt ${E})...`),X()},e)},X=()=>{L(),F(`connecting`);let e=n.getWebSocketAgent(h);w=new c.default(h,e?{agent:e}:{}),w.on(`message`,e=>{let t;try{t=JSON.parse(e.toString())}catch(t){P.error({data:e,error:t},`Failed to parse JSON message`);return}switch(t.type){case`screenshot`:{if(!(`dataUri`in t)||typeof t.dataUri!=`string`||!(`id`in t)){P.warn(`Received invalid screenshot message:`,t);break}let e=t;P.debug(`Received screenshot data URI for request ${e.id}.`),K(e.id,{dataUri:e.dataUri});break}case`appExit`:{let e=t,{execId:n,packageName:r,reason:i}=e;if(typeof n!=`string`||typeof r!=`string`||typeof i!=`string`){P.warn(`Received malformed appExit message:`,t);break}let a=M.get(n);if(!a){P.debug(`Received appExit for unknown or already handled execId: ${n}`);break}M.delete(n);let o=Array.isArray(e.logs)?e.logs.map(String):[],s={packageName:r,reason:i,...e.crash?{crash:e.crash}:{},...e.anr?{anr:e.anr}:{}};Promise.resolve().then(()=>a(o,s)).catch(e=>{P.error(`Error in onExit callback for execId ${n}:`,e)});break}case`screenshotResult`:{let e=t,n=J(e);if(n){q(e.id,Error(n));break}let r=typeof e.payload?.dataUri==`string`?e.payload.dataUri:``;if(!r){q(e.id,Error(`Received screenshotResult without payload.dataUri`));break}K(e.id,{dataUri:r});break}case`screenshotError`:{if(!(`message`in t)||!(`id`in t)){P.warn(`Received invalid screenshot error message:`,t);break}let e=t;P.error(`Server reported an error capturing screenshot for request ${e.id}:`,e.message),q(e.id,Error(e.message));break}case`assetResult`:{P.debug(`Received assetResult:`,t);let e=t.url,n=j.get(e);if(!n||n.length===0){P.warn(`Received assetResult for unknown or already handled url: ${t.url}`);break}let r=n.shift();if(n.length===0?j.delete(e):j.set(e,n),clearTimeout(r.timeout),t.result===`success`){P.debug(`Asset result is success`),r.resolve();break}let i=typeof t.message==`string`&&t.message?t.message:`Asset processing failed: ${JSON.stringify(t)}`;P.debug(`Asset result is failure`,i),r.reject(Error(i));break}default:if(ie(t)){let e=J(t);e?q(t.id,Error(e)):K(t.id,t.payload??t);break}P.warn(`Received unexpected message type: ${t.type}`)}}),w.on(`error`,e=>{let t=e.message;k=t,P.debug(`WebSocket error:`,t),!U&&(w?.readyState===c.default.CONNECTING||w?.readyState===c.default.OPEN)&&H(e)}),w.on(`close`,()=>{R&&=(clearInterval(R),void 0);let e=!O&&!f(k??``)&&T!==`disconnected`;F(`disconnected`),P.debug(`Disconnected from server.`),I(`Connection closed`),e?ae():f(k??``)&&(P.error(`Closing connection due to non-retryable error: ${k}`),L(),F(`disconnected`),I(`Non-retryable error`),P.debug(`Non-retryable error. Closing connection.`))}),w.on(`open`,()=>{P.debug(`Connected to ${h}`),E=0,k=void 0,F(`connected`),R=setInterval(()=>{w&&w.readyState===c.default.OPEN&&w.ping()},3e4),U||(U=!0,V({screenshot:oe,getElementTree:se,findElement:ce,tap:le,setText:ue,pressKey:de,scrollScreen:fe,scrollElement:pe,openUrl:me,launchApp:he,terminateApp:ge,listApps:_e,watchApp:ve,playOnMicrophone:ye,pushFile:Q,pullFile:be,setCameraVideo:xe,clearCameraVideo:Se,adbShell:Ce,setWifiBandwidth:we,startRecording:Te,stopRecording:Ee,startAppLogCapture:De,stopAppLogCapture:Oe,startEventCapture:ke,stopEventCapture:Ae,streamAppLogCapture:je,streamEventCapture:Me,keepAlive:Ne,disconnect:Pe,startAdbTunnel:Le,startTunnel:Re,getTunnelStatus:ze,stopTunnel:Be,sendAsset:Ve,syncApp:He,getConnectionState:Fe,onConnectionStateChange:Ie}))})},oe=async()=>Y(`screenshot`,{}),se=async e=>{let t=await Y(`getElementTree`,e??{},3e4+(e?.waitForIdleTimeoutMs??0));return{xml:typeof t.xml==`string`?t.xml:``,nodes:Array.isArray(t.nodes)?t.nodes:[]}},ce=async(e,t=20)=>{let n=await Y(`findElement`,{selector:e,limit:t}),r=Array.isArray(n.elements)?n.elements:[];return{elements:r,count:typeof n.count==`number`?n.count:r.length}},le=async e=>{let t=await Y(`tap`,e);return{x:Number(t.x??0),y:Number(t.y??0)}},ue=async(e,t)=>{let n={text:t};e?.selector&&(n.selector=e.selector),typeof e?.x==`number`&&(n.x=e.x),typeof e?.y==`number`&&(n.y=e.y);let r=await Y(`setText`,n);return{textLength:Number(r.textLength??t.length)}},de=async(e,t)=>{let n={keyName:e,...t?{modifiers:t}:{}},r=await Y(`pressKey`,n);return{key:typeof r.key==`string`?r.key:String(e)}},fe=async(e,t=6)=>await Y(`scrollScreen`,{direction:e,amount:t}),pe=async(e,t,n=6)=>await Y(`scrollElement`,{...e,direction:t,amount:n}),me=async e=>{let t=await Y(`openUrl`,{url:e});return{url:typeof t.url==`string`?t.url:e}},Z=async(e,t,n)=>{let r=W(e);M.set(r,t);try{return{execId:r,result:await n(r)}}catch(e){throw M.delete(r),e}},he=async(e,t={})=>{let n=n=>{let r={packageName:e};return t.mode&&(r.mode=t.mode),n&&(r.execId=n),Y(`launchApp`,r,6e4)},r=t.onExit?(await Z(`exec`,t.onExit,n)).result:await n();return{packageName:typeof r.packageName==`string`?r.packageName:e}},ge=async e=>{await Y(`terminateApp`,{packageName:e})},_e=async()=>(await Y(`listApps`,{})).apps??[],ve=async(e,t)=>{let{execId:n}=await Z(`watch`,t,t=>Y(`watchApp`,{packageName:e,execId:t}));return{execId:n,stop:async()=>{M.delete(n),await Y(`unwatchApp`,{execId:n})}}},ye=async(e,t)=>{if(!e)throw Error(`path must be a non-empty string`);return Y(`playOnMicrophone`,{path:e,...t?.once===void 0?{}:{once:t.once}})},Q=async(t,r)=>{let i=r===void 0?`${e.apiUrl}/files`:`${e.apiUrl}/files?path=${encodeURIComponent(r)}`,a=m.createReadStream(t),o=await n.fetch(i,{method:`PUT`,headers:{"Content-Type":`application/octet-stream`,"Content-Length":m.statSync(t).size.toString(),Authorization:`Bearer ${e.token}`},body:a,duplex:`half`});if(!o.ok){let e=await o.text();throw P.debug(`Upload failed: ${o.status} ${e}`),Error(`Upload failed: ${o.status} ${e}`)}return(await o.json()).path},be=async(t,n)=>{let i=`${e.apiUrl}/files?path=${encodeURIComponent(t)}`;await r(i,e.token,n)},xe=async(e,t)=>{let n=await Q(e);await Y(`cameraControl`,{action:`setSource`,source:`video`,arg:n,loop:t?.loop??!0})},Se=async()=>{await Y(`cameraControl`,{action:`reset`})},Ce=async(e,t=[],n)=>{if(!e)throw Error(`command must be a non-empty string`);let r=re([e,...t]),i=n?.timeoutMs,a=(i??3e4)+15e3,o=await Y(`adbShell`,{command:r,...i===void 0?{}:{timeoutMs:i}},a),s=n?.encoding??`utf8`;return{stdout:Buffer.from(o.stdout??``,`base64`).toString(s),stderr:Buffer.from(o.stderr??``,`base64`).toString(s),exitCode:typeof o.exitCode==`number`?o.exitCode:-1,truncated:o.truncated===!0}},we=async e=>{let t={};if(e.downKbps!==void 0&&(G(`downKbps`,e.downKbps),t.downKbps=e.downKbps),e.upKbps!==void 0&&(G(`upKbps`,e.upKbps),t.upKbps=e.upKbps),t.downKbps===void 0&&t.upKbps===void 0)throw Error(`setWifiBandwidth requires downKbps, upKbps, or both`);await Y(`setWifiBandwidth`,t)},Te=async e=>{let t={...s(e?.persist)};if(e?.quality!==void 0){if(!Number.isInteger(e.quality)||e.quality<5||e.quality>10)throw Error(`quality must be one of: 5, 6, 7, 8, 9, 10`);t.quality=e.quality}await Y(`startRecording`,t)},Ee=async t=>{let n={};t.presignedUrl&&(n.upload={presignedUrl:t.presignedUrl}),await Y(`stopRecording`,n);let i=te(y);return t.localPath&&await r(i,e.token,t.localPath),i},De=async e=>{if(!e.bundleId)throw Error(`bundleId must be a non-empty string`);await Y(`startAppLogCapture`,{bundleId:e.bundleId,...s(e.persist)})},Oe=async()=>{await Y(`stopAppLogCapture`,{})},ke=async e=>{await Y(`startEventCapture`,{...s(e?.persist)})},Ae=async()=>{await Y(`stopEventCapture`,{})},je=t=>d({url:`${e.apiUrl}/session/applogs/events`,token:e.token,onEntry:t.onLine,onError:t.onError}),Me=t=>d({url:`${e.apiUrl}/session/events/events`,token:e.token,onEntry:t.onEvent,onError:t.onError}),Ne=()=>{!w||w.readyState!==c.default.OPEN||w.send(JSON.stringify({type:`keepAlive`,sessionId:B}))},Pe=()=>{O=!0,L(),F(`disconnected`),I(`Intentional disconnect`),P.debug(`Intentionally disconnected from WebSocket.`)},Fe=()=>T,Ie=e=>(N.add(e),()=>{N.delete(e)}),Le=async()=>{if(!e.adbUrl)throw Error(`adbUrl is required to start an ADB tunnel.`);let t=await i(e.adbUrl,e.token,`127.0.0.1`,0,{maxReconnectAttempts:x,reconnectDelay:S,maxReconnectDelay:C,logLevel:b});try{await new Promise((n,r)=>{p(e.adbPath??`adb`,[`connect`,`${t.address.address}:${t.address.port}`],e=>{if(e)return r(e);n()})}),P.debug(`ADB connected on ${t.address.address}`)}catch(e){throw t.close(),e}return t},$=()=>{if(!e.adbUrl)throw Error(`adbUrl is required to manage a destination tunnel.`);return e.adbUrl},Re=async n=>t(u($()),e.token,{selectors:n.selectors,inspection:{enabled:!0,captureBodies:!1,...n.inspection??{}},...n.onInspectionEvent?{onInspectionEvent:n.onInspectionEvent}:{},...n.onInspectionError?{onInspectionError:n.onInspectionError}:{},...n.window===void 0?{}:{window:n.window},logLevel:n.logLevel??b}),ze=async()=>l($(),e.token),Be=async t=>{await a($(),e.token,t)},Ve=async(e,t)=>{if(!w||w.readyState!==c.default.OPEN)return Promise.reject(Error(`WebSocket is not connected or connection is not open.`));let n={type:`asset`,url:e};return new Promise((r,i)=>{let a,o=setTimeout(()=>{let t=j.get(e);if(!t)return;let n=t.indexOf(a);n>=0&&(t.splice(n,1),i(Error(`Request asset timed out for url: ${e}`))),t.length===0?j.delete(e):j.set(e,t)},t??12e4);a={resolve:r,reject:e=>i(e),timeout:o};let s=j.get(e)??[];s.push(a),j.set(e,s),w.send(JSON.stringify(n),t=>{if(t){clearTimeout(o);let n=j.get(e)??[],r=n.indexOf(a);r>=0&&n.splice(r,1),n.length===0?j.delete(e):j.set(e,n),P.error(`Failed to send asset request:`,t),i(t)}})})},He=async(t,n)=>{let r=_.resolve(t);await ne(r);let i=`limsync-cache-android-${_.basename(r)}-${v.createHash(`sha1`).update(r).digest(`hex`).slice(0,8)}`,a=n?.basisCacheDir??_.join(g.tmpdir(),i),s=(e,t)=>{switch(e){case`debug`:P.debug(t);break;case`info`:P.info(t);break;case`warn`:P.warn(t);break;case`error`:P.error(t);break;default:P.info(t)}};return await m.promises.mkdir(a,{recursive:!0}),await ee(r,a,e.apiUrl,e.token,s,n?.onBasisDownloadProgress),await o(r,{apiUrl:e.apiUrl,token:e.token,udid:i,basisCacheDir:a,install:n?.install??!0,launchMode:n?.launchMode??`ForegroundIfRunning`,watch:n?.watch??!1,ignoreFn:()=>!1,log:s,compression:`identity`,...n?.onSyncComplete?{onSyncComplete:n.onSyncComplete}:{}})};X()})}export{U as n,q as t};
1
+ import{r as e}from"./rolldown-runtime.js";import{C as t,a as n,c as r,f as i,g as a,h as o,i as s,l as c,m as l,n as u,o as d,r as f,s as p,u as m}from"./log-stream.js";import{execFile as h}from"node:child_process";import{EventEmitter as g}from"events";import _ from"fs";import{Readable as v}from"stream";import ee from"os";import y from"path";import b from"crypto";const x=/^[0-9a-f]{64}$/i,S=/^[0-9a-f]{32}$/i;function C(e){return b.createHash(`sha256`).update(e).digest(`hex`).slice(0,32)}function w(e,t){let n=t*e.blockSize;return{offset:n,length:Math.min(e.blockSize,e.fileSize-n)}}async function T(e){return await new Promise((t,n)=>{let r=b.createHash(`sha256`),i=_.createReadStream(e);i.on(`data`,e=>r.update(e)),i.on(`error`,n),i.on(`end`,()=>t(r.digest(`hex`)))})}function E(e,t){if(!e||typeof e!=`object`)throw Error(`Invalid seed signature: expected an object`);let n=e;if(n.version!==1)throw Error(`Unsupported seed signature version: ${String(n.version)}`);if(!Number.isSafeInteger(n.blockSize)||n.blockSize<=0)throw Error(`Invalid seed signature blockSize`);if(!Number.isSafeInteger(n.fileSize)||n.fileSize<0)throw Error(`Invalid seed signature fileSize`);if(typeof n.sha256!=`string`||!x.test(n.sha256)||n.sha256.toLowerCase()!==t.toLowerCase())throw Error(`Seed signature sha256 does not match the requested seed`);if(!Array.isArray(n.blocks))throw Error(`Invalid seed signature blocks`);let r=Math.ceil(n.fileSize/n.blockSize);if(n.blocks.length!==r)throw Error(`Invalid seed signature block count: got ${n.blocks.length}, expected ${r}`);let i=n.blocks.map((e,t)=>{if(!e||!Number.isInteger(e.w)||e.w<0||e.w>4294967295||typeof e.s!=`string`||!S.test(e.s))throw Error(`Invalid seed signature block at index ${t}`);return{w:e.w,s:e.s.toLowerCase()}});return{version:n.version,blockSize:n.blockSize,fileSize:n.fileSize,sha256:n.sha256.toLowerCase(),blocks:i}}async function D(e,n,r){let i=await t.fetch(e,{method:`GET`,headers:{Authorization:`Bearer ${n}`}});if(!i.ok){let e=await i.text();throw Error(`Seed signature download failed: ${i.status} ${e}`)}return E(await i.json(),r)}async function O(e,t,n,r){let i=0;for(;i<n;){let{bytesRead:a}=await e.read(t,i,n-i,r+i);if(a<=0)throw Error(`Unexpected EOF at offset ${r+i}`);i+=a}}async function k(e,t,n,r,i){let a=n.blockSize,o=await _.promises.open(e.path,`r`);try{if(e.size<a||i.size===0)return;let s=Buffer.allocUnsafe(a);await O(o,s,a,0);let c=0,l=0;for(let e=0;e<a;e++){let t=s[e];c=c+t&65535,l=l+(a-e)*t&65535}let u=0,d=0,f,p=async t=>{f??=Buffer.allocUnsafe(a),await O(o,f,a,d);let s=C(f);for(let a of t)i.has(a)&&n.blocks[a].s===s&&(r.set(a,{sourcePath:e.path,sourceOffset:d}),i.delete(a))},m=t.get(l*65536+c);m?.some(e=>i.has(e))&&await p(m);let h=Buffer.allocUnsafe(1048576),g=a;for(;g<e.size&&i.size>0;){let n=Math.min(h.byteLength,e.size-g),{bytesRead:r}=await o.read(h,0,n,g);if(r<=0)break;for(let e=0;e<r&&i.size>0;e++){let n=s[u],r=h[e];s[u]=r,u++,u===a&&(u=0),c=c-n+r&65535,l=l-(a*n&65535)+c&65535,d++,m=t.get(l*65536+c),m?.some(e=>i.has(e))&&await p(m)}g+=r}}finally{await o.close()}}async function A(e){let t=[];for(let n of e){let e=await _.promises.stat(n).catch(()=>void 0);e?.isFile()&&t.push({path:n,size:e.size})}return t}async function j(e,t,n){for(let r of e){let e=await _.promises.open(r.path,`r`),i=Buffer.allocUnsafe(t.blockSize);try{for(let a=0;a<t.blocks.length;a++){if(n.has(a))continue;let o=w(t,a);o.offset+o.length>r.size||(await O(e,i,o.length,o.offset),C(i.subarray(0,o.length))===t.blocks[a].s&&n.set(a,{sourcePath:r.path,sourceOffset:o.offset}))}}finally{await e.close()}}}async function M(e,t,n){if(t.fileSize===0||t.fileSize%t.blockSize===0)return;let r=t.blocks.length-1;if(n.has(r))return;let i=w(t,r),a=t.blocks[r].s,o=Buffer.allocUnsafe(i.length);for(let t of e){if(t.size<i.length)continue;let e=t.size-i.length;if(e===i.offset)continue;let s=await _.promises.open(t.path,`r`);try{if(await O(s,o,i.length,e),C(o)===a){n.set(r,{sourcePath:t.path,sourceOffset:e});return}}finally{await s.close()}}}function N(e,t){let n=0;for(let r=0;r<e.blocks.length;r++)t.has(r)||(n+=w(e,r).length);return(e.blocks.length===0?1:t.size/e.blocks.length)>=.8&&n<=33554432}async function P(e,t,n){let r=Math.floor(t.fileSize/t.blockSize),i=new Set,a=new Map;for(let e=0;e<r;e++){if(n.has(e))continue;i.add(e);let r=t.blocks[e].w,o=a.get(r)??[];o.push(e),a.set(r,o)}for(let r of e){if(i.size===0)return;await k(r,a,t,n,i)}}async function F(e,t){let n=await A(e),r=new Map;return await j(n,t,r),await M(n,t,r),N(t,r)||await P(n,t,r),r}function I(e,t){let n=[],r;for(let i=0;i<=e.blocks.length;i++){let a=i<e.blocks.length&&!t.has(i);if(a&&r===void 0)r=i;else if(!a&&r!==void 0){let t=w(e,r),a=w(e,i-1);n.push({start:t.offset,end:a.offset+a.length-1}),r=void 0}}return n}async function L(e,t,n){let r=new Map;try{for(let[i,a]of n){let n=r.get(a.sourcePath);n||(n=await _.promises.open(a.sourcePath,`r`),r.set(a.sourcePath,n));let o=w(t,i),s=Buffer.allocUnsafe(o.length);await O(n,s,o.length,a.sourceOffset),await R(e,s,o.offset)}}finally{await Promise.all([...r.values()].map(e=>e.close()))}}async function R(e,t,n){let r=0;for(;r<t.byteLength;){let{bytesWritten:i}=await e.write(t,r,t.byteLength-r,n+r);if(i<=0)throw Error(`Unable to write reconstructed seed at offset ${n+r}`);r+=i}}async function z(e,n,r,i,a,o){let s=await t.fetch(e,{method:`GET`,headers:{Authorization:`Bearer ${n}`,Range:`bytes=${r.start}-${r.end}`}});if(s.status!==206||!s.body){let e=await s.text();throw Error(`Seed range download failed: ${s.status} ${e}`)}let c=`bytes ${r.start}-${r.end}/${i}`;if(s.headers.get(`content-range`)!==c)throw Error(`Invalid Content-Range for seed: ${s.headers.get(`content-range`)??`<missing>`}`);let l=r.end-r.start+1,u=0,d=v.fromWeb(s.body);for await(let e of d){let t=Buffer.isBuffer(e)?e:Buffer.from(e);if(u+t.byteLength>l)throw Error(`Seed range response exceeded the requested length`);await R(a,t,r.start+u),u+=t.byteLength,o(t.byteLength)}if(u!==l)throw Error(`Seed range response was truncated: got ${u}, expected ${l}`)}async function B(e){let t=e.expectedSha256.toLowerCase(),n=await D(e.signatureUrl,e.token,t),r=await F([...new Set(e.sourcePaths.map(e=>y.resolve(e)))],n),i=I(n,r),a=i.reduce((e,t)=>e+t.end-t.start+1,0),o=0;e.onProgress?.(0,a),await _.promises.mkdir(y.dirname(e.outputPath),{recursive:!0});let s=`${e.outputPath}.reconstruct-${process.pid}-${b.randomBytes(6).toString(`hex`)}`,c=await _.promises.open(s,`wx`),l=!1,u=!1;try{await c.truncate(n.fileSize),await L(c,n,r);for(let t of i)await z(e.seedUrl,e.token,t,n.fileSize,c,t=>{o+=t,e.onProgress?.(o,a)});await c.close(),l=!0;let d=await T(s);if(d!==t)throw Error(`Reconstructed seed SHA-256 mismatch: got ${d}, expected ${t}`);await _.promises.rm(e.outputPath,{force:!0}),await _.promises.rename(s,e.outputPath),u=!0}finally{l||await c.close().catch(()=>void 0),u||await _.promises.rm(s,{force:!0})}return{downloadedBytes:o,totalDownloadBytes:a,matchedBlocks:r.size}}function V(e){return`${e}/sync/state`}function H(e,t){return`${e}/sync/seeds/${encodeURIComponent(t)}`}async function U(e){return await new Promise((t,n)=>{let r=b.createHash(`sha256`),i=_.createReadStream(e);i.on(`data`,e=>r.update(e)),i.on(`error`,n),i.on(`end`,()=>t(r.digest(`hex`)))})}async function W(e,n){let r=await t.fetch(V(e),{method:`GET`,headers:{Authorization:`Bearer ${n}`}});if(!r.ok){let e=await r.text();throw Error(`Failed to fetch Android sync state: ${r.status} ${e}`)}return await r.json()}async function te(e,t,n,r,i,a){let o=y.basename(e),s=y.join(t,o),c=await W(n,r).catch(e=>{i(`debug`,`android sync state unavailable: ${e instanceof Error?e.message:String(e)}`)});if(!c)return;let l=new Set;for(let e of c.roots??[])for(let t of e.files??[])t.path===o&&typeof t.sha256==`string`&&l.add(t.sha256.toLowerCase());let u=[...c.seeds??[]].filter(e=>typeof e.sha256==`string`&&/^[0-9a-f]{64}$/i.test(e.sha256)).sort((e,t)=>(t.mtime??0)-(e.mtime??0));for(let e of u)l.add(e.sha256.toLowerCase());let d;if(_.existsSync(s)){let e=(await U(s)).toLowerCase();if(l.has(e))return;i(`debug`,`local basis ${e} unknown to instance; re-seeding basis cache`),d=s}let f=(await U(e)).toLowerCase();if(l.has(f)){await _.promises.mkdir(y.dirname(s),{recursive:!0}),await _.promises.copyFile(e,s),i(`debug`,`seeded Android basis cache from local APK already known to instance: ${f}`);return}let p=u[0];if(!p){d&&await _.promises.rm(d,{force:!0});return}let h=H(n,p.sha256);try{let t=await B({signatureUrl:`${h}.sig`,seedUrl:h,token:r,sourcePaths:d?[e,d]:[e],outputPath:s,expectedSha256:p.sha256,...a?{onProgress:a}:{}});i(`debug`,`reconstructed Android basis seed ${p.sha256}: matched=${t.matchedBlocks} downloaded=${t.downloadedBytes}`)}catch(e){i(`debug`,`basis seed reconstruction unavailable; downloading full seed: ${e instanceof Error?e.message:String(e)}`),a?.(0,p.size??0),await m(h,r,s,a),i(`debug`,`seeded Android basis cache from full instance seed: ${p.sha256}`)}}async function ne(e,n,i){let a=await t.fetch(r(e,`trusted-cas`).toString(),{method:`POST`,headers:{"Content-Type":`application/x-pem-file`,Authorization:`Bearer ${n}`},body:i});if(!a.ok){let e=(await a.text()).trim();throw Error(`Adding the CA certificate failed (${a.status}): ${e}`)}return await a.json()}var re=class extends g{constructor(e,t,n){super(),this.apiUrl=e,this.token=t,this.stopStream=null,this.runId=null,this.stopped=!1,this.exited=!1,this.exitPromise=new Promise(e=>{this.settleExit=e}),this.start(n)}on(e,t){return super.on(e,t)}once(e,t){return super.once(e,t)}off(e,t){return super.off(e,t)}wait(){return this.exitPromise}stop(){this.stopped||this.exited||(this.stopped=!0,this.deleteRun(this.runId),this.finish(-1))}deleteRun(e){e&&t.fetch(`${this.apiUrl}/logcat/${e}`,{method:`DELETE`,headers:{Authorization:`Bearer ${this.token}`}}).catch(()=>{})}finish(e){this.exited||(this.exited=!0,this.stopStream?.(),this.stopStream=null,this.settleExit(e),this.emit(`exit`,e))}fail(e){this.exited||(this.deleteRun(this.runId),this.emit(`error`,e),this.finish(-1))}async start(e){let n;try{let r=await t.fetch(`${this.apiUrl}/logcat`,{method:`POST`,headers:{Authorization:`Bearer ${this.token}`,"Content-Type":`application/json`},body:JSON.stringify({args:e})});if(!r.ok){let e=await r.text().catch(()=>``);throw Error(`logcat failed to start: HTTP ${r.status}${e?` ${e.trim()}`:``}`)}let i=await r.json();if(!i.id)throw Error(`logcat failed to start: server returned no run id`);n=i.id}catch(e){this.fail(e instanceof Error?e:Error(String(e)));return}if(this.stopped){this.deleteRun(n);return}this.runId=n,this.stopStream=u({url:`${this.apiUrl}/logcat/${n}/events`,token:this.token,onEntry:e=>{if(e.lines&&e.lines.length>0){this.emit(`lines`,e.lines);for(let t of e.lines)this.emit(`line`,t)}e.error&&this.emit(`error`,Error(e.error)),typeof e.exitCode==`number`&&this.finish(e.exitCode)},onError:e=>this.fail(e)})}},G=e({RecordingQuality:()=>J,createInstanceClient:()=>Y});function K(e){let t=new URL(e);return t.protocol=t.protocol===`https:`?`wss:`:`ws:`,t.search=``,t.hash=``,t.pathname=`${t.pathname.replace(/\/$/,``)}/ws`,t.toString().replace(/\/$/,``)}function ie(e){return`${e}/files?path=%2Fdata%2Flocal%2Ftmp%2Frecordings%2Fvideo_recording.mp4`}function q(e,t){if(!Number.isInteger(t)||t<0)throw Error(`${e} must be a non-negative integer Kbps value`)}async function ae(e){if(!(await _.promises.stat(e).catch(()=>null))?.isFile())throw Error(`APK file not found: ${e}`);let t=await _.promises.open(e,`r`);try{let n=Buffer.alloc(4),{bytesRead:r}=await t.read(n,0,4,0);if(r<4||n[0]!==80||n[1]!==75)throw Error(`File is not an APK/ZIP archive: ${e}`)}finally{await t.close()}}var J;(function(e){e[e.Q5=5]=`Q5`,e[e.Q6=6]=`Q6`,e[e.Q7=7]=`Q7`,e[e.Q8=8]=`Q8`,e[e.Q9=9]=`Q9`,e[e.Q10=10]=`Q10`})(J||={});function oe(e){return e.map(e=>`'${e.replace(/'/g,`'\\''`)}'`).join(` `)}async function Y(e){let r=`${K(e.apiUrl)}?token=${e.token}`,g=e.apiUrl,v=e.logLevel??`info`,x=e.maxReconnectAttempts??6,S=e.reconnectDelay??1e3,C=e.maxReconnectDelay??3e4,w,T=`connecting`,E=0,D,O=!1,k,A=new Map,j=new Map,M=new Map,N=new Set,P={debug:(...e)=>{v===`debug`&&console.log(`[Endpoint]`,...e)},info:(...e)=>{(v===`info`||v===`debug`)&&console.log(`[Endpoint]`,...e)},warn:(...e)=>{(v===`warn`||v===`info`||v===`debug`)&&console.warn(`[Endpoint]`,...e)},error:(...e)=>{v!==`none`&&console.error(`[Endpoint]`,...e)}},F=e=>{T!==e&&(T=e,P.debug(`Connection state changed to: ${e}`),N.forEach(t=>{try{t(e)}catch(e){P.error(`Error in connection state callback:`,e)}}))},I=e=>{A.forEach(t=>{clearTimeout(t.timeout),t.reject(Error(e))}),A.clear(),j.forEach(t=>{t.forEach(t=>{clearTimeout(t.timeout),t.reject(Error(e))})}),j.clear()},L=()=>{D&&=(clearTimeout(D),void 0),R&&=(clearInterval(R),void 0),w&&=(w.removeAllListeners(),(w.readyState===o.default.OPEN||w.readyState===o.default.CONNECTING)&&w.close(),void 0)},R,z=0,B=Math.random().toString(36).substring(2,15)+Math.random().toString(36).substring(2,15);return new Promise((V,H)=>{let U=!1,W=e=>(z+=1,`${e}-${Date.now()}-${z}`),G=(e,t)=>{let n=A.get(e);if(!n){P.debug(`Received response for unknown/already-settled request: ${e}`);return}clearTimeout(n.timeout),A.delete(e),n.resolve(t)},K=(e,t)=>{let n=A.get(e);if(!n){P.debug(`Received error for unknown/already-settled request: ${e}`);return}clearTimeout(n.timeout),A.delete(e),n.reject(t)},J=e=>{if(`message`in e&&typeof e.message==`string`)return e.message;if(`error`in e&&typeof e.error==`string`&&e.error)return e.error;if(`error`in e&&e.error&&typeof e.error==`object`){let t=e.error;return typeof t.message==`string`&&t.message?t.message:typeof t.code==`string`&&t.code?t.code:`Server returned ${String(e.type)} with an error payload but no error message/code`}},Y=e=>{if(!(`type`in e)||typeof e.type!=`string`)return!1;switch(e.type){case`screenshotResult`:case`getElementTreeResult`:case`findElementResult`:case`tapResult`:case`setTextResult`:case`pressKeyResult`:case`scrollScreenResult`:case`scrollElementResult`:case`openUrlResult`:case`launchAppResult`:case`terminateAppResult`:case`watchAppResult`:case`unwatchAppResult`:case`listAppsResult`:case`playOnMicrophoneResult`:case`cameraControlResult`:case`adbShellResult`:case`setWifiBandwidthResult`:case`startRecordingResult`:case`stopRecordingResult`:case`startAppLogCaptureResult`:case`stopAppLogCaptureResult`:case`startEventCaptureResult`:case`stopEventCaptureResult`:return`id`in e&&typeof e.id==`string`;default:return!1}},X=async(e,t,n=3e4)=>{if(!w||w.readyState!==o.default.OPEN)return Promise.reject(Error(`WebSocket is not connected or connection is not open.`));let r=W(`ts-client`),i=Object.keys(t).length>0?{type:e,id:r,...t,payload:t}:{type:e,id:r};return new Promise((t,a)=>{let o=setTimeout(()=>{A.has(r)&&(A.delete(r),a(Error(`Request ${e} timed out`)))},n);A.set(r,{resolve:e=>t(e),reject:e=>a(e),timeout:o}),w.send(JSON.stringify(i),e=>{e&&(clearTimeout(o),A.delete(r),a(e))})})},se=()=>{if(O){P.debug(`Skipping reconnection (intentional disconnect)`);return}if(i(k??``)){P.debug(`Skipping reconnection (non-retryable error)`);return}if(E>=x){P.error(`Max reconnection attempts (${x}) reached. Giving up.`,k?`Last error: ${k}`:``),F(`disconnected`);return}let e=Math.min(S*2**E,C);E++,P.debug(`Scheduling reconnection attempt ${E} in ${e}ms...`),F(`reconnecting`),D=setTimeout(()=>{P.debug(`Attempting to reconnect (attempt ${E})...`),Z()},e)},Z=()=>{L(),F(`connecting`);let e=t.getWebSocketAgent(r);w=new o.default(r,e?{agent:e}:{}),w.on(`message`,e=>{let t;try{t=JSON.parse(e.toString())}catch(t){P.error({data:e,error:t},`Failed to parse JSON message`);return}switch(t.type){case`screenshot`:{if(!(`dataUri`in t)||typeof t.dataUri!=`string`||!(`id`in t)){P.warn(`Received invalid screenshot message:`,t);break}let e=t;P.debug(`Received screenshot data URI for request ${e.id}.`),G(e.id,{dataUri:e.dataUri});break}case`appExit`:{let e=t,{execId:n,packageName:r,reason:i}=e;if(typeof n!=`string`||typeof r!=`string`||typeof i!=`string`){P.warn(`Received malformed appExit message:`,t);break}let a=M.get(n);if(!a){P.debug(`Received appExit for unknown or already handled execId: ${n}`);break}M.delete(n);let o=Array.isArray(e.logs)?e.logs.map(String):[],s={packageName:r,reason:i,...e.crash?{crash:e.crash}:{},...e.anr?{anr:e.anr}:{}};Promise.resolve().then(()=>a(o,s)).catch(e=>{P.error(`Error in onExit callback for execId ${n}:`,e)});break}case`screenshotResult`:{let e=t,n=J(e);if(n){K(e.id,Error(n));break}let r=typeof e.payload?.dataUri==`string`?e.payload.dataUri:``;if(!r){K(e.id,Error(`Received screenshotResult without payload.dataUri`));break}G(e.id,{dataUri:r});break}case`screenshotError`:{if(!(`message`in t)||!(`id`in t)){P.warn(`Received invalid screenshot error message:`,t);break}let e=t;P.error(`Server reported an error capturing screenshot for request ${e.id}:`,e.message),K(e.id,Error(e.message));break}case`assetResult`:{P.debug(`Received assetResult:`,t);let e=t.url,n=j.get(e);if(!n||n.length===0){P.warn(`Received assetResult for unknown or already handled url: ${t.url}`);break}let r=n.shift();if(n.length===0?j.delete(e):j.set(e,n),clearTimeout(r.timeout),t.result===`success`){P.debug(`Asset result is success`),r.resolve();break}let i=typeof t.message==`string`&&t.message?t.message:`Asset processing failed: ${JSON.stringify(t)}`;P.debug(`Asset result is failure`,i),r.reject(Error(i));break}default:if(Y(t)){let e=J(t);e?K(t.id,Error(e)):G(t.id,t.payload??t);break}P.warn(`Received unexpected message type: ${t.type}`)}}),w.on(`error`,e=>{let t=e.message;k=t,P.debug(`WebSocket error:`,t),!U&&(w?.readyState===o.default.CONNECTING||w?.readyState===o.default.OPEN)&&H(e)}),w.on(`close`,()=>{R&&=(clearInterval(R),void 0);let e=!O&&!i(k??``)&&T!==`disconnected`;F(`disconnected`),P.debug(`Disconnected from server.`),I(`Connection closed`),e?se():i(k??``)&&(P.error(`Closing connection due to non-retryable error: ${k}`),L(),F(`disconnected`),I(`Non-retryable error`),P.debug(`Non-retryable error. Closing connection.`))}),w.on(`open`,()=>{P.debug(`Connected to ${r}`),E=0,k=void 0,F(`connected`),R=setInterval(()=>{w&&w.readyState===o.default.OPEN&&w.ping()},3e4),U||(U=!0,V({screenshot:ce,getElementTree:le,findElement:ue,tap:de,setText:fe,pressKey:pe,scrollScreen:me,scrollElement:he,openUrl:ge,launchApp:_e,terminateApp:ve,listApps:ye,watchApp:be,playOnMicrophone:xe,pushFile:Se,pullFile:Ce,setCameraVideo:we,clearCameraVideo:Te,adbShell:Ee,logcat:De,setWifiBandwidth:Oe,startRecording:ke,stopRecording:Ae,startAppLogCapture:je,stopAppLogCapture:Me,startEventCapture:Ne,stopEventCapture:Pe,streamAppLogCapture:Fe,streamEventCapture:Ie,keepAlive:Le,disconnect:Re,startAdbTunnel:Ve,startTunnel:He,getTunnelStatus:Ue,stopTunnel:We,addCaCertificate:Ge,sendAsset:Ke,syncApp:qe,getConnectionState:ze,onConnectionStateChange:Be}))})},ce=async()=>X(`screenshot`,{}),le=async e=>{let t=await X(`getElementTree`,e??{},3e4+(e?.waitForIdleTimeoutMs??0));return{xml:typeof t.xml==`string`?t.xml:``,nodes:Array.isArray(t.nodes)?t.nodes:[]}},ue=async(e,t=20)=>{let n=await X(`findElement`,{selector:e,limit:t}),r=Array.isArray(n.elements)?n.elements:[];return{elements:r,count:typeof n.count==`number`?n.count:r.length}},de=async e=>{let t=await X(`tap`,e);return{x:Number(t.x??0),y:Number(t.y??0)}},fe=async(e,t)=>{let n={text:t};e?.selector&&(n.selector=e.selector),typeof e?.x==`number`&&(n.x=e.x),typeof e?.y==`number`&&(n.y=e.y);let r=await X(`setText`,n);return{textLength:Number(r.textLength??t.length)}},pe=async(e,t)=>{let n={keyName:e,...t?{modifiers:t}:{}},r=await X(`pressKey`,n);return{key:typeof r.key==`string`?r.key:String(e)}},me=async(e,t=6)=>await X(`scrollScreen`,{direction:e,amount:t}),he=async(e,t,n=6)=>await X(`scrollElement`,{...e,direction:t,amount:n}),ge=async e=>{let t=await X(`openUrl`,{url:e});return{url:typeof t.url==`string`?t.url:e}},Q=async(e,t,n)=>{let r=W(e);M.set(r,t);try{return{execId:r,result:await n(r)}}catch(e){throw M.delete(r),e}},_e=async(e,t={})=>{let n=n=>{let r={packageName:e};return t.mode&&(r.mode=t.mode),n&&(r.execId=n),X(`launchApp`,r,6e4)},r=t.onExit?(await Q(`exec`,t.onExit,n)).result:await n();return{packageName:typeof r.packageName==`string`?r.packageName:e}},ve=async e=>{await X(`terminateApp`,{packageName:e})},ye=async()=>(await X(`listApps`,{})).apps??[],be=async(e,t)=>{let{execId:n}=await Q(`watch`,t,t=>X(`watchApp`,{packageName:e,execId:t}));return{execId:n,stop:async()=>{M.delete(n),await X(`unwatchApp`,{execId:n})}}},xe=async(e,t)=>{if(!e)throw Error(`path must be a non-empty string`);return X(`playOnMicrophone`,{path:e,...t?.once===void 0?{}:{once:t.once}})},Se=async(n,r)=>{let i=r===void 0?`${e.apiUrl}/files`:`${e.apiUrl}/files?path=${encodeURIComponent(r)}`,a=_.createReadStream(n),o=await t.fetch(i,{method:`PUT`,headers:{"Content-Type":`application/octet-stream`,"Content-Length":_.statSync(n).size.toString(),Authorization:`Bearer ${e.token}`},body:a,duplex:`half`});if(!o.ok){let e=await o.text();throw P.debug(`Upload failed: ${o.status} ${e}`),Error(`Upload failed: ${o.status} ${e}`)}return(await o.json()).path},Ce=async(t,n)=>{let r=`${e.apiUrl}/files?path=${encodeURIComponent(t)}`;await m(r,e.token,n)},we=async(e,t)=>{let n=await Se(e);await X(`cameraControl`,{action:`setSource`,source:`video`,arg:n,loop:t?.loop??!0})},Te=async()=>{await X(`cameraControl`,{action:`reset`})},Ee=async(e,t=[],n)=>{if(!e)throw Error(`command must be a non-empty string`);let r=oe([e,...t]),i=n?.timeoutMs,a=(i??3e4)+15e3,o=await X(`adbShell`,{command:r,...i===void 0?{}:{timeoutMs:i}},a),s=n?.encoding??`utf8`;return{stdout:Buffer.from(o.stdout??``,`base64`).toString(s),stderr:Buffer.from(o.stderr??``,`base64`).toString(s),exitCode:typeof o.exitCode==`number`?o.exitCode:-1,truncated:o.truncated===!0}},De=(t=[])=>new re(e.apiUrl,e.token,t),Oe=async e=>{let t={};if(e.downKbps!==void 0&&(q(`downKbps`,e.downKbps),t.downKbps=e.downKbps),e.upKbps!==void 0&&(q(`upKbps`,e.upKbps),t.upKbps=e.upKbps),t.downKbps===void 0&&t.upKbps===void 0)throw Error(`setWifiBandwidth requires downKbps, upKbps, or both`);await X(`setWifiBandwidth`,t)},ke=async e=>{let t={...f(e?.persist)};if(e?.quality!==void 0){if(!Number.isInteger(e.quality)||e.quality<5||e.quality>10)throw Error(`quality must be one of: 5, 6, 7, 8, 9, 10`);t.quality=e.quality}await X(`startRecording`,t)},Ae=async t=>{let n={};t.presignedUrl&&(n.upload={presignedUrl:t.presignedUrl}),await X(`stopRecording`,n);let r=ie(g);return t.localPath&&await m(r,e.token,t.localPath),r},je=async e=>{if(!e.bundleId)throw Error(`bundleId must be a non-empty string`);await X(`startAppLogCapture`,{bundleId:e.bundleId,...f(e.persist)})},Me=async()=>{await X(`stopAppLogCapture`,{})},Ne=async e=>{await X(`startEventCapture`,{...f(e?.persist)})},Pe=async()=>{await X(`stopEventCapture`,{})},Fe=t=>u({url:`${e.apiUrl}/session/applogs/events`,token:e.token,onEntry:t.onLine,onError:t.onError}),Ie=t=>u({url:`${e.apiUrl}/session/events/events`,token:e.token,onEntry:t.onEvent,onError:t.onError}),Le=()=>{!w||w.readyState!==o.default.OPEN||w.send(JSON.stringify({type:`keepAlive`,sessionId:B}))},Re=()=>{O=!0,L(),F(`disconnected`),I(`Intentional disconnect`),P.debug(`Intentionally disconnected from WebSocket.`)},ze=()=>T,Be=e=>(N.add(e),()=>{N.delete(e)}),Ve=async()=>{if(!e.adbUrl)throw Error(`adbUrl is required to start an ADB tunnel.`);let t=await l(e.adbUrl,e.token,`127.0.0.1`,0,{maxReconnectAttempts:x,reconnectDelay:S,maxReconnectDelay:C,logLevel:v});try{await new Promise((n,r)=>{h(e.adbPath??`adb`,[`connect`,`${t.address.address}:${t.address.port}`],e=>{if(e)return r(e);n()})}),P.debug(`ADB connected on ${t.address.address}`)}catch(e){throw t.close(),e}return t},$=(t=`manage a destination tunnel`)=>{if(!e.adbUrl)throw Error(`adbUrl is required to ${t}.`);return e.adbUrl},He=async t=>p(c($()),e.token,d(t,v)),Ue=async()=>s($(),e.token),We=async t=>{await n($(),e.token,t)},Ge=t=>ne($(`add a CA certificate`),e.token,t),Ke=async(e,t)=>{if(!w||w.readyState!==o.default.OPEN)return Promise.reject(Error(`WebSocket is not connected or connection is not open.`));let n={type:`asset`,url:e};return new Promise((r,i)=>{let a,o=setTimeout(()=>{let t=j.get(e);if(!t)return;let n=t.indexOf(a);n>=0&&(t.splice(n,1),i(Error(`Request asset timed out for url: ${e}`))),t.length===0?j.delete(e):j.set(e,t)},t??12e4);a={resolve:r,reject:e=>i(e),timeout:o};let s=j.get(e)??[];s.push(a),j.set(e,s),w.send(JSON.stringify(n),t=>{if(t){clearTimeout(o);let n=j.get(e)??[],r=n.indexOf(a);r>=0&&n.splice(r,1),n.length===0?j.delete(e):j.set(e,n),P.error(`Failed to send asset request:`,t),i(t)}})})},qe=async(t,n)=>{let r=y.resolve(t);await ae(r);let i=`limsync-cache-android-${y.basename(r)}-${b.createHash(`sha1`).update(r).digest(`hex`).slice(0,8)}`,o=n?.basisCacheDir??y.join(ee.tmpdir(),i),s=(e,t)=>{switch(e){case`debug`:P.debug(t);break;case`info`:P.info(t);break;case`warn`:P.warn(t);break;case`error`:P.error(t);break;default:P.info(t)}};return await _.promises.mkdir(o,{recursive:!0}),await te(r,o,e.apiUrl,e.token,s,n?.onBasisDownloadProgress),await a(r,{apiUrl:e.apiUrl,token:e.token,udid:i,basisCacheDir:o,install:n?.install??!0,launchMode:n?.launchMode??`ForegroundIfRunning`,watch:n?.watch??!1,ignoreFn:()=>!1,log:s,compression:`identity`,...n?.onSyncComplete?{onSyncComplete:n.onSyncComplete}:{}})};Z()})}export{G as n,Y as t};
@@ -1 +1 @@
1
- async function e(e,n,r){try{await t(e,n,r)}catch(e){r.stderr(`${e instanceof Error?e.message:String(e)}\n`),await(await n.processExit()).exitAfterFlush(1)}}async function t(e,t,l){if(e.length===0)return await n(t,l);if(o(e))return await r(t,l);let u=c(e);if(u!==void 0)return await i(u,e,t,l);if(s(e))return await(await t.mcp()).runAgentDeviceMcpServer();await a(e,t)}async function n(e,t){t.stdout(`${(await e.help()).buildUsageText()}\n`),await(await e.processExit()).exitAfterFlush(1)}async function r(e,t){t.stdout(`${t.bundledVersion??(await e.version()).readVersion()}\n`)}async function i(e,t,n,r){let i=await n.help(),o=e===null?`${i.buildUsageText()}\n`:i.resolveHelpTargetUsageText(e);if(o===null)return await a(t,n);r.stdout(o)}async function a(e,t){await(await t.cli()).runCliProcess(e)}function o(e){return e.length===1&&(e[0]===`--version`||e[0]===`-V`)}function s(e){return e[0]===`mcp`&&!e.some(l)}function c(e){let[t,n]=e;if(e.length===1)return t===`help`||l(t)?null:void 0;if(e.length===2)return t===`help`?n:l(n)?t:void 0}function l(e){return e===`--help`||e===`-h`}e(process.argv.slice(2),{help:()=>import(`../cli-help.js`).then(e=>e.n),cli:()=>import(`../process-entry.js`),mcp:()=>import(`../server.js`),version:()=>import(`../version.js`).then(e=>e.t),processExit:()=>import(`../process-exit.js`)},{bundledVersion:`0.21.22`,stdout:e=>{process.stdout.write(e)},stderr:e=>{process.stderr.write(e)}}).catch(()=>process.exit(1));export{};
1
+ async function e(e,n,r){try{await t(e,n,r)}catch(e){r.stderr(`${e instanceof Error?e.message:String(e)}\n`),await(await n.processExit()).exitAfterFlush(1)}}async function t(e,t,l){if(e.length===0)return await n(t,l);if(o(e))return await r(t,l);let u=c(e);if(u!==void 0)return await i(u,e,t,l);if(s(e))return await(await t.mcp()).runAgentDeviceMcpServer();await a(e,t)}async function n(e,t){t.stdout(`${(await e.help()).buildUsageText()}\n`),await(await e.processExit()).exitAfterFlush(1)}async function r(e,t){t.stdout(`${t.bundledVersion??(await e.version()).readVersion()}\n`)}async function i(e,t,n,r){let i=await n.help(),o=e===null?`${i.buildUsageText()}\n`:i.resolveHelpTargetUsageText(e);if(o===null)return await a(t,n);r.stdout(o)}async function a(e,t){await(await t.cli()).runCliProcess(e)}function o(e){return e.length===1&&(e[0]===`--version`||e[0]===`-V`)}function s(e){return e[0]===`mcp`&&!e.some(l)}function c(e){let[t,n]=e;if(e.length===1)return t===`help`||l(t)?null:void 0;if(e.length===2)return t===`help`?n:l(n)?t:void 0}function l(e){return e===`--help`||e===`-h`}e(process.argv.slice(2),{help:()=>import(`../cli-help.js`).then(e=>e.n),cli:()=>import(`../process-entry.js`),mcp:()=>import(`../server.js`),version:()=>import(`../version.js`).then(e=>e.t),processExit:()=>import(`../process-exit.js`)},{bundledVersion:`0.21.23`,stdout:e=>{process.stdout.write(e)},stderr:e=>{process.stderr.write(e)}}).catch(()=>process.exit(1));export{};