agent-device 0.20.9 → 0.20.10

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 (140) hide show
  1. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.9.apk → agent-device-android-ime-helper-0.20.10.apk} +0 -0
  2. package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.10.apk.sha256 +1 -0
  3. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.9.manifest.json → agent-device-android-ime-helper-0.20.10.manifest.json} +4 -4
  4. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.9.apk → agent-device-android-snapshot-helper-0.20.10.apk} +0 -0
  5. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.10.apk.sha256 +1 -0
  6. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.9.manifest.json → agent-device-android-snapshot-helper-0.20.10.manifest.json} +6 -6
  7. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +6 -5
  8. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +4 -4
  9. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+FlatSnapshotFiltering.swift +94 -1
  10. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +22 -23
  11. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +3 -23
  12. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Navigation.swift +10 -11
  13. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+PrivateAXPresentation.swift +30 -12
  14. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollGesture.swift +8 -5
  15. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +133 -63
  16. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +13 -12
  17. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotPresentation.swift +183 -0
  18. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotPresentationTests.swift +0 -0
  19. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SystemModal.swift +20 -18
  20. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextInputCandidatePolicy.swift +19 -0
  21. package/dist/src/agent-device-client.js +2 -2
  22. package/dist/src/ai-sdk.d.ts +61 -0
  23. package/dist/src/ai-sdk.js +1 -0
  24. package/dist/src/android-adb.d.ts +1 -1
  25. package/dist/src/app-lifecycle.js +1 -1
  26. package/dist/src/app-log-reconnect.js +1 -1
  27. package/dist/src/app-log-runtime.js +3 -3
  28. package/dist/src/app-resolution.js +2 -2
  29. package/dist/src/apps.js +5 -5
  30. package/dist/src/audio-probe.js +1 -1
  31. package/dist/src/boot-diagnostics.js +2 -2
  32. package/dist/src/cli-config.js +1 -1
  33. package/dist/src/cli-help.js +30 -23
  34. package/dist/src/cli-runner.js +1 -1
  35. package/dist/src/cli.js +7 -7
  36. package/dist/src/client-metro.js +1 -1
  37. package/dist/src/client-types.d.ts +1582 -0
  38. package/dist/src/command-tools.js +2 -0
  39. package/dist/src/connection-runtime.js +1 -1
  40. package/dist/src/contracts.d.ts +1 -1
  41. package/dist/src/contracts.js +1 -1
  42. package/dist/src/daemon-shutdown-report.js +1 -1
  43. package/dist/src/daemon.js +1 -1
  44. package/dist/src/debug-symbols.js +1 -1
  45. package/dist/src/device-input-state.js +1 -1
  46. package/dist/src/dispatch.js +1 -1
  47. package/dist/src/find.js +1 -1
  48. package/dist/src/finders.js +1 -1
  49. package/dist/src/generic-settle.js +1 -1
  50. package/dist/src/generic.js +1 -1
  51. package/dist/src/helper-package-install.js +1 -1
  52. package/dist/src/helper.js +1 -1
  53. package/dist/src/ime-lifecycle.js +1 -1
  54. package/dist/src/ime-recovery-marker.js +1 -1
  55. package/dist/src/index.d.ts +2 -1578
  56. package/dist/src/index.js +1 -1
  57. package/dist/src/input-actions.js +1 -1
  58. package/dist/src/input-actions3.js +1 -1
  59. package/dist/src/install-source2.js +1 -1
  60. package/dist/src/interaction-common.js +1 -1
  61. package/dist/src/interaction-runtime.js +1 -1
  62. package/dist/src/interaction-snapshot.js +1 -1
  63. package/dist/src/interaction.js +1 -1
  64. package/dist/src/interaction2.js +1 -1
  65. package/dist/src/interactor.js +2 -2
  66. package/dist/src/interactor2.js +1 -1
  67. package/dist/src/interactors.js +1 -1
  68. package/dist/src/internal/bin.js +2 -2
  69. package/dist/src/internal/daemon.js +4 -4
  70. package/dist/src/internal/png-worker.js +1 -1
  71. package/dist/src/lease-context.js +1 -1
  72. package/dist/src/lease.js +1 -1
  73. package/dist/src/limrun.d.ts +10 -2
  74. package/dist/src/linux.js +1 -1
  75. package/dist/src/location-coordinates.js +1 -1
  76. package/dist/src/{screenshot-geometry.js → mobile-snapshot-semantics.js} +1 -1
  77. package/dist/src/perf.js +1 -1
  78. package/dist/src/platform-runtime-open-target.js +1 -1
  79. package/dist/src/platform-runtime-operation-host.js +4 -4
  80. package/dist/src/platform-runtime.js +1 -1
  81. package/dist/src/platform-runtime2.js +1 -1
  82. package/dist/src/png-resize.js +1 -1
  83. package/dist/src/provider.js +1 -1
  84. package/dist/src/proxy.js +1 -1
  85. package/dist/src/react-native.js +1 -1
  86. package/dist/src/record-runtime.js +1 -1
  87. package/dist/src/registry.js +27 -27
  88. package/dist/src/remote-config2.js +1 -1
  89. package/dist/src/replay.js +2 -2
  90. package/dist/src/reporting.js +5 -5
  91. package/dist/src/runner-client.js +1 -1
  92. package/dist/src/runner-disposal.js +1 -1
  93. package/dist/src/runner-sequence.js +1 -1
  94. package/dist/src/runtime.js +3 -3
  95. package/dist/src/runtime2.js +4 -4
  96. package/dist/src/runtime3.js +1 -1
  97. package/dist/src/runtime4.js +3 -3
  98. package/dist/src/runtime5.js +1 -1
  99. package/dist/src/runtime6.js +1 -1
  100. package/dist/src/runtime7.js +1 -1
  101. package/dist/src/runtime8.js +1 -1
  102. package/dist/src/runtime9.js +1 -1
  103. package/dist/src/screenshot-result.js +4 -4
  104. package/dist/src/screenshot.js +1 -1
  105. package/dist/src/script-source-bundle.js +16 -0
  106. package/dist/src/sdk-android-adb.d.ts +40 -40
  107. package/dist/src/sdk-android-adb.js +4 -4
  108. package/dist/src/sdk-batch-runner.js +3 -3
  109. package/dist/src/sdk-contracts.d.ts +122 -85
  110. package/dist/src/sdk-contracts.js +2 -2
  111. package/dist/src/sdk-finders.d.ts +1 -1
  112. package/dist/src/sdk-finders.js +1 -1
  113. package/dist/src/sdk-selectors.d.ts +89 -77
  114. package/dist/src/sdk-selectors.js +1 -1
  115. package/dist/src/selector-runtime.js +1 -1
  116. package/dist/src/selectors.js +1 -1
  117. package/dist/src/server.js +10 -3
  118. package/dist/src/session-target-evidence.js +1 -1
  119. package/dist/src/session2.js +7 -8
  120. package/dist/src/shared.js +1 -1
  121. package/dist/src/snapshot-runtime.js +1 -1
  122. package/dist/src/snapshot-scope.js +1 -0
  123. package/dist/src/snapshot.js +6 -6
  124. package/dist/src/snapshot2.js +1 -1
  125. package/dist/src/snapshot3.js +1 -1
  126. package/dist/src/src.js +1 -1
  127. package/dist/src/src2.js +1 -1
  128. package/dist/src/src3.js +1 -1
  129. package/dist/src/src4.js +1 -0
  130. package/dist/src/tool-provider2.js +1 -1
  131. package/dist/src/tool-provider3.js +1 -0
  132. package/dist/src/verified-file.js +1 -1
  133. package/dist/src/web.js +1 -1
  134. package/package.json +21 -8
  135. package/server.json +2 -2
  136. package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.9.apk.sha256 +0 -1
  137. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.9.apk.sha256 +0 -1
  138. package/dist/src/cancel.js +0 -1
  139. package/dist/src/prepare-kind.js +0 -15
  140. package/dist/src/selector-vocabulary.js +0 -1
@@ -1 +1 @@
1
- import{C as e}from"../sdk-contracts.js";import{a as t,i as n,n as r,r as i,t as a}from"../png-worker-contract.js";import{parentPort as o}from"node:worker_threads";function s(e){switch(e.kind){case`decode`:{let t=n(a(e.png),e.label);return{kind:`decode`,width:t.width,height:t.height,data:t.data}}case`encode`:{let n=new t.PNG({width:e.width,height:e.height});return n.data=a(e.data),{kind:`encode`,png:t.PNG.sync.write(n)}}case`rgb-difference`:return{kind:`rgb-difference`,...r(n(a(e.firstPng),e.label),n(a(e.secondPng),e.label))};case`diff-pixels`:return{kind:`diff-pixels`,...i(e)}}}function c(e){return e.buffer instanceof ArrayBuffer&&e.byteOffset===0&&e.byteLength===e.buffer.byteLength}function l(e){return u(e).filter(c).map(e=>e.buffer)}function u(e){switch(e.kind){case`decode`:return[e.data];case`encode`:return[e.png];case`rgb-difference`:return[];case`diff-pixels`:return[e.diffData,e.diffMask]}}const d=o;d&&d.on(`message`,t=>{let n;try{n={id:t.id,ok:!0,result:s(t)}}catch(r){n={id:t.id,ok:!1,error:e(r)}}d.postMessage(n,n.ok?l(n.result):[])});export{l as resultTransferList};
1
+ import{E as e}from"../sdk-contracts.js";import{a as t,i as n,n as r,r as i,t as a}from"../png-worker-contract.js";import{parentPort as o}from"node:worker_threads";function s(e){switch(e.kind){case`decode`:{let t=n(a(e.png),e.label);return{kind:`decode`,width:t.width,height:t.height,data:t.data}}case`encode`:{let n=new t.PNG({width:e.width,height:e.height});return n.data=a(e.data),{kind:`encode`,png:t.PNG.sync.write(n)}}case`rgb-difference`:return{kind:`rgb-difference`,...r(n(a(e.firstPng),e.label),n(a(e.secondPng),e.label))};case`diff-pixels`:return{kind:`diff-pixels`,...i(e)}}}function c(e){return e.buffer instanceof ArrayBuffer&&e.byteOffset===0&&e.byteLength===e.buffer.byteLength}function l(e){return u(e).filter(c).map(e=>e.buffer)}function u(e){switch(e.kind){case`decode`:return[e.data];case`encode`:return[e.png];case`rgb-difference`:return[];case`diff-pixels`:return[e.diffData,e.diffMask]}}const d=o;d&&d.on(`message`,t=>{let n;try{n={id:t.id,ok:!0,result:s(t)}}catch(r){n={id:t.id,ok:!1,error:e(r)}}d.postMessage(n,n.ok?l(n.result):[])});export{l as resultTransferList};
@@ -1 +1 @@
1
- import{Br as e}from"./sdk-batch-runner.js";import{qt as t}from"./prepare-kind.js";function n(e){return t(e)}function r(t,r){let i=n(t),a=i.leaseId??r?.leaseId,o=i.tenantId??r?.tenantId,s=i.runId??r?.runId;if(!(!o||!s||!a))return e({tenantId:o,runId:s,leaseId:a,leaseBackend:i.leaseBackend??r?.backend,leaseProvider:i.leaseProvider??r?.leaseProvider,deviceKey:i.deviceKey??r?.deviceKey,clientId:i.clientId??r?.clientId,expiresAt:r?.expiresAt})}function i(t,r){let i=n(t),a=r?.lease??r?.deviceLease??void 0;return e({tenantId:i.tenantId??a?.tenantId,runId:i.runId??a?.runId,leaseId:i.leaseId??a?.leaseId,leaseTtlMs:i.leaseTtlMs,leaseBackend:i.leaseBackend??a?.leaseBackend,leaseProvider:i.leaseProvider??a?.leaseProvider,deviceKey:i.deviceKey??a?.deviceKey,clientId:i.clientId??a?.clientId})}function a(t){let n=t.meta,r=e({leaseId:o(n?.leaseId),clientId:o(n?.clientId),tenantId:o(n?.tenantId),runId:o(n?.runId),leaseProvider:o(n?.leaseProvider),deviceKey:o(n?.deviceKey)});return Object.keys(r).length>0?r:void 0}function o(e){return typeof e==`string`&&e.trim().length>0?e.trim():void 0}export{a as i,n,i as r,r as t};
1
+ import{Jr as e}from"./sdk-batch-runner.js";import{Tn as t}from"./script-source-bundle.js";function n(e){return t(e)}function r(t,r){let i=n(t),a=i.leaseId??r?.leaseId,o=i.tenantId??r?.tenantId,s=i.runId??r?.runId;if(!(!o||!s||!a))return e({tenantId:o,runId:s,leaseId:a,leaseBackend:i.leaseBackend??r?.backend,leaseProvider:i.leaseProvider??r?.leaseProvider,deviceKey:i.deviceKey??r?.deviceKey,clientId:i.clientId??r?.clientId,expiresAt:r?.expiresAt})}function i(t,r){let i=n(t),a=r?.lease??r?.deviceLease??void 0;return e({tenantId:i.tenantId??a?.tenantId,runId:i.runId??a?.runId,leaseId:i.leaseId??a?.leaseId,leaseTtlMs:i.leaseTtlMs,leaseBackend:i.leaseBackend??a?.leaseBackend,leaseProvider:i.leaseProvider??a?.leaseProvider,deviceKey:i.deviceKey??a?.deviceKey,clientId:i.clientId??a?.clientId})}function a(t){let n=t.meta,r=e({leaseId:o(n?.leaseId),clientId:o(n?.clientId),tenantId:o(n?.tenantId),runId:o(n?.runId),leaseProvider:o(n?.leaseProvider),deviceKey:o(n?.deviceKey)});return Object.keys(r).length>0?r:void 0}function o(e){return typeof e==`string`&&e.trim().length>0?e.trim():void 0}export{a as i,n,i as r,r as t};
package/dist/src/lease.js CHANGED
@@ -1 +1 @@
1
- import{_ as e}from"./sdk-contracts.js";import{$t as t,Gt as n,Jt as r,Zt as i}from"./prepare-kind.js";import{n as a}from"./command-catalog.js";import{n as o,r as s}from"./lease-context.js";import{nn as c}from"./internal/daemon.js";async function l(e){let{req:n,sessionName:c,sessionStore:l,leaseRegistry:p,providerRuntimeIds:m,providerRuntimeRequiredIds:h,leaseLifecycleProvider:g,cloudArtifactProvider:_}=e,v=o(n);switch(n.command){case a.artifacts:return{ok:!0,data:await f(n,s(n,l.get(c)),_)};case`lease_allocate`:{d(v.leaseProvider,m,h);let e=p.allocateLease(r(v)),i;try{i=await g?.allocate?.(e,u(n))}catch(n){throw p.releaseLease(t({leaseId:e.leaseId,tenantId:e.tenantId,runId:e.runId,leaseBackend:e.backend,leaseProvider:e.leaseProvider,deviceKey:e.deviceKey,clientId:e.clientId})),n}return{ok:!0,data:{lease:e,...i?{provider:i}:{}}}}case`lease_heartbeat`:{let e=p.heartbeatLease(i(v)),t=await g?.heartbeat?.(e,u(n));return{ok:!0,data:{lease:e,...t?{provider:t}:{}}}}case`lease_release`:{let e=t(v),r=p.getLease(e),i=r?await g?.release?.(r,u(n)):void 0;return{ok:!0,data:{released:p.releaseLease(e).released,...i?{provider:i}:{}}}}default:return null}}function u(e){return{flags:e.flags,cwd:typeof e.meta?.cwd==`string`?e.meta.cwd:void 0}}function d(t,n,r){if(!(!t||n===void 0||r===void 0||!r.includes(t)||n.includes(t)))throw new e(`UNSUPPORTED_OPERATION`,`Provider "${t}" is not available in this daemon runtime.`,{provider:t,hint:`Restart the daemon with ${t} configured, then retry lease allocation.`})}async function f(e,t,n){let r=g(e.flags,`providerSessionId`);return p(t,r)?await m(t.tenantId):await h(t,r,n)}function p(e,t){return n(e)||!e.leaseProvider&&!t}async function m(e){let t=await c(e);return{source:`daemon`,status:`ready`,artifacts:t,...t.length===0?{message:`No daemon artifacts available.`}:{}}}async function h(t,n,r){if(!t.leaseProvider)throw new e(`INVALID_ARGS`,`artifacts requires --provider for provider session lookup or an active cloud connection.`);if(!t.leaseId&&!n)throw new e(`INVALID_ARGS`,`artifacts requires an active cloud lease or --provider-session <id>.`);let i=await r?.listCloudArtifacts?.({provider:t.leaseProvider,leaseId:t.leaseId,providerSessionId:n});if(!i)throw new e(`UNSUPPORTED_OPERATION`,`Cloud artifacts are not available for provider "${t.leaseProvider}".`);return i}function g(e,t){let n=e?.[t];return typeof n==`string`&&n.length>0?n:void 0}export{l as handleLeaseCommands};
1
+ import{_ as e,x as t,y as n}from"./sdk-contracts.js";import{Jt as r}from"./sdk-batch-runner.js";import{Cn as i,En as a,jn as o,kn as s}from"./script-source-bundle.js";import{n as c}from"./command-catalog.js";import{M as l,j as u}from"./runner-disposal.js";import{n as d,r as f}from"./lease-context.js";import{Ht as p}from"./internal/daemon.js";async function m(e){let{req:t,sessionName:n,sessionStore:i,leaseRegistry:p,providerRuntimeIds:m,providerRuntimeRequiredIds:v,leaseLifecycleProvider:y,cloudArtifactProvider:C}=e,w=d(t);switch(t.command){case c.artifacts:return{ok:!0,data:await S(t,f(t,i.get(n)),C)};case`lease_allocate`:{x(w.leaseProvider,m,v);let e=p.allocateLease(a(w)),n;try{n=await y?.allocate?.(e,{...b(t),signal:u(t.meta?.requestId),deadline:Date.now()+r})}catch(t){throw p.releaseLease(h(e)),t}if(l(t.meta?.requestId))throw await _(e,y,p);return{ok:!0,data:{lease:e,...n?{provider:n}:{}}}}case`lease_heartbeat`:{let e=p.heartbeatLease(s(w)),n=await y?.heartbeat?.(e,b(t));return{ok:!0,data:{lease:e,...n?{provider:n}:{}}}}case`lease_release`:{let e=o(w),n=await g(p,y,p.getLease(e),e,b(t));return{ok:!0,data:{released:n.registryReleased,...n.provider?{provider:n.provider}:{}}}}default:return null}}function h(e){return o({leaseId:e.leaseId,tenantId:e.tenantId,runId:e.runId,leaseBackend:e.backend,leaseProvider:e.leaseProvider,deviceKey:e.deviceKey,clientId:e.clientId})}async function g(e,t,n,r,i){let a=n?await t?.release?.(n,i):void 0;return{registryReleased:e.releaseLease(r).released,provider:a}}async function _(e,n,r){let i=h(e),a,o;try{a=await g(r,n,e,i)}catch(e){o=t(e),a={registryReleased:r.releaseLease(i).released}}return v(e,a,o)}function v(e,t,r){let i=t.provider?.providerSessionId,a=Array.isArray(t.provider?.warnings)?t.provider.warnings:[],o=t.registryReleased&&r===void 0&&a.length===0;return n({leaseId:e.leaseId,leaseProvider:e.leaseProvider,released:o,registryReleased:t.registryReleased,providerSessionId:i,...a.length>0?{warnings:a}:{},...r===void 0?{}:{releaseError:r},hint:y(o,e.leaseId,i)})}function y(e,t,n){return e?`The lease request was canceled while the provider was still allocating; the session it produced was released.`:`The lease request was canceled while the provider was still allocating, and the session it produced could NOT be confirmed released — it may still be running and billing. Stop provider session ${String(n??`(unknown)`)} for lease ${t} by hand.`}function b(e){return{flags:e.flags,cwd:typeof e.meta?.cwd==`string`?e.meta.cwd:void 0}}function x(t,n,r){if(!(!t||n===void 0||r===void 0||!r.includes(t)||n.includes(t)))throw new e(`UNSUPPORTED_OPERATION`,`Provider "${t}" is not available in this daemon runtime.`,{provider:t,hint:`Restart the daemon with ${t} configured, then retry lease allocation.`})}async function S(e,t,n){let r=E(e.flags,`providerSessionId`);return C(t,r)?await w(t.tenantId):await T(t,r,n)}function C(e,t){return i(e)||!e.leaseProvider&&!t}async function w(e){let t=await p(e);return{source:`daemon`,status:`ready`,artifacts:t,...t.length===0?{message:`No daemon artifacts available.`}:{}}}async function T(t,n,r){if(!t.leaseProvider)throw new e(`INVALID_ARGS`,`artifacts requires --provider for provider session lookup or an active cloud connection.`);if(!t.leaseId&&!n)throw new e(`INVALID_ARGS`,`artifacts requires an active cloud lease or --provider-session <id>.`);let i=await r?.listCloudArtifacts?.({provider:t.leaseProvider,leaseId:t.leaseId,providerSessionId:n});if(!i)throw new e(`UNSUPPORTED_OPERATION`,`Cloud artifacts are not available for provider "${t.leaseProvider}".`);return i}function E(e,t){let n=e?.[t];return typeof n==`string`&&n.length>0?n:void 0}export{m as handleLeaseCommands};
@@ -1,7 +1,7 @@
1
1
  import { B as DeviceTarget, H as PlatformSelector, R as DeviceInfo, f as LeaseBackend, z as DeviceKind } from "./sdk-contracts.js";
2
- import { r as AndroidAdbProvider } from "./sdk-android-adb.js";
3
- import { _ as Interactor, v as RunnerContext } from "./sdk-selectors.js";
4
2
  import { t as AppsFilter } from "./app-inventory.js";
3
+ import { v as Interactor, y as RunnerContext } from "./sdk-selectors.js";
4
+ import { r as AndroidAdbProvider } from "./sdk-android-adb.js";
5
5
  import { n as CloudArtifactProvider } from "./cloud-artifacts.js";
6
6
  import { n as AndroidKeyboardState, s as AndroidInputOwner, t as AndroidKeyboardDismissResult } from "./device-input-state.js";
7
7
  import Limrun from "@limrun/api";
@@ -44,6 +44,14 @@ type DeviceLease = {
44
44
  type LeaseLifecycleContext = {
45
45
  flags?: Readonly<Record<string, unknown>>;
46
46
  cwd?: string;
47
+ /** Request-bound cancellation (explicit cancel or client disconnect). */
48
+ signal?: AbortSignal;
49
+ /**
50
+ * Epoch-ms deadline by which `allocate` must have settled; derived from the
51
+ * same budget as the client's `lease_allocate` envelope, so a provider that
52
+ * fits its remote phases within it is never abandoned by a client first.
53
+ */
54
+ deadline?: number;
47
55
  };
48
56
  type LeaseLifecycleProvider = {
49
57
  allocate?: (lease: DeviceLease, context?: LeaseLifecycleContext) => Promise<Record<string, unknown> | undefined>;
package/dist/src/linux.js CHANGED
@@ -1 +1 @@
1
- import{_ as e}from"./sdk-contracts.js";import{b as t}from"./interaction.js";import{F as n}from"./sdk-android-adb.js";import{r,t as i}from"./snapshot2.js";import{doubleClickLinux as a,fillLinux as o,focusLinux as s,longPressLinux as c,pressLinux as l,scrollLinux as u,sendKey as d,swipeLinux as f,typeLinux as p}from"./input-actions3.js";async function m(e){await r().desktop.openTarget(e)}async function h(e){await r().desktop.closeApp(e)}async function g(){await d(`alt+Left`,[`56:1`,`105:1`,`105:0`,`56:0`])}async function _(){await d(`super+d`,[`125:1`,`32:1`,`32:0`,`125:0`])}async function v(){return await r().clipboard.readText()}async function y(e){await r().clipboard.writeText(e)}async function b(e,t){await r().screenshot.capture(e,t)}function x(){return{open:e=>m(e),openDevice:()=>Promise.resolve(),close:e=>h(e),tap:(e,t)=>l(e,t),doubleTap:(e,t)=>a(e,t),longPress:(e,t,n)=>c(e,t,n),focus:(e,t)=>s(e,t),type:(e,t)=>p(e,t),fill:(e,t,n,r)=>o(e,t,n,r),scroll:(e,t)=>u(e,t),performGesture:async n=>{if(n.topology===`two`)throw new e(`UNSUPPORTED_OPERATION`,`Multi-touch gestures are not supported on Linux`);let{start:r,end:i}=t(n);await f(r.x,r.y,i.x,i.y,n.durationMs)},screenshot:(e,t)=>b(e,t),snapshot:async e=>{let t=await n(`snapshot_capture`,async()=>await i(e?.surface,e?.signal),{backend:`linux-atspi`});return{nodes:t.nodes??[],truncated:t.truncated??!1,backend:`linux-atspi`}},back:()=>g(),home:()=>_(),setOrientation:()=>{throw new e(`UNSUPPORTED_OPERATION`,`orientation not supported on Linux`)},appSwitcher:()=>{throw new e(`UNSUPPORTED_OPERATION`,`appSwitcher not yet supported on Linux`)},tvRemote:()=>{throw new e(`UNSUPPORTED_OPERATION`,`tv-remote not supported on Linux`)},readClipboard:()=>v(),writeClipboard:e=>y(e),setSetting:()=>{throw new e(`UNSUPPORTED_OPERATION`,`setSetting not supported on Linux`)}}}export{x as createLinuxInteractor};
1
+ import{_ as e}from"./sdk-contracts.js";import{b as t}from"./interaction.js";import{F as n}from"./sdk-android-adb.js";import{i as r}from"./verified-file.js";import{t as i}from"./tool-provider2.js";import{doubleClickLinux as a,fillLinux as o,focusLinux as s,longPressLinux as c,pressLinux as l,scrollLinux as u,sendKey as d,swipeLinux as f,typeLinux as p}from"./input-actions3.js";async function m(e){await i().desktop.openTarget(e)}async function h(e){await i().desktop.closeApp(e)}async function g(){await d(`alt+Left`,[`56:1`,`105:1`,`105:0`,`56:0`])}async function _(){await d(`super+d`,[`125:1`,`32:1`,`32:0`,`125:0`])}async function v(){return await i().clipboard.readText()}async function y(e){await i().clipboard.writeText(e)}async function b(e,t){await i().screenshot.capture(e,t)}function x(){return{open:e=>m(e),openDevice:()=>Promise.resolve(),close:e=>h(e),tap:(e,t)=>l(e,t),doubleTap:(e,t)=>a(e,t),longPress:(e,t,n)=>c(e,t,n),focus:(e,t)=>s(e,t),type:(e,t)=>p(e,t),fill:(e,t,n,r)=>o(e,t,n,r),scroll:(e,t)=>u(e,t),performGesture:async n=>{if(n.topology===`two`)throw new e(`UNSUPPORTED_OPERATION`,`Multi-touch gestures are not supported on Linux`);let{start:r,end:i}=t(n);await f(r.x,r.y,i.x,i.y,n.durationMs)},screenshot:(e,t)=>b(e,t),snapshot:async e=>await n(`snapshot_capture`,async()=>await r(e,e?.signal),{backend:`linux-atspi`}),back:()=>g(),home:()=>_(),setOrientation:()=>{throw new e(`UNSUPPORTED_OPERATION`,`orientation not supported on Linux`)},appSwitcher:()=>{throw new e(`UNSUPPORTED_OPERATION`,`appSwitcher not yet supported on Linux`)},tvRemote:()=>{throw new e(`UNSUPPORTED_OPERATION`,`tv-remote not supported on Linux`)},readClipboard:()=>v(),writeClipboard:e=>y(e),setSetting:()=>{throw new e(`UNSUPPORTED_OPERATION`,`setSetting not supported on Linux`)}}}export{x as createLinuxInteractor};
@@ -1 +1 @@
1
- import{_ as e}from"./sdk-contracts.js";import{Vr as t}from"./sdk-batch-runner.js";const n={min:.01,max:1},r={flagKey:`screenshotMaxSize`,cliToken:`--max-size`,envVar:`AGENT_DEVICE_SCREENSHOT_MAX_SIZE`,publicOptionKey:`maxSize`,migration:{screenshot:`screenshot --max-size was removed; use --scale <0.01-1> (or AGENT_DEVICE_SCREENSHOT_SCALE) to downscale proportionally`,record:`record --max-size was removed; recordings capture at native resolution`}};function i(e,t){return t&&Object.hasOwn(t,r.flagKey)?r.migration[e]:void 0}function a(t,n){if(Object.hasOwn(n,r.publicOptionKey)||Object.hasOwn(n,r.flagKey))throw new e(`INVALID_ARGS`,r.migration[t])}const o=[`out`,`overlayRefs`,`screenshotPixelDensity`,`screenshotFullscreen`,`screenshotScale`,`screenshotNoStabilize`,`screenshotNormalizeStatusBar`],s=[`screenshotPixelDensity`,`screenshotFullscreen`,`screenshotScale`,`screenshotNoStabilize`,`screenshotNormalizeStatusBar`],c=[{key:`screenshotPixelDensity`,names:[`--pixel-density`],type:`int`,min:1,usageLabel:`--pixel-density <n>`,usageDescription:`Screenshot: output PNG pixel density in pixels per logical point (currently supported on iOS simulators)`},{key:`screenshotFullscreen`,names:[`--fullscreen`,`--full`,`-f`],type:`boolean`,usageLabel:`--fullscreen, --full, -f`,usageDescription:`Screenshot: on web capture the full page; on macOS app sessions capture the full desktop instead of the app window`},{key:`screenshotScale`,names:[`--scale`],type:`number`,min:n.min,max:n.max,usageLabel:`--scale <0.01-1>`,usageDescription:`Screenshot: resize both dimensions by this factor (or use AGENT_DEVICE_SCREENSHOT_SCALE)`},{key:`screenshotNoStabilize`,names:[`--no-stabilize`],type:`boolean`,usageLabel:`--no-stabilize`,usageDescription:`Screenshot: skip Android demo-mode/status-bar stabilization and settle delay for low-latency capture loops`},{key:`screenshotNormalizeStatusBar`,names:[`--normalize-status-bar`],type:`boolean`,usageLabel:`--normalize-status-bar`,usageDescription:`Screenshot: on iOS simulators temporarily normalize status-bar chrome for deterministic screenshot diffs`}],l=[{tokens:[`--fullscreen`,`--full`,`-f`],key:`screenshotFullscreen`},{tokens:[`--no-stabilize`],key:`screenshotNoStabilize`},{tokens:[`--normalize-status-bar`],key:`screenshotNormalizeStatusBar`}],ee=[{token:`--pixel-density`,key:`screenshotPixelDensity`,label:`screenshot --pixel-density`}],u=[{token:`--scale`,key:`screenshotScale`,label:`screenshot --scale`,min:n.min,max:n.max}];function d(e){return _({overlayRefs:e?.overlayRefs,pixelDensity:e?.screenshotPixelDensity,fullscreen:e?.screenshotFullscreen,scale:e?.screenshotScale,stabilize:e?.screenshotNoStabilize?!1:void 0,normalizeStatusBar:e?.screenshotNormalizeStatusBar})}function f(e={}){return _({overlayRefs:e.overlayRefs,screenshotPixelDensity:e.screenshotPixelDensity??e.pixelDensity,screenshotFullscreen:e.screenshotFullscreen??e.fullscreen,screenshotScale:e.screenshotScale,screenshotNoStabilize:e.screenshotNoStabilize??(e.stabilize===!1?!0:void 0),screenshotNormalizeStatusBar:e.screenshotNormalizeStatusBar??e.normalizeStatusBar})}function p(e={}){return f({...e,screenshotScale:e.screenshotScale??e.scale})}function m(t){let{min:r,max:i}=n;if(t.scale!==void 0&&(!Number.isFinite(t.scale)||t.scale<r||t.scale>i))throw new e(`INVALID_ARGS`,`screenshot scale must be between ${r} and ${i}`)}function h(e,t){typeof t?.screenshotPixelDensity==`number`&&e.push(`--pixel-density`,String(t.screenshotPixelDensity)),t?.screenshotFullscreen&&e.push(`--fullscreen`),typeof t?.screenshotScale==`number`&&e.push(`--scale`,String(t.screenshotScale)),t?.screenshotNoStabilize&&e.push(`--no-stabilize`),t?.screenshotNormalizeStatusBar&&e.push(`--normalize-status-bar`)}function g(t){let{args:n,flags:i,index:a}=t,o=n[a];if(o===r.cliToken)throw new e(`INVALID_ARGS`,r.migration.screenshot);return v(o,i,a)??y({args:n,index:a,flags:i,token:o})??b({args:n,index:a,flags:i,token:o})??{handled:!1}}function _(e){return Object.fromEntries(Object.entries(e).filter(e=>e[1]!==void 0))}function v(e,t,n){let r=l.find(t=>t.tokens.some(t=>t===e));if(r)return t[r.key]=!0,{handled:!0,nextIndex:n}}function y(t){let n=ee.find(e=>e.token===t.token);if(!n)return;let r=Number(t.args[t.index+1]);if(!Number.isInteger(r)||r<1)throw new e(`INVALID_ARGS`,`${n.label} requires a positive integer`);return t.flags[n.key]=r,{handled:!0,nextIndex:t.index+1}}function b(t){let n=u.find(e=>e.token===t.token);if(!n)return;let r=Number(t.args[t.index+1]);if(!Number.isFinite(r)||r<n.min||r>n.max)throw new e(`INVALID_ARGS`,`${n.label} requires a number from ${n.min} to ${n.max}`);return t.flags[n.key]=r,{handled:!0,nextIndex:t.index+1}}function x(e){let t=w(e.quality);return{...e.analysis?{analysis:e.analysis}:{},...e.androidSnapshot?{androidSnapshot:e.androidSnapshot}:{},...e.freshness?{freshness:e.freshness}:{},...t?{quality:t}:{},...e.warnings?{warnings:e.warnings}:{}}}function S(e){return{...e.androidSnapshot?{androidSnapshot:e.androidSnapshot}:{},...e.quality?{snapshotQuality:e.quality}:{},...e.warnings&&e.warnings.length>0?{warnings:e.warnings}:{}}}function C(e){let t=te(e.androidSnapshot),n=Array.isArray(e.warnings)?e.warnings.filter(e=>typeof e==`string`):void 0,r=w(e.snapshotQuality);return S({...t?{androidSnapshot:t}:{},...r?{quality:r}:{},...n?{warnings:n}:{}})}function w(e){if(!e||typeof e!=`object`)return;let t=e;return typeof t.state==`string`&&typeof t.backend==`string`?t:void 0}function te(e){return typeof e==`object`&&e?e:void 0}const T=1500;function E(e,t){e&&(e.snapshotDiagnostics??={samples:[]}).samples.push({...t,durationMs:Math.max(0,Math.round(t.durationMs))})}function D(e){let t=e?.snapshotDiagnostics?.samples;if(!(!t||t.length===0))return O(t)}function O(e){if(e.length===0)return;let t=e.slice(1),n=t.length>=3?j(t):void 0,r=t.filter(e=>e.durationMs>=T).length,i=n!==void 0&&n.p95Ms>=T&&r>=2;return{stats:j(e),...i&&n?{warning:F(n)}:{}}}function k(e){let t=e.filter(e=>e!==void 0),n=t.flatMap(e=>ne(e.stats));if(n.length===0)return;let r=j(n),i=t.filter(e=>e.warning);return{stats:r,...i.length>0?{warning:I({warnedCount:i.length,totalCount:t.length,worst:i.reduce((e,t)=>Math.max(e,t.stats.p95Ms),0),platform:r.platform})}:{}}}function A(e){if(!t(e))return;let n=L(e.stats);if(!n)return;let r=typeof e.warning==`string`?e.warning:void 0;return{stats:n,...r?{warning:r}:{}}}function j(e){let t=e.map(e=>e.durationMs).sort((e,t)=>e-t);return{count:t.length,p50Ms:M(t,50),p95Ms:M(t,95),maxMs:t[t.length-1]??0,slowThresholdMs:T,...N(e),...P(e)}}function M(e,t){if(e.length===0)return 0;let n=Math.max(0,Math.ceil(t/100*e.length)-1);return e[Math.min(n,e.length-1)]??0}function N(e){let t=e.map(e=>e.platform).filter(e=>!!e);return new Set(t).size===1?{platform:t[0]}:{}}function P(e){let t={};for(let n of e)n.backend&&(t[n.backend]=(t[n.backend]??0)+1);return Object.keys(t).length>0?{backends:t}:{}}function F(e){return`Warning: ${e.platform?`${e.platform} `:``}snapshots are slow in this run: p95 ${e.p95Ms}ms over ${e.count} captures. Possible causes: device load, app or dev server stuck, helper fallback, or stale daemon.`}function I(e){return`Warning: ${e.platform?`${e.platform} `:``}snapshots were slow in ${e.warnedCount} of ${e.totalCount} runs (worst run p95 ${e.worst}ms). Possible causes: device load, app or dev server stuck, helper fallback, or stale daemon.`}function L(e){if(!t(e))return;let n=R(e);if(n)return{...n,...B(e)}}function R(e){let t={count:e.count,p50Ms:e.p50Ms,p95Ms:e.p95Ms,maxMs:e.maxMs,slowThresholdMs:e.slowThresholdMs};if(!Object.values(t).some(e=>typeof e!=`number`))return t}function z(e){let t=Object.entries(e).filter(e=>typeof e[1]==`number`);return t.length>0?Object.fromEntries(t):void 0}function B(e){let n=typeof e.platform==`string`?e.platform:void 0,r=t(e.backends)?z(e.backends):void 0;return{...n?{platform:n}:{},...r?{backends:r}:{}}}function ne(e){if(!e||e.count<=0)return[];let t=e.platform;return e.count===1?[{durationMs:e.maxMs,platform:t}]:e.count===2?[{durationMs:e.p50Ms,platform:t},{durationMs:e.maxMs,platform:t}]:[...Array.from({length:e.count-3},()=>({durationMs:e.p50Ms,platform:t})),{durationMs:e.p50Ms,platform:t},{durationMs:e.p95Ms,platform:t},{durationMs:e.maxMs,platform:t}]}const V=[`camera`,`microphone`,`photos`,`contacts`,`contacts-limited`,`notifications`,`calendar`,`location`,`location-always`,`media-library`,`motion`,`reminders`,`siri`],H=`<wifi|airplane|location> <on|off>`,U=`location set <lat> <lon>`,W=`animations <on|off>`,G=`appearance <light|dark|toggle>`,K=`faceid <match|nonmatch|enroll|unenroll>`,q=`touchid <match|nonmatch|enroll|unenroll>`,J=`fingerprint <match|nonmatch>`,Y=`clear-app-state [app-id]`,X=`permission <grant|deny|reset> <camera|microphone|photos|contacts|contacts-limited|notifications|calendar|location|location-always|media-library|motion|reminders|siri> [full|limited]`,Z=`permission <grant|reset> <accessibility|screen-recording|input-monitoring>`,re=`macOS supports only settings ${G} and settings ${Z}. wifi|airplane|location|animations remain unsupported on macOS.`,ie=[`settings ${H}`,`settings ${U}`,`settings ${W}`,`settings ${G}`,`settings ${K}`,`settings ${q}`,`settings ${J}`,`settings ${Y}`,`settings ${X}`,`settings ${Z}`].join(` | `),ae=`settings requires ${H}, ${U}, ${W}, ${G}, ${K}, ${q}, ${J}, ${Y}, ${X}, or ${Z}`;function oe(e){let t=e.trim().toLowerCase();return t===`appearance`||t===`permission`}function se(e){return`Unsupported macOS setting: ${e}. ${re}`}function Q(t){let n=t.trim().toLowerCase();if(n===`grant`)return`grant`;if(n===`deny`)return`deny`;if(n===`reset`)return`reset`;throw new e(`INVALID_ARGS`,`Invalid permission action: ${t}. Use grant|deny|reset.`)}function ce(t){let n=t?.trim().toLowerCase();if(n===`camera`||n===`microphone`||n===`photos`||n===`contacts`||n===`contacts-limited`||n===`notifications`||n===`calendar`||n===`location`||n===`location-always`||n===`media-library`||n===`motion`||n===`reminders`||n===`siri`)return n;throw new e(`INVALID_ARGS`,`permission setting requires a target: ${V.join(`|`)}`)}function le(t,n){if(t===void 0||t.trim()===``)throw new e(`INVALID_ARGS`,`settings location set requires ${n}`);return $(Number(t),n)}function ue(e){return{latitude:$(e?.latitude,`latitude`),longitude:$(e?.longitude,`longitude`)}}function $(t,n){let r=n===`latitude`?-90:-180,i=n===`latitude`?90:180;if(typeof t!=`number`||!Number.isFinite(t)||t<r||t>i)throw new e(`INVALID_ARGS`,`${n} must be a number from ${r} to ${i}`);return t}export{g as C,d as D,p as E,a as O,h as S,f as T,r as _,se as a,n as b,ce as c,E as d,D as f,x as g,C as h,ie as i,m as k,k as l,S as m,ue as n,oe as o,O as p,ae as r,Q as s,le as t,A as u,s as v,i as w,c as x,o as y};
1
+ import{_ as e}from"./sdk-contracts.js";import{Yr as t}from"./sdk-batch-runner.js";const n={min:.01,max:1},r={flagKey:`screenshotMaxSize`,cliToken:`--max-size`,envVar:`AGENT_DEVICE_SCREENSHOT_MAX_SIZE`,publicOptionKey:`maxSize`,migration:{screenshot:`screenshot --max-size was removed; use --scale <0.01-1> (or AGENT_DEVICE_SCREENSHOT_SCALE) to downscale proportionally`,record:`record --max-size was removed; recordings capture at native resolution`}};function i(e,t){return t&&Object.hasOwn(t,r.flagKey)?r.migration[e]:void 0}function a(t,n){if(Object.hasOwn(n,r.publicOptionKey)||Object.hasOwn(n,r.flagKey))throw new e(`INVALID_ARGS`,r.migration[t])}const o=[`out`,`overlayRefs`,`screenshotPixelDensity`,`screenshotFullscreen`,`screenshotScale`,`screenshotNoStabilize`,`screenshotNormalizeStatusBar`],s=[`screenshotPixelDensity`,`screenshotFullscreen`,`screenshotScale`,`screenshotNoStabilize`,`screenshotNormalizeStatusBar`],c=[{key:`screenshotPixelDensity`,names:[`--pixel-density`],type:`int`,min:1,usageLabel:`--pixel-density <n>`,usageDescription:`Screenshot: output PNG pixel density in pixels per logical point (currently supported on iOS simulators)`},{key:`screenshotFullscreen`,names:[`--fullscreen`,`--full`,`-f`],type:`boolean`,usageLabel:`--fullscreen, --full, -f`,usageDescription:`Screenshot: on web capture the full page; on macOS app sessions capture the full desktop instead of the app window`},{key:`screenshotScale`,names:[`--scale`],type:`number`,min:n.min,max:n.max,usageLabel:`--scale <0.01-1>`,usageDescription:`Screenshot: resize both dimensions by this factor (or use AGENT_DEVICE_SCREENSHOT_SCALE)`},{key:`screenshotNoStabilize`,names:[`--no-stabilize`],type:`boolean`,usageLabel:`--no-stabilize`,usageDescription:`Screenshot: skip Android demo-mode/status-bar stabilization and settle delay for low-latency capture loops`},{key:`screenshotNormalizeStatusBar`,names:[`--normalize-status-bar`],type:`boolean`,usageLabel:`--normalize-status-bar`,usageDescription:`Screenshot: on iOS simulators temporarily normalize status-bar chrome for deterministic screenshot diffs`}],l=[{tokens:[`--fullscreen`,`--full`,`-f`],key:`screenshotFullscreen`},{tokens:[`--no-stabilize`],key:`screenshotNoStabilize`},{tokens:[`--normalize-status-bar`],key:`screenshotNormalizeStatusBar`}],ee=[{token:`--pixel-density`,key:`screenshotPixelDensity`,label:`screenshot --pixel-density`}],u=[{token:`--scale`,key:`screenshotScale`,label:`screenshot --scale`,min:n.min,max:n.max}];function d(e){return _({overlayRefs:e?.overlayRefs,pixelDensity:e?.screenshotPixelDensity,fullscreen:e?.screenshotFullscreen,scale:e?.screenshotScale,stabilize:e?.screenshotNoStabilize?!1:void 0,normalizeStatusBar:e?.screenshotNormalizeStatusBar})}function f(e={}){return _({overlayRefs:e.overlayRefs,screenshotPixelDensity:e.screenshotPixelDensity??e.pixelDensity,screenshotFullscreen:e.screenshotFullscreen??e.fullscreen,screenshotScale:e.screenshotScale,screenshotNoStabilize:e.screenshotNoStabilize??(e.stabilize===!1?!0:void 0),screenshotNormalizeStatusBar:e.screenshotNormalizeStatusBar??e.normalizeStatusBar})}function p(e={}){return f({...e,screenshotScale:e.screenshotScale??e.scale})}function m(t){let{min:r,max:i}=n;if(t.scale!==void 0&&(!Number.isFinite(t.scale)||t.scale<r||t.scale>i))throw new e(`INVALID_ARGS`,`screenshot scale must be between ${r} and ${i}`)}function h(e,t){typeof t?.screenshotPixelDensity==`number`&&e.push(`--pixel-density`,String(t.screenshotPixelDensity)),t?.screenshotFullscreen&&e.push(`--fullscreen`),typeof t?.screenshotScale==`number`&&e.push(`--scale`,String(t.screenshotScale)),t?.screenshotNoStabilize&&e.push(`--no-stabilize`),t?.screenshotNormalizeStatusBar&&e.push(`--normalize-status-bar`)}function g(t){let{args:n,flags:i,index:a}=t,o=n[a];if(o===r.cliToken)throw new e(`INVALID_ARGS`,r.migration.screenshot);return v(o,i,a)??y({args:n,index:a,flags:i,token:o})??b({args:n,index:a,flags:i,token:o})??{handled:!1}}function _(e){return Object.fromEntries(Object.entries(e).filter(e=>e[1]!==void 0))}function v(e,t,n){let r=l.find(t=>t.tokens.some(t=>t===e));if(r)return t[r.key]=!0,{handled:!0,nextIndex:n}}function y(t){let n=ee.find(e=>e.token===t.token);if(!n)return;let r=Number(t.args[t.index+1]);if(!Number.isInteger(r)||r<1)throw new e(`INVALID_ARGS`,`${n.label} requires a positive integer`);return t.flags[n.key]=r,{handled:!0,nextIndex:t.index+1}}function b(t){let n=u.find(e=>e.token===t.token);if(!n)return;let r=Number(t.args[t.index+1]);if(!Number.isFinite(r)||r<n.min||r>n.max)throw new e(`INVALID_ARGS`,`${n.label} requires a number from ${n.min} to ${n.max}`);return t.flags[n.key]=r,{handled:!0,nextIndex:t.index+1}}function x(e){let t=w(e.quality);return{...e.analysis?{analysis:e.analysis}:{},...e.androidSnapshot?{androidSnapshot:e.androidSnapshot}:{},...e.freshness?{freshness:e.freshness}:{},...t?{quality:t}:{},...e.warnings?{warnings:e.warnings}:{}}}function S(e){return{...e.androidSnapshot?{androidSnapshot:e.androidSnapshot}:{},...e.quality?{snapshotQuality:e.quality}:{},...e.warnings&&e.warnings.length>0?{warnings:e.warnings}:{}}}function C(e){let t=te(e.androidSnapshot),n=Array.isArray(e.warnings)?e.warnings.filter(e=>typeof e==`string`):void 0,r=w(e.snapshotQuality);return S({...t?{androidSnapshot:t}:{},...r?{quality:r}:{},...n?{warnings:n}:{}})}function w(e){if(!e||typeof e!=`object`)return;let t=e;return typeof t.state==`string`&&typeof t.backend==`string`?t:void 0}function te(e){return typeof e==`object`&&e?e:void 0}const T=1500;function E(e,t){e&&(e.snapshotDiagnostics??={samples:[]}).samples.push({...t,durationMs:Math.max(0,Math.round(t.durationMs))})}function D(e){let t=e?.snapshotDiagnostics?.samples;if(!(!t||t.length===0))return O(t)}function O(e){if(e.length===0)return;let t=e.slice(1),n=t.length>=3?j(t):void 0,r=t.filter(e=>e.durationMs>=T).length,i=n!==void 0&&n.p95Ms>=T&&r>=2;return{stats:j(e),...i&&n?{warning:F(n)}:{}}}function k(e){let t=e.filter(e=>e!==void 0),n=t.flatMap(e=>ne(e.stats));if(n.length===0)return;let r=j(n),i=t.filter(e=>e.warning);return{stats:r,...i.length>0?{warning:I({warnedCount:i.length,totalCount:t.length,worst:i.reduce((e,t)=>Math.max(e,t.stats.p95Ms),0),platform:r.platform})}:{}}}function A(e){if(!t(e))return;let n=L(e.stats);if(!n)return;let r=typeof e.warning==`string`?e.warning:void 0;return{stats:n,...r?{warning:r}:{}}}function j(e){let t=e.map(e=>e.durationMs).sort((e,t)=>e-t);return{count:t.length,p50Ms:M(t,50),p95Ms:M(t,95),maxMs:t[t.length-1]??0,slowThresholdMs:T,...N(e),...P(e)}}function M(e,t){if(e.length===0)return 0;let n=Math.max(0,Math.ceil(t/100*e.length)-1);return e[Math.min(n,e.length-1)]??0}function N(e){let t=e.map(e=>e.platform).filter(e=>!!e);return new Set(t).size===1?{platform:t[0]}:{}}function P(e){let t={};for(let n of e)n.backend&&(t[n.backend]=(t[n.backend]??0)+1);return Object.keys(t).length>0?{backends:t}:{}}function F(e){return`Warning: ${e.platform?`${e.platform} `:``}snapshots are slow in this run: p95 ${e.p95Ms}ms over ${e.count} captures. Possible causes: device load, app or dev server stuck, helper fallback, or stale daemon.`}function I(e){return`Warning: ${e.platform?`${e.platform} `:``}snapshots were slow in ${e.warnedCount} of ${e.totalCount} runs (worst run p95 ${e.worst}ms). Possible causes: device load, app or dev server stuck, helper fallback, or stale daemon.`}function L(e){if(!t(e))return;let n=R(e);if(n)return{...n,...B(e)}}function R(e){let t={count:e.count,p50Ms:e.p50Ms,p95Ms:e.p95Ms,maxMs:e.maxMs,slowThresholdMs:e.slowThresholdMs};if(!Object.values(t).some(e=>typeof e!=`number`))return t}function z(e){let t=Object.entries(e).filter(e=>typeof e[1]==`number`);return t.length>0?Object.fromEntries(t):void 0}function B(e){let n=typeof e.platform==`string`?e.platform:void 0,r=t(e.backends)?z(e.backends):void 0;return{...n?{platform:n}:{},...r?{backends:r}:{}}}function ne(e){if(!e||e.count<=0)return[];let t=e.platform;return e.count===1?[{durationMs:e.maxMs,platform:t}]:e.count===2?[{durationMs:e.p50Ms,platform:t},{durationMs:e.maxMs,platform:t}]:[...Array.from({length:e.count-3},()=>({durationMs:e.p50Ms,platform:t})),{durationMs:e.p50Ms,platform:t},{durationMs:e.p95Ms,platform:t},{durationMs:e.maxMs,platform:t}]}const V=[`camera`,`microphone`,`photos`,`contacts`,`contacts-limited`,`notifications`,`calendar`,`location`,`location-always`,`media-library`,`motion`,`reminders`,`siri`],H=`<wifi|airplane|location> <on|off>`,U=`location set <lat> <lon>`,W=`animations <on|off>`,G=`appearance <light|dark|toggle>`,K=`faceid <match|nonmatch|enroll|unenroll>`,q=`touchid <match|nonmatch|enroll|unenroll>`,J=`fingerprint <match|nonmatch>`,Y=`clear-app-state [app-id]`,X=`permission <grant|deny|reset> <camera|microphone|photos|contacts|contacts-limited|notifications|calendar|location|location-always|media-library|motion|reminders|siri> [full|limited]`,Z=`permission <grant|reset> <accessibility|screen-recording|input-monitoring>`,re=`macOS supports only settings ${G} and settings ${Z}. wifi|airplane|location|animations remain unsupported on macOS.`,ie=[`settings ${H}`,`settings ${U}`,`settings ${W}`,`settings ${G}`,`settings ${K}`,`settings ${q}`,`settings ${J}`,`settings ${Y}`,`settings ${X}`,`settings ${Z}`].join(` | `),ae=`settings requires ${H}, ${U}, ${W}, ${G}, ${K}, ${q}, ${J}, ${Y}, ${X}, or ${Z}`;function oe(e){let t=e.trim().toLowerCase();return t===`appearance`||t===`permission`}function se(e){return`Unsupported macOS setting: ${e}. ${re}`}function Q(t){let n=t.trim().toLowerCase();if(n===`grant`)return`grant`;if(n===`deny`)return`deny`;if(n===`reset`)return`reset`;throw new e(`INVALID_ARGS`,`Invalid permission action: ${t}. Use grant|deny|reset.`)}function ce(t){let n=t?.trim().toLowerCase();if(n===`camera`||n===`microphone`||n===`photos`||n===`contacts`||n===`contacts-limited`||n===`notifications`||n===`calendar`||n===`location`||n===`location-always`||n===`media-library`||n===`motion`||n===`reminders`||n===`siri`)return n;throw new e(`INVALID_ARGS`,`permission setting requires a target: ${V.join(`|`)}`)}function le(t,n){if(t===void 0||t.trim()===``)throw new e(`INVALID_ARGS`,`settings location set requires ${n}`);return $(Number(t),n)}function ue(e){return{latitude:$(e?.latitude,`latitude`),longitude:$(e?.longitude,`longitude`)}}function $(t,n){let r=n===`latitude`?-90:-180,i=n===`latitude`?90:180;if(typeof t!=`number`||!Number.isFinite(t)||t<r||t>i)throw new e(`INVALID_ARGS`,`${n} must be a number from ${r} to ${i}`);return t}export{g as C,d as D,p as E,a as O,h as S,f as T,r as _,se as a,n as b,ce as c,E as d,D as f,x as g,C as h,ie as i,m as k,k as l,S as m,ue as n,oe as o,O as p,ae as r,Q as s,le as t,A as u,s as v,i as w,c as x,o as y};
@@ -1 +1 @@
1
- import{Cr as e,ar as t,dr as n,fr as r,gr as i,ir as a,sr as o,ur as s}from"./sdk-batch-runner.js";function c(e){let t=e.trim().toLowerCase();return t?/^(vertical|horizontal)\s+scroll\s+bar(?:,?\s*\d+\s+pages?)?$/.test(t):!1}function l(e,t){if(!(e?.trim().toLowerCase()??``).includes(`vertical scroll bar`))return null;let n=u(t);return n===null?null:n<=1?{above:!1,below:!0}:n>=99?{above:!0,below:!1}:{above:!0,below:!0}}function u(e){if(!e)return null;let t=/^(\d{1,3})%$/.exec(e.trim());if(!t)return null;let n=Number(t[1]);return Number.isFinite(n)?Math.max(0,Math.min(100,n)):null}function d(e){if(e.length===0)return{nodes:e,hiddenCount:0,summaryLines:[]};let{byIndex:t,visibleNodeIndexes:n,offscreenNodes:r,hintedContainers:i}=p(e),a=n.size===0?e:e.filter(e=>n.has(e.index));return{nodes:a.map(e=>y(e,i.directionsByContainer)),hiddenCount:n.size===0?0:e.length-a.length,summaryLines:b(r.filter(e=>!i.coveredNodeIndexes.has(e.index)&&C(e)),e,t)}}function f(e){if(e.length===0)return new Map;let{hintedContainers:t}=p(e);return v(t.directionsByContainer)}function p(e){let n=i(e),r=new Set,a=[];for(let i of e){if(t(i,e,n)){T(i,r,n);continue}a.push(i)}return{byIndex:n,visibleNodeIndexes:r,offscreenNodes:a,hintedContainers:_(e,a,r,n)}}function m(e,t){return e.hittable&&o(e.rect,t)}function h(t,r,a=i(r)){if(!t.rect)return null;let c=s(t,r,a);if(c&&!e(t.rect,c)){let e=g(t.rect,c);if(e)return e}let l=n(r,t.rect);if(l&&!o(t.rect,l)){let e=g(t.rect,l);if(e)return e}return null}function g(e,t){let n=e.x+e.width/2,r=e.y+e.height/2,i=[{direction:`down`,amount:r-(t.y+t.height)},{direction:`up`,amount:t.y-r},{direction:`right`,amount:n-(t.x+t.width)},{direction:`left`,amount:t.x-n}],a=null;for(let e of i)e.amount>0&&(!a||e.amount>a.amount)&&(a=e);return a?.direction??null}function _(e,t,n,r){let i=new Map,a=new Map,o=new Set;for(let e of t){if(!e.rect)continue;let t=E(e,n,r);if(!t?.rect)continue;let s=S(e.rect,t.rect);if(!s)continue;let c=i.get(t.index)??new Set;c.add(s),i.set(t.index,c);let l=a.get(t.index)??new Set;l.add(s),a.set(t.index,l),o.add(e.index)}return D(e,n,r,i,a),{directionsByContainer:i,coveredNodeIndexes:o}}function v(e){let t=new Map;for(let[n,r]of e){let e={};r.has(`above`)&&(e.hiddenContentAbove=!0),r.has(`below`)&&(e.hiddenContentBelow=!0),(e.hiddenContentAbove||e.hiddenContentBelow)&&t.set(n,e)}return t}function y(e,t){let n=t.get(e.index);if(!n||n.size===0)return e;let r=e.hiddenContentAbove===!0||n.has(`above`)?!0:void 0,i=e.hiddenContentBelow===!0||n.has(`below`)?!0:void 0;return{...e,hiddenContentAbove:r,hiddenContentBelow:i}}function b(e,t,n){let r=new Map;for(let i of e){let e=x(i,t,n);if(!e)continue;let a=r.get(e)??[];a.push(i),r.set(e,a)}return[`above`,`below`].flatMap(e=>{let t=r.get(e);if(!t||t.length===0)return[];let n=w(t).slice(0,3).map(e=>`"${e}"`),i=t.length===1?`interactive item`:`interactive items`,a=n.length>0?`: ${n.join(`, `)}`:``;return[`[off-screen ${e}] ${t.length} ${i}${a}`]})}function x(e,t,n){if(!e.rect)return null;let r=s(e,t,n);return r?S(e.rect,r):null}function S(e,t){return e.y+e.height<=t.y?`above`:e.y>=t.y+t.height?`below`:null}function C(e){if(e.hittable===!0)return!0;let t=(e.type??``).toLowerCase();return t.includes(`button`)||t.includes(`link`)||t.includes(`textfield`)||t.includes(`edittext`)||t.includes(`searchfield`)||t.includes(`checkbox`)||t.includes(`radio`)||t.includes(`switch`)||t.includes(`menuitem`)||!!r(e)}function w(e){let t=new Set,n=[];for(let i of e){let e=r(i);!e||t.has(e)||(t.add(e),n.push(e))}return n}function T(e,t,n){let r=e,i=new Set;for(;r&&!i.has(r.index);)i.add(r.index),t.add(r.index),r=typeof r.parentIndex==`number`?n.get(r.parentIndex):void 0}function E(e,t,n){return a(e,n,e=>t.has(e.index))}function D(e,t,n,r,i){for(let a of e){let e=O(a);if(!e||e.size===0)continue;let o=E(a,t,n);if(!o)continue;let s=r.get(o.index)??new Set,c=i.get(o.index);for(let t of e)c&&c.size>0&&!c.has(t)||s.add(t);r.set(o.index,s)}}function O(e){let t=l(e.label,e.value);if(!t)return null;let n=new Set;return t.above&&n.add(`above`),t.below&&n.add(`below`),n.size>0?n:null}function k(e){return e}function A(e,t){let n=Math.max(e.x,t.x),r=Math.max(e.y,t.y),i=Math.min(e.x+e.width,t.x+t.width),a=Math.min(e.y+e.height,t.y+t.height);return i<=n||a<=r?0:(i-n)*(a-r)}export{f as a,c,h as i,k as n,m as o,d as r,l as s,A as t};
1
+ import{br as e,fr as t,hr as n,jr as r,pr as i,vr as a,wr as o,yr as s}from"./sdk-batch-runner.js";function c(e){let t=e.trim().toLowerCase();return t?/^(vertical|horizontal)\s+scroll\s+bar(?:,?\s*\d+\s+pages?)?$/.test(t):!1}function l(e,t){if(!(e?.trim().toLowerCase()??``).includes(`vertical scroll bar`))return null;let n=u(t);return n===null?null:n<=1?{above:!1,below:!0}:n>=99?{above:!0,below:!1}:{above:!0,below:!0}}function u(e){if(!e)return null;let t=/^(\d{1,3})%$/.exec(e.trim());if(!t)return null;let n=Number(t[1]);return Number.isFinite(n)?Math.max(0,Math.min(100,n)):null}function d(e){if(e.length===0)return{nodes:e,hiddenCount:0,summaryLines:[]};let{byIndex:t,visibleNodeIndexes:n,offscreenNodes:r,hintedContainers:i}=p(e),a=n.size===0?e:e.filter(e=>n.has(e.index));return{nodes:a.map(e=>y(e,i.directionsByContainer)),hiddenCount:n.size===0?0:e.length-a.length,summaryLines:b(r.filter(e=>!i.coveredNodeIndexes.has(e.index)&&C(e)),e,t)}}function f(e){if(e.length===0)return new Map;let{hintedContainers:t}=p(e);return v(t.directionsByContainer)}function p(e){let t=o(e),n=new Set,r=[];for(let a of e){if(i(a,e,t)){T(a,n,t);continue}r.push(a)}return{byIndex:t,visibleNodeIndexes:n,offscreenNodes:r,hintedContainers:_(e,r,n,t)}}function m(e,t){return e.hittable&&n(e.rect,t)}function h(e,t,i=o(t)){if(!e.rect)return null;let c=a(e,t,i);if(c&&!r(e.rect,c)){let t=g(e.rect,c);if(t)return t}let l=s(t,e.rect);if(l&&!n(e.rect,l)){let t=g(e.rect,l);if(t)return t}return null}function g(e,t){let n=e.x+e.width/2,r=e.y+e.height/2,i=[{direction:`down`,amount:r-(t.y+t.height)},{direction:`up`,amount:t.y-r},{direction:`right`,amount:n-(t.x+t.width)},{direction:`left`,amount:t.x-n}],a=null;for(let e of i)e.amount>0&&(!a||e.amount>a.amount)&&(a=e);return a?.direction??null}function _(e,t,n,r){let i=new Map,a=new Map,o=new Set;for(let e of t){if(!e.rect)continue;let t=E(e,n,r);if(!t?.rect)continue;let s=S(e.rect,t.rect);if(!s)continue;let c=i.get(t.index)??new Set;c.add(s),i.set(t.index,c);let l=a.get(t.index)??new Set;l.add(s),a.set(t.index,l),o.add(e.index)}return D(e,n,r,i,a),{directionsByContainer:i,coveredNodeIndexes:o}}function v(e){let t=new Map;for(let[n,r]of e){let e={};r.has(`above`)&&(e.hiddenContentAbove=!0),r.has(`below`)&&(e.hiddenContentBelow=!0),(e.hiddenContentAbove||e.hiddenContentBelow)&&t.set(n,e)}return t}function y(e,t){let n=t.get(e.index);if(!n||n.size===0)return e;let r=e.hiddenContentAbove===!0||n.has(`above`)?!0:void 0,i=e.hiddenContentBelow===!0||n.has(`below`)?!0:void 0;return{...e,hiddenContentAbove:r,hiddenContentBelow:i}}function b(e,t,n){let r=new Map;for(let i of e){let e=x(i,t,n);if(!e)continue;let a=r.get(e)??[];a.push(i),r.set(e,a)}return[`above`,`below`].flatMap(e=>{let t=r.get(e);if(!t||t.length===0)return[];let n=w(t).slice(0,3).map(e=>`"${e}"`),i=t.length===1?`interactive item`:`interactive items`,a=n.length>0?`: ${n.join(`, `)}`:``;return[`[off-screen ${e}] ${t.length} ${i}${a}`]})}function x(e,t,n){if(!e.rect)return null;let r=a(e,t,n);return r?S(e.rect,r):null}function S(e,t){return e.y+e.height<=t.y?`above`:e.y>=t.y+t.height?`below`:null}function C(t){if(t.hittable===!0)return!0;let n=(t.type??``).toLowerCase();return n.includes(`button`)||n.includes(`link`)||n.includes(`textfield`)||n.includes(`edittext`)||n.includes(`searchfield`)||n.includes(`checkbox`)||n.includes(`radio`)||n.includes(`switch`)||n.includes(`menuitem`)||!!e(t)}function w(t){let n=new Set,r=[];for(let i of t){let t=e(i);!t||n.has(t)||(n.add(t),r.push(t))}return r}function T(e,t,n){let r=e,i=new Set;for(;r&&!i.has(r.index);)i.add(r.index),t.add(r.index),r=typeof r.parentIndex==`number`?n.get(r.parentIndex):void 0}function E(e,n,r){return t(e,r,e=>n.has(e.index))}function D(e,t,n,r,i){for(let a of e){let e=O(a);if(!e||e.size===0)continue;let o=E(a,t,n);if(!o)continue;let s=r.get(o.index)??new Set,c=i.get(o.index);for(let t of e)c&&c.size>0&&!c.has(t)||s.add(t);r.set(o.index,s)}}function O(e){let t=l(e.label,e.value);if(!t)return null;let n=new Set;return t.above&&n.add(`above`),t.below&&n.add(`below`),n.size>0?n:null}export{l as a,m as i,h as n,c as o,f as r,d as t};
package/dist/src/perf.js CHANGED
@@ -1,4 +1,4 @@
1
- import{n as e}from"./rolldown-runtime.js";import{_ as t}from"./sdk-contracts.js";import{zr as n}from"./sdk-batch-runner.js";import{h as r,n as i,o as a}from"./sdk-android-adb.js";import{t as o}from"./timeouts.js";import s from"node:path";import{promises as c}from"node:fs";function l(e){return Math.round(e*10)/10}function u(e){return l(e)}function d(e){let t=e.replaceAll(`,`,``).match(/^-?\d+(?:\.\d+)?/);if(!t)return null;let n=Number(t[0]);return Number.isFinite(n)?n:null}function f(e){let t=ne(e.map(e=>e.intendedVsyncNs)),n=[];for(let e=1;e<t.length;e+=1){let r=t[e]-t[e-1];r>=4e6&&r<=5e7&&n.push(r)}if(n.length!==0)return re(n)}function p(e){let{frames:t,frameDeadlineNs:n,summaryDroppedFrameCount:r}=e;return r===void 0?n===void 0?[]:t.filter(e=>e.durationNs>n):r<=0?[]:[...t].sort((e,t)=>t.durationNs-e.durationNs).slice(0,r).sort((e,t)=>e.intendedVsyncNs-t.intendedVsyncNs)}function ee(e){let{frames:t,windowStartNs:n,measuredAtMs:r,uptimeMs:i}=e;if(t.length===0||n===void 0)return[];let a=[],o=[];for(let e of t){let t=o.at(-1);if(!t||e.intendedVsyncNs-t.frameCompletedNs<=5e8){o.push(e);continue}a.push(o),o=[e]}return o.length>0&&a.push(o),a.map(e=>te({frames:e,windowStartNs:n,measuredAtMs:r,uptimeMs:i})).sort((e,t)=>t.missedDeadlineFrameCount-e.missedDeadlineFrameCount||t.worstFrameMs-e.worstFrameMs).slice(0,3).sort((e,t)=>e.startOffsetMs-t.startOffsetMs)}function m(e){return Math.round(e*10)/10}function te(e){let{frames:t,windowStartNs:n,measuredAtMs:r,uptimeMs:i}=e,a=Math.min(...t.map(e=>e.intendedVsyncNs)),o=Math.max(...t.map(e=>e.frameCompletedNs)),s=Math.max(0,Math.round((a-n)/1e6)),c=Math.max(s,Math.round((o-n)/1e6)),l=i!==void 0&&Number.isFinite(r)?r-i:void 0;return{startOffsetMs:s,endOffsetMs:c,startAt:l===void 0?void 0:new Date(l+a/1e6).toISOString(),endAt:l===void 0?void 0:new Date(l+o/1e6).toISOString(),missedDeadlineFrameCount:t.length,worstFrameMs:m(Math.max(...t.map(e=>e.durationNs))/1e6)}}function ne(e){return[...new Set(e.filter(e=>Number.isFinite(e)))].sort((e,t)=>e-t)}function re(e){let t=[...e].sort((e,t)=>e-t),n=Math.floor(t.length/2);return t.length%2==1?t[n]:(t[n-1]+t[n])/2}const h=`adb-shell-dumpsys-gfxinfo-framestats`,g=`Rendered-frame health from the current adb shell dumpsys gfxinfo <package> framestats window. Dropped frames use Android gfxinfo janky-frame/frame-deadline data when available; this is not video recording FPS.`;function ie(e,t,n){_(e,t);let r=pe(e),i=ue(e),a=oe(i,r,t),o=Date.parse(n),s=he({frames:i,measuredAtMs:o,summary:r}),c=p({frames:i,frameDeadlineNs:a,summaryDroppedFrameCount:r?.droppedFrameCount}),l=r?.sampleWindowMs??s.sampleWindowMs??x(i),u=se(r,i,c),d=le({droppedFrames:c,timing:s,measuredAtMs:o,summary:r});return{...u,sampleWindowMs:l,...ce(a),windowStartedAt:s.windowStartedAt,windowEndedAt:s.windowEndedAt,timestampSource:s.timestampSource,measuredAt:n,method:h,source:r?`android-gfxinfo-summary`:`framestats-rows`,worstWindows:d&&d.length>0?d:void 0}}function _(e,n){if(/no process found for:/i.test(e))throw new t(`COMMAND_FAILED`,`Android gfxinfo did not find a running process for ${n}`,{metric:`fps`,package:n,hint:`Run open <app> for this session again to ensure the Android app is active, then retry perf after the interaction you want to inspect.`})}function ae(e){throw new t(`COMMAND_FAILED`,`Failed to parse Android framestats output for ${e}`,{metric:`fps`,package:e,hint:`Retry perf after exercising the app screen. If the problem persists, capture adb shell dumpsys gfxinfo <package> framestats output for debugging.`})}function oe(e,n,r){let i=f(e);if(!n&&e.length===0&&ae(r),n||i!==void 0)return i;throw new t(`COMMAND_FAILED`,`Failed to infer Android frame deadline from framestats output for ${r}`,{metric:`fps`,package:r,hint:`Retry perf after a longer interaction window so consecutive Android frame timestamps are available.`})}function se(e,t,n){let r=e?.totalFrameCount??t.length,i=e?.droppedFrameCount??n.length;return{totalFrameCount:r,droppedFrameCount:i,droppedFramePercent:e?.droppedFramePercent??(r>0?l(i/r*100):0)}}function ce(e){return{frameDeadlineMs:e===void 0?void 0:m(e/1e6),refreshRateHz:e===void 0?void 0:m(1e9/e)}}function le(e){let{droppedFrames:t,timing:n,measuredAtMs:r,summary:i}=e;if(t.length===0)return;let a=ee({frames:t,windowStartNs:n.windowStartNs,measuredAtMs:r,uptimeMs:i?.uptimeMs});return a.length>0?a:void 0}function ue(e){let t=[],n=null;for(let r of e.split(`
1
+ import{n as e}from"./rolldown-runtime.js";import{_ as t}from"./sdk-contracts.js";import{qr as n}from"./sdk-batch-runner.js";import{h as r,n as i,o as a}from"./sdk-android-adb.js";import{t as o}from"./timeouts.js";import s from"node:path";import{promises as c}from"node:fs";function l(e){return Math.round(e*10)/10}function u(e){return l(e)}function d(e){let t=e.replaceAll(`,`,``).match(/^-?\d+(?:\.\d+)?/);if(!t)return null;let n=Number(t[0]);return Number.isFinite(n)?n:null}function f(e){let t=ne(e.map(e=>e.intendedVsyncNs)),n=[];for(let e=1;e<t.length;e+=1){let r=t[e]-t[e-1];r>=4e6&&r<=5e7&&n.push(r)}if(n.length!==0)return re(n)}function p(e){let{frames:t,frameDeadlineNs:n,summaryDroppedFrameCount:r}=e;return r===void 0?n===void 0?[]:t.filter(e=>e.durationNs>n):r<=0?[]:[...t].sort((e,t)=>t.durationNs-e.durationNs).slice(0,r).sort((e,t)=>e.intendedVsyncNs-t.intendedVsyncNs)}function ee(e){let{frames:t,windowStartNs:n,measuredAtMs:r,uptimeMs:i}=e;if(t.length===0||n===void 0)return[];let a=[],o=[];for(let e of t){let t=o.at(-1);if(!t||e.intendedVsyncNs-t.frameCompletedNs<=5e8){o.push(e);continue}a.push(o),o=[e]}return o.length>0&&a.push(o),a.map(e=>te({frames:e,windowStartNs:n,measuredAtMs:r,uptimeMs:i})).sort((e,t)=>t.missedDeadlineFrameCount-e.missedDeadlineFrameCount||t.worstFrameMs-e.worstFrameMs).slice(0,3).sort((e,t)=>e.startOffsetMs-t.startOffsetMs)}function m(e){return Math.round(e*10)/10}function te(e){let{frames:t,windowStartNs:n,measuredAtMs:r,uptimeMs:i}=e,a=Math.min(...t.map(e=>e.intendedVsyncNs)),o=Math.max(...t.map(e=>e.frameCompletedNs)),s=Math.max(0,Math.round((a-n)/1e6)),c=Math.max(s,Math.round((o-n)/1e6)),l=i!==void 0&&Number.isFinite(r)?r-i:void 0;return{startOffsetMs:s,endOffsetMs:c,startAt:l===void 0?void 0:new Date(l+a/1e6).toISOString(),endAt:l===void 0?void 0:new Date(l+o/1e6).toISOString(),missedDeadlineFrameCount:t.length,worstFrameMs:m(Math.max(...t.map(e=>e.durationNs))/1e6)}}function ne(e){return[...new Set(e.filter(e=>Number.isFinite(e)))].sort((e,t)=>e-t)}function re(e){let t=[...e].sort((e,t)=>e-t),n=Math.floor(t.length/2);return t.length%2==1?t[n]:(t[n-1]+t[n])/2}const h=`adb-shell-dumpsys-gfxinfo-framestats`,g=`Rendered-frame health from the current adb shell dumpsys gfxinfo <package> framestats window. Dropped frames use Android gfxinfo janky-frame/frame-deadline data when available; this is not video recording FPS.`;function ie(e,t,n){_(e,t);let r=pe(e),i=ue(e),a=oe(i,r,t),o=Date.parse(n),s=he({frames:i,measuredAtMs:o,summary:r}),c=p({frames:i,frameDeadlineNs:a,summaryDroppedFrameCount:r?.droppedFrameCount}),l=r?.sampleWindowMs??s.sampleWindowMs??x(i),u=se(r,i,c),d=le({droppedFrames:c,timing:s,measuredAtMs:o,summary:r});return{...u,sampleWindowMs:l,...ce(a),windowStartedAt:s.windowStartedAt,windowEndedAt:s.windowEndedAt,timestampSource:s.timestampSource,measuredAt:n,method:h,source:r?`android-gfxinfo-summary`:`framestats-rows`,worstWindows:d&&d.length>0?d:void 0}}function _(e,n){if(/no process found for:/i.test(e))throw new t(`COMMAND_FAILED`,`Android gfxinfo did not find a running process for ${n}`,{metric:`fps`,package:n,hint:`Run open <app> for this session again to ensure the Android app is active, then retry perf after the interaction you want to inspect.`})}function ae(e){throw new t(`COMMAND_FAILED`,`Failed to parse Android framestats output for ${e}`,{metric:`fps`,package:e,hint:`Retry perf after exercising the app screen. If the problem persists, capture adb shell dumpsys gfxinfo <package> framestats output for debugging.`})}function oe(e,n,r){let i=f(e);if(!n&&e.length===0&&ae(r),n||i!==void 0)return i;throw new t(`COMMAND_FAILED`,`Failed to infer Android frame deadline from framestats output for ${r}`,{metric:`fps`,package:r,hint:`Retry perf after a longer interaction window so consecutive Android frame timestamps are available.`})}function se(e,t,n){let r=e?.totalFrameCount??t.length,i=e?.droppedFrameCount??n.length;return{totalFrameCount:r,droppedFrameCount:i,droppedFramePercent:e?.droppedFramePercent??(r>0?l(i/r*100):0)}}function ce(e){return{frameDeadlineMs:e===void 0?void 0:m(e/1e6),refreshRateHz:e===void 0?void 0:m(1e9/e)}}function le(e){let{droppedFrames:t,timing:n,measuredAtMs:r,summary:i}=e;if(t.length===0)return;let a=ee({frames:t,windowStartNs:n.windowStartNs,measuredAtMs:r,uptimeMs:i?.uptimeMs});return a.length>0?a:void 0}function ue(e){let t=[],n=null;for(let r of e.split(`
2
2
  `)){let e=r.trim();if(e.length===0||e===`---PROFILEDATA---`)continue;let i=e.split(`,`).map(e=>e.trim());if(de(i)){n=new Map(i.map((e,t)=>[e,t]));continue}let a=fe(i,n);a&&t.push(a)}return t.sort((e,t)=>e.intendedVsyncNs-t.intendedVsyncNs)}function de(e){return e.includes(`IntendedVsync`)&&e.includes(`FrameCompleted`)}function fe(e,t){if(!t||e.length<t.size)return;let n=v(e,t,`Flags`),r=v(e,t,`IntendedVsync`),i=v(e,t,`FrameCompleted`);if(!(n!==0||r===null||i===null||r<=0||i<=r))return{intendedVsyncNs:r,frameCompletedNs:i,durationNs:i-r}}function v(e,t,n){let r=t.get(n);if(r===void 0)return null;let i=Number(e[r]);return Number.isFinite(i)?i:null}function pe(e){let t=e.split(/\nProfile data in ms:\n/i)[0]??``,n=S(t,`Total frames rendered`),r=t.match(/^\s*Janky frames:\s*([0-9][0-9,]*)\s*\(([0-9.]+)%\)/im);if(n===void 0||!r)return;let i=r[1],a=r[2];if(i===void 0||a===void 0)return;let o=d(i)??void 0,s=Number(a);if(o===void 0||!Number.isFinite(s)||n<0)return;let c=S(t,`Uptime`),u=S(t,`Stats since`);return{droppedFramePercent:l(s),droppedFrameCount:o,totalFrameCount:n,sampleWindowMs:me({uptimeMs:c,statsSinceNs:u}),uptimeMs:c,statsSinceNs:u}}function me(e){let{uptimeMs:t,statsSinceNs:n}=e;if(t===void 0||n===void 0)return;let r=t-Math.round(n/1e6);return r>=0?r:void 0}function he(e){let{frames:t,measuredAtMs:n,summary:r}=e,i=y(t),a=r?.statsSinceNs,o=a??i.firstFrameNs,s=b(o,i.lastFrameNs),c=r?.sampleWindowMs??s;if(!Number.isFinite(n)||r?.uptimeMs===void 0||o===void 0)return{sampleWindowMs:c,windowStartNs:o};let l=n-r.uptimeMs;return{sampleWindowMs:c,windowStartNs:o,windowStartedAt:new Date(l+o/1e6).toISOString(),windowEndedAt:ge({deviceBootWallClockMs:l,measuredAtMs:n,summaryStartNs:a,lastFrameNs:i.lastFrameNs}),timestampSource:`estimated-from-device-uptime`}}function y(e){return e.length===0?{}:{firstFrameNs:Math.min(...e.map(e=>e.intendedVsyncNs)),lastFrameNs:Math.max(...e.map(e=>e.frameCompletedNs))}}function b(e,t){if(!(e===void 0||t===void 0))return Math.max(0,Math.round((t-e)/1e6))}function ge(e){let{deviceBootWallClockMs:t,measuredAtMs:n,summaryStartNs:r,lastFrameNs:i}=e;return r===void 0?i===void 0?void 0:new Date(t+i/1e6).toISOString():new Date(n).toISOString()}function x(e){if(e.length===0)return;let t=y(e);return b(t.firstFrameNs,t.lastFrameNs)}function S(e,t){let n=t.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`),r=e.match(RegExp(`^\\s*${n}:\\s*([0-9][0-9,]*)`,`im`));if(!r)return;let i=r[1];return i===void 0?void 0:d(i)??void 0}async function C(e,t,n={}){let r=a(e,n.adb);try{let i=ie((await r([`shell`,`dumpsys`,`gfxinfo`,t,`framestats`],{timeoutMs:15e3})).stdout,t,new Date().toISOString());return await w(e,t,n),i}catch(e){throw _e(t,e)}}async function w(e,t,n={}){let r=a(e,n.adb);try{await r([`shell`,`dumpsys`,`gfxinfo`,t,`reset`],{allowFailure:!0,timeoutMs:3e3})}catch{}}function _e(e,n){return n instanceof t?new t(n.code,n.message,{...n.details??{},metric:`fps`,package:e},n):new t(`COMMAND_FAILED`,`Failed to sample Android fps for ${e}`,{metric:`fps`,package:e},n)}function T(e,n,r,i){if(i instanceof t){let a=i.details??{};return new t(i.code,i.message,{...a,action:e,package:r,tool:n,hint:typeof a.hint==`string`?a.hint:ye(n,a)},i)}return new t(`COMMAND_FAILED`,`Failed to ${e} Android ${n} for ${r}`,{action:e,package:r,tool:n,hint:E(n)},i)}function E(e){return e===`simpleperf`?`Verify simpleperf is available, the app process is running, and the app/device permits native CPU profiling.`:`Verify perfetto is available, the app process is running, and the device permits trace capture.`}function ve(e){return e===`simpleperf`?`Use an emulator/system image with simpleperf available, or install the Android NDK simpleperf binary for this device.`:`Use Android 10+ or a system image that exposes the perfetto command-line binary.`}function ye(e,t){let n=(typeof t.stderr==`string`?t.stderr:``).toLowerCase();return e===`simpleperf`?be(n):Se(n)?`Use a device image that permits perfetto trace capture for shell, keep the app running, then retry perf trace start.`:E(e)}function be(e){return xe(e)?`Use a debuggable/profileable Android app or a device image that permits simpleperf for the target process, then retry perf cpu profile start.`:e.includes(`not supported`)||e.includes(`failed to open perf event`)?`This device image does not expose the requested simpleperf event for the app process. Try a different emulator/system image or a profileable app.`:E(`simpleperf`)}function xe(e){return e.includes(`permission denied`)||e.includes(`not profileable`)||e.includes(`profileable`)}function Se(e){return e.includes(`permission denied`)||e.includes(`not allowed`)}async function Ce(e,t,n,r,i){return{capture:{durationMs:r,packageName:t.packageName,appPid:t.appPid,artifactPath:t.outPath,sizeBytes:n},frameHealth:t.kind===`perfetto`?await we(e,t.packageName,i):void 0,notes:[t.kind===`perfetto`?`Frame health is sampled from Android gfxinfo around the trace window; open the Perfetto artifact for timeline root cause.`:`Open the Simpleperf report artifact for symbol-level CPU attribution.`]}}async function we(e,t,n){try{let r=await C(e,t,n);return{available:!0,droppedFramePercent:r.droppedFramePercent,droppedFrameCount:r.droppedFrameCount,totalFrameCount:r.totalFrameCount,method:r.method,worstWindows:r.worstWindows?.slice(0,3).map(e=>({startOffsetMs:e.startOffsetMs,endOffsetMs:e.endOffsetMs,missedDeadlineFrameCount:e.missedDeadlineFrameCount,worstFrameMs:e.worstFrameMs}))}}catch(e){return{available:!1,reason:e instanceof Error?e.message:`Android frame health was not available`}}}const D=`adb-shell-simpleperf`,O=`adb-shell-perfetto`,k=15e3,A=3e4,j=`/data/local/tmp`;async function M(e,t,n){let r=a(e,n.adb);await L(r,t),await R(r,t),await Oe(r,t);let i=await F(t.outPath);await P(r,t.remotePath);let o=Date.now(),s=Math.max(0,o-t.startedAt),c=await Ce(e,t,i,s,{adb:r});return{...t,action:`stop`,platform:`android`,state:`stopped`,stoppedAt:o,durationMs:s,sizeBytes:i,method:t.kind===`simpleperf`?D:O,artifact:{path:t.outPath,sizeBytes:i},summary:c,message:`Stopped Android ${t.kind} ${t.type} for ${t.packageName}`}}async function Te(e,t,n={}){let r=a(e,n.adb);try{t.state===`running`&&(await L(r,t),await R(r,t).catch(()=>{}))}finally{await P(r,t.remotePath)}}function N(e,t,n=j){return`${n}/agent-device-${e.replace(/[^A-Za-z0-9_.-]/g,`_`)}-${Date.now()}-${t}`}async function P(e,t){try{await e([`shell`,`rm -f ${I(t)}`],{allowFailure:!0,timeoutMs:k})}catch{}}async function Ee(e,t){await c.mkdir(s.dirname(e),{recursive:!0}),await c.writeFile(e,`${JSON.stringify(t,null,2)}\n`)}async function F(e){try{return(await c.stat(e)).size}catch(n){throw new t(`COMMAND_FAILED`,`Profiler artifact was not written: ${e}`,{outPath:e,hint:`Retry the profiling command and check daemon logs if the artifact path is still missing.`},n)}}function I(e){return`'${e.replace(/'/g,`'\\''`)}'`}async function L(e,t){try{await e([`shell`,De(t.profilerPid)],{timeoutMs:A})}catch(e){throw T(`stop`,t.kind,t.packageName,e)}}function De(e){return[`pid=${I(e)}`,`kill -INT "$pid" 2>/dev/null || true`,`for i in 1 2 3 4 5 6 7 8 9 10; do kill -0 "$pid" 2>/dev/null || exit 0; sleep 0.2; done`,`kill -TERM "$pid" 2>/dev/null || true`,`for i in 1 2 3 4 5 6 7 8 9 10; do kill -0 "$pid" 2>/dev/null || exit 0; sleep 0.2; done`,`echo "profiler process did not stop after SIGTERM" >&2`,`exit 1`].join(`; `)}async function Oe(e,n){await c.mkdir(s.dirname(n.outPath),{recursive:!0});try{await e([`pull`,n.remotePath,n.outPath],{timeoutMs:A})}catch(e){throw new t(`COMMAND_FAILED`,`Failed to pull Android ${n.kind} artifact for ${n.packageName}`,{package:n.packageName,tool:n.kind,remotePath:n.remotePath,outPath:n.outPath,hint:`Check that the profiling command ran long enough to create an artifact, then retry stop with the same session.`},e)}}async function R(e,n){let r;for(let t=0;t<12;t+=1){let t=await ke(e,n.remotePath);if(t!==void 0&&t>0&&t===r)return;r=t,await o(250)}throw new t(`COMMAND_FAILED`,`Android ${n.kind} artifact is not ready to pull`,{package:n.packageName,tool:n.kind,remotePath:n.remotePath,hint:`The profiler stopped, but the remote artifact was missing, empty, or still changing. Retry stop with the same session or inspect the device-side artifact.`})}async function ke(e,t){let n=I(t),r=await e([`shell`,`if [ -f ${n} ]; then stat -c %s ${n} 2>/dev/null || wc -c < ${n}; fi`],{allowFailure:!0,timeoutMs:k});if(r.exitCode!==0)return;let i=Number(r.stdout.trim().split(/\s+/)[0]);return Number.isFinite(i)?i:void 0}async function z(e,n){try{let t=await e([`shell`,`pidof`,n],{allowFailure:!0,timeoutMs:k}),r=V(t.stdout);if(t.exitCode===0&&r)return r}catch{}throw new t(`COMMAND_FAILED`,`No active Android app process found for ${n}`,{package:n,hint:`Run open <app> for this session again, wait for the app UI to appear, then retry perf.`})}async function B(e,n,r){let i=await e([`shell`,`command -v ${n} || which ${n}`],{allowFailure:!0,timeoutMs:k});if(!(i.exitCode===0&&i.stdout.trim()))throw new t(`UNSUPPORTED_OPERATION`,`Android device does not expose ${n}`,{package:r,tool:n,hint:ve(n)})}function V(e){return e.trim().split(/\s+/).find(e=>/^\d+$/.test(e))}async function H(e,t,n,r={}){let i=a(e,r.adb),o=await z(i,t);await B(i,`perfetto`,t);let s=N(t,`app.perfetto-trace`,`/data/misc/perfetto-traces`),c;try{await w(e,t,{adb:i}),c=await je(i,s,t)}catch(e){throw await P(i,s),e}return{type:`trace`,kind:`perfetto`,packageName:t,appPid:o,profilerPid:c,remotePath:s,outPath:n,startedAt:Date.now(),state:`running`,action:`start`,platform:`android`,method:O,message:`Started Android Perfetto trace for ${t}`}}async function Ae(e,t,n,r={}){return await M(e,{...t,outPath:n},r)}async function je(e,n,r){try{let i=V((await e([`shell`,`perfetto`,`--background-wait`,`-o`,n,`-t`,`3600s`,`sched`,`freq`,`idle`,`am`,`wm`,`gfx`,`view`,`binder_driver`,`hal`,`dalvik`],{timeoutMs:A})).stdout);if(i)return i;throw new t(`COMMAND_FAILED`,`Android perfetto did not return a profiler pid`,{package:r,tool:`perfetto`,hint:`Retry perf trace start. If perfetto exits immediately, verify the device permits trace capture.`})}catch(e){throw T(`start`,`perfetto`,r,e)}}function Me(e){let t=[];for(let r of n(e)){let e=r.match(/^([0-9]+(?:\.[0-9]+)?)%\s+(.+)$/);if(!e)continue;let n=Number(e[1]),i=e[2]?.trim();if(!Number.isFinite(n)||!i)continue;let a=i.split(/\s{2,}/).filter(Boolean);if(t.push({percentage:l(n),command:a[0],dso:a[1],symbol:a.slice(2).join(` `)||void 0}),t.length>=50)break}return t}async function Ne(e,t,n,r={}){let i=a(e,r.adb),o=await z(i,t);await B(i,`simpleperf`,t);let s=N(t,`cpu.perf.data`),c;try{c=await Ie(i,o,s,t)}catch(e){throw await P(i,s),e}return{type:`cpu-profile`,kind:`simpleperf`,packageName:t,appPid:o,profilerPid:c,remotePath:s,outPath:n,startedAt:Date.now(),state:`running`,action:`start`,platform:`android`,method:D,message:`Started Android Simpleperf CPU profile for ${t}`}}async function Pe(e,t,n,r={}){return await M(e,{...t,outPath:n},r)}async function Fe(e,t,n,r={}){let i=a(e,r.adb);await B(i,`simpleperf`,t.packageName);let o=await ze(i,t),s=new Date().toISOString(),c=Me(o.stdout),l=c.slice(0,10).map(e=>({symbol:e.symbol??`<unknown>`,binary:e.dso,selfSamplePercent:e.percentage}));await Ee(n,{kind:`simpleperf-report`,generatedAt:s,packageName:t.packageName,appPid:t.appPid,sourceProfilePath:t.outPath,sourceRemotePath:t.remotePath,entryCount:c.length,summary:{topFunctions:l},entries:c});let u=await F(n);return{action:`report`,platform:`android`,type:`cpu-profile-report`,kind:`simpleperf`,packageName:t.packageName,appPid:t.appPid,sourceProfilePath:t.outPath,outPath:n,sizeBytes:u,generatedAt:s,entryCount:c.length,summary:{topFunctions:l},method:D,message:`Wrote Android Simpleperf report for ${t.packageName}`}}async function Ie(e,n,r,i){try{let a=V((await e([`shell`,Le(n,r)],{timeoutMs:A})).stdout);if(a)return a;throw new t(`COMMAND_FAILED`,`Android simpleperf did not return a profiler pid`,{package:i,tool:`simpleperf`,hint:`Retry perf. If simpleperf exits immediately, verify the app is profileable and the device permits native profiling.`})}catch(e){throw T(`start`,`simpleperf`,i,e)}}function Le(e,t){return Re([`simpleperf`,`record`,`-e`,`cpu-clock:u`,`-p`,e,`-o`,t,`--duration`,`3600`],`simpleperf`)}function Re(e,t){let n=e.map(I).join(` `);return[`err=${I(`${j}/agent-device-${t}-${Date.now()}.err`)}`,`(${n}) >/dev/null 2>"$err" & pid=$!`,`sleep 1`,`if kill -0 "$pid" 2>/dev/null; then rm -f "$err"; echo "$pid"; exit 0; fi`,`cat "$err" >&2`,`rm -f "$err"`,`exit 1`].join(`; `)}async function ze(e,t){try{return await e([`shell`,`simpleperf`,`report`,`-i`,t.remotePath,`--stdio`,`--sort`,`comm,dso,symbol`],{timeoutMs:A})}catch(e){throw T(`report`,`simpleperf`,t.packageName,e)}}var Be=e({ANDROID_FRAME_SAMPLE_DESCRIPTION:()=>g,ANDROID_FRAME_SAMPLE_METHOD:()=>h,ANDROID_HPROF_SNAPSHOT_DESCRIPTION:()=>K,ANDROID_HPROF_SNAPSHOT_METHOD:()=>G,ANDROID_MEMORY_SAMPLE_DESCRIPTION:()=>W,ANDROID_MEMORY_SAMPLE_METHOD:()=>U,captureAndroidHeapSnapshot:()=>X,parseAndroidMemInfoSample:()=>Q,resetAndroidFramePerfStats:()=>w,sampleAndroidMemoryPerf:()=>Y});const U=`adb-shell-dumpsys-meminfo`,W=`Memory snapshot from adb shell dumpsys meminfo <package>. Values are reported in kilobytes.`,G=`adb-shell-am-dumpheap`,K=`Java heap dump captured with adb shell am dumpheap, pulled to a local artifact path.`,q=15e3,J=12e4;async function Y(e,t,n={}){let r=a(e,n.adb);try{return Q((await r([`shell`,`dumpsys`,`meminfo`,t],{timeoutMs:q})).stdout,t,new Date().toISOString())}catch(e){throw Ye(`memory`,t,e)}}async function X(e,n,o,l={}){let u=a(e,l.adb),d=await He(u,n),f=Ue(n);await c.mkdir(s.dirname(o),{recursive:!0});let p=await Ve(o);try{r(await u([`shell`,`am`,`dumpheap`,n,f],{allowFailure:!0,timeoutMs:J}),`Failed to capture Android heap dump for ${n}`,e=>({kind:`android-hprof`,package:n,pid:d,remotePath:f,hint:We(e.stdout,e.stderr)}));let e=await u([`pull`,f,o],{allowFailure:!0,timeoutMs:J});if(e.exitCode!==0)throw await Z(o,p),i(`Failed to pull Android heap dump for ${n}`,e,{kind:`android-hprof`,package:n,pid:d,remotePath:f,path:o,hint:`Verify the daemon can write the requested --out path and retry. The heap dump stays on-device only until cleanup runs.`});let a=await c.stat(o).catch(()=>null);if(!a?.isFile()||a.size<=0)throw await Z(o,p),new t(`COMMAND_FAILED`,`Android heap dump artifact is missing or empty`,{kind:`android-hprof`,package:n,pid:d,path:o,remotePath:f,hint:`Retry with a writable --out path. If the file is still empty, inspect adb pull output with --debug.`});return{available:!0,kind:`android-hprof`,path:o,sizeBytes:a.size,measuredAt:new Date().toISOString(),method:G,packageName:n,pid:d,remotePath:f}}finally{await u([`shell`,`rm`,`-f`,f],{allowFailure:!0,timeoutMs:q}).catch(()=>{})}}async function Ve(e){return await c.stat(e).then(e=>e.isFile()).catch(()=>!1)}async function Z(e,t){t||await c.rm(e,{force:!0}).catch(()=>{})}function Q(e,n,r){if(/no process found for:/i.test(e))throw new t(`COMMAND_FAILED`,`Android meminfo did not find a running process for ${n}`,{metric:`memory`,package:n,hint:`Run open <app> for this session again to ensure the Android app is active, then retry perf.`});let i=$(e,`TOTAL PSS`)??Xe(e);if(i===void 0)throw new t(`COMMAND_FAILED`,`Failed to parse Android meminfo output for ${n}`,{metric:`memory`,package:n,hint:`Retry perf after reopening the app session. If the problem persists, capture adb shell dumpsys meminfo output for debugging.`});return{totalPssKb:i,totalRssKb:$(e,`TOTAL RSS`),measuredAt:r,method:U,topConsumers:Ge(e)}}async function He(e,n){let r=await e([`shell`,`pidof`,n],{allowFailure:!0,timeoutMs:q}),i=r.stdout.trim().split(/\s+/).map(e=>Number(e)).find(e=>Number.isInteger(e)&&e>0);if(r.exitCode===0&&i!==void 0)return i;throw new t(`COMMAND_FAILED`,`No running Android process found for ${n}`,{kind:`android-hprof`,package:n,stdout:r.stdout,stderr:r.stderr,hint:`Run open <app> for this session again to ensure the Android app is active, then retry perf memory snapshot.`})}function Ue(e){return`/data/local/tmp/agent-device-${e.replace(/[^a-zA-Z0-9._-]/g,`_`)}-${Date.now()}.hprof`}function We(e,t){let n=`${e}\n${t}`.toLowerCase();return n.includes(`profileable`)||n.includes(`debuggable`)||n.includes(`not allowed`)?`Android heap dumps require a debuggable/profileable app process on many devices. Use a debug/profileable build, reopen the app, then retry.`:n.includes(`permission`)||n.includes(`denied`)?`The device denied heap dump access. Use a debug/profileable build or a device image that permits app heap dumping.`:`Reopen the app to refresh the process, then retry perf memory snapshot. If it still fails, run with --debug and inspect adb am dumpheap output.`}function Ge(e){let t=e.split(`
3
3
  `).flatMap(e=>Ke(e)??[]).sort((e,t)=>t.pssKb-e.pssKb).slice(0,5);return t.length>0?t:void 0}function Ke(e){let t=e.trim();if(qe(t))return;let n=t.match(/^(.+?)\s+([0-9][0-9,]*(?:\(\d+\))?)(?:\s|$)/);if(n)return Je(n[1],n[2])}function qe(e){if(!e||e.startsWith(`**`)||e.startsWith(`-`)||e.includes(`:`))return!0;let t=/^\S.+\s+\d/.test(e);return/^(pss|total|native|dalvik|unknown|app summary\b)/i.test(e)&&!t}function Je(e,t){let n=e?.trim(),r=t?d(t):null;if(!(!n||n===`TOTAL`||r===null||r<=0)&&!/^(pss|private|shared|heap|size|alloc|free)$/i.test(n))return{name:n,pssKb:r}}function Ye(e,n,r){return r instanceof t?new t(r.code,r.message,{...r.details??{},metric:e,package:n},r):new t(`COMMAND_FAILED`,`Failed to sample Android ${e} for ${n}`,{metric:e,package:n},r)}function $(e,t){let n=t.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`),r=e.match(RegExp(`${n}:\\s*([0-9][0-9,]*)`,`i`));if(!r)return;let i=r[1];return i===void 0?void 0:d(i)??void 0}function Xe(e){for(let t of e.split(`
4
4
  `)){let e=t.trim();if(!/^TOTAL\b(?!\s+PSS:)/.test(e))continue;let n=e.split(/\s+/).slice(1).find(e=>d(e)!==null);return n?d(n)??void 0:void 0}}export{u as _,X as a,Ne as c,H as d,Ae as f,h as g,g as h,U as i,Pe as l,C as m,G as n,Be as o,Te as p,W as r,Y as s,K as t,Fe as u,l as v};
@@ -1 +1 @@
1
- import{n as e}from"./rolldown-runtime.js";import{_ as t}from"./sdk-contracts.js";import{J as n,K as r,q as i}from"./sdk-batch-runner.js";import{l as a,s as o}from"./sdk-device.js";import{n as s}from"./session.js";var c=e({inferAndroidPackageAfterOpen:()=>x,resolveAndroidPackageForOpen:()=>b,resolveRequestedOpenSurface:()=>d,resolveSessionAppBundleIdForTarget:()=>w,resolveSoleForegroundIosApp:()=>u,validateOpenRelaunchTarget:()=>g});const l=new Set([`app`,`desktop`,`frontmost-app`]);async function u(e={}){let{listLocalDeviceInventory:t,shouldPropagateDeviceInventoryProbeError:n}=await import(`./verified-file.js`).then(e=>e.i);try{let n=await t({platform:`ios`,iosSimulatorSetPath:e.simulatorSetPath,kind:`simulator`,booted:!0});if(n.length!==1)return;let[r]=n;if(!r)return;let{detectSoleRunningIosSimulatorApp:i}=await import(`./app-resolution.js`).then(e=>e.t),a=await i(r);return a?{device:r,app:a}:void 0}catch(e){if(n(e))throw e;return}}function d(e){let{device:t,surfaceFlag:n,openTarget:r,existingSurface:i}=e;return t.platform===`linux`?f(n,r,i):a(t)?p(n,r,i):m(n)}function f(e,n,r){if(!e)return r??`app`;let i=s(e);if(!l.has(i))throw new t(`INVALID_ARGS`,`Linux supports --surface app, desktop, and frontmost-app (got "${e}")`);return h(i,n),i}function p(e,t,n){if(!e)return n??`app`;let r=s(e);return r!==`app`&&r!==`menubar`&&h(r,t),r}function m(e){if(e)throw new t(`INVALID_ARGS`,`surface is only supported on macOS and Linux`);return`app`}function h(e,n){if(e!==`app`&&e!==`menubar`&&n)throw new t(`INVALID_ARGS`,`open --surface ${e} does not accept an app target`)}async function g(e){let{target:t,platform:n,surface:i}=e;if(t&&r(t))return`open --relaunch does not support URL targets.`;if(i!==void 0&&i!==`app`)return`open --relaunch is supported only for app surfaces.`;if(n===`android`&&t){let{classifyAndroidAppTarget:e,formatAndroidInstalledPackageRequiredMessage:n}=await import(`./app-lifecycle.js`).then(e=>e.p);if(e(t)===`binary`)return n(t)}}async function _(e,t,s){if(!(!o(e.platform)||!t))return r(t)?a(e)?void 0:e.kind===`device`?n(s,t):i(t)?void 0:s??await v(e,t):await y(e,t)}async function v(e,t){try{let{resolveIosSimulatorDeepLinkBundleId:n}=await import(`./apps.js`).then(e=>e.t);return await n(e,t)}catch{return}}async function y(e,t){try{let{resolveIosApp:n}=await import(`./apps.js`).then(e=>e.t);return await n(e,t)}catch{return}}async function b(e,t){if(!(e.platform!==`android`||!t||r(t)))try{let{resolveAndroidApp:n}=await import(`./app-lifecycle.js`).then(e=>e.u),r=await n(e,t);return r.type===`package`?r.value:void 0}catch{return}}async function x(e,t,n){if(n||e.platform!==`android`||!t||!r(t))return n;try{let{getAndroidAppState:t}=await import(`./app-lifecycle.js`).then(e=>e.t);return(await t(e)).package?.trim()||n}catch{return n}}function S(e,t){return e.platform===`android`&&!!(t&&r(t))}function C(e){let t=e?.trim();if(!(!t||r(t)||!t.includes(`.`)))return t}async function w(e,t,n,r){return e.platform===`harmonyos`?C(t)??n:await _(e,t,n)??await r(e,t)??(S(e,t)?n:void 0)}export{u as a,w as i,b as n,g as o,d as r,c as t};
1
+ import{n as e}from"./rolldown-runtime.js";import{_ as t}from"./sdk-contracts.js";import{J as n,X as r,Y as i}from"./sdk-batch-runner.js";import{l as a,s as o}from"./sdk-device.js";import{n as s}from"./session.js";var c=e({inferAndroidPackageAfterOpen:()=>x,resolveAndroidPackageForOpen:()=>b,resolveRequestedOpenSurface:()=>d,resolveSessionAppBundleIdForTarget:()=>w,resolveSoleForegroundIosApp:()=>u,validateOpenRelaunchTarget:()=>g});const l=new Set([`app`,`desktop`,`frontmost-app`]);async function u(e={}){let{listLocalDeviceInventory:t,shouldPropagateDeviceInventoryProbeError:n}=await import(`./verified-file.js`).then(e=>e.c);try{let n=await t({platform:`ios`,iosSimulatorSetPath:e.simulatorSetPath,kind:`simulator`,booted:!0});if(n.length!==1)return;let[r]=n;if(!r)return;let{detectSoleRunningIosSimulatorApp:i}=await import(`./app-resolution.js`).then(e=>e.t),a=await i(r);return a?{device:r,app:a}:void 0}catch(e){if(n(e))throw e;return}}function d(e){let{device:t,surfaceFlag:n,openTarget:r,existingSurface:i}=e;return t.platform===`linux`?f(n,r,i):a(t)?p(n,r,i):m(n)}function f(e,n,r){if(!e)return r??`app`;let i=s(e);if(!l.has(i))throw new t(`INVALID_ARGS`,`Linux supports --surface app, desktop, and frontmost-app (got "${e}")`);return h(i,n),i}function p(e,t,n){if(!e)return n??`app`;let r=s(e);return r!==`app`&&r!==`menubar`&&h(r,t),r}function m(e){if(e)throw new t(`INVALID_ARGS`,`surface is only supported on macOS and Linux`);return`app`}function h(e,n){if(e!==`app`&&e!==`menubar`&&n)throw new t(`INVALID_ARGS`,`open --surface ${e} does not accept an app target`)}async function g(e){let{target:t,platform:r,surface:i}=e;if(t&&n(t))return`open --relaunch does not support URL targets.`;if(i!==void 0&&i!==`app`)return`open --relaunch is supported only for app surfaces.`;if(r===`android`&&t){let{classifyAndroidAppTarget:e,formatAndroidInstalledPackageRequiredMessage:n}=await import(`./app-lifecycle.js`).then(e=>e.p);if(e(t)===`binary`)return n(t)}}async function _(e,t,s){if(!(!o(e.platform)||!t))return n(t)?a(e)?void 0:e.kind===`device`?r(s,t):i(t)?void 0:s??await v(e,t):await y(e,t)}async function v(e,t){try{let{resolveIosSimulatorDeepLinkBundleId:n}=await import(`./apps.js`).then(e=>e.t);return await n(e,t)}catch{return}}async function y(e,t){try{let{resolveIosApp:n}=await import(`./apps.js`).then(e=>e.t);return await n(e,t)}catch{return}}async function b(e,t){if(!(e.platform!==`android`||!t||n(t)))try{let{resolveAndroidApp:n}=await import(`./app-lifecycle.js`).then(e=>e.u),r=await n(e,t);return r.type===`package`?r.value:void 0}catch{return}}async function x(e,t,r){if(r||e.platform!==`android`||!t||!n(t))return r;try{let{getAndroidAppState:t}=await import(`./app-lifecycle.js`).then(e=>e.t);return(await t(e)).package?.trim()||r}catch{return r}}function S(e,t){return e.platform===`android`&&!!(t&&n(t))}function C(e){let t=e?.trim();if(!(!t||n(t)||!t.includes(`.`)))return t}async function w(e,t,n,r){return e.platform===`harmonyos`?C(t)??n:await _(e,t,n)??await r(e,t)??(S(e,t)?n:void 0)}export{u as a,w as i,b as n,g as o,d as r,c as t};
@@ -1,5 +1,5 @@
1
- import{_ as e}from"./sdk-contracts.js";import{c as t,l as n}from"./sdk-device.js";import{A as r,C as i,_ as a,y as o}from"./sdk-android-adb.js";import{u as s}from"./host-process.js";import{n as c,o as l,t as u}from"./verified-file.js";import{t as d}from"./app-log-files.js";import{n as f,r as p,t as m}from"./platform-runtime-app-log-process.js";import{createTemporaryTextFile as h,n as g,t as _}from"./platform-runtime-host.js";import v from"node:fs";import{setTimeout as y}from"node:timers/promises";async function b(e,t){t=S(e,t),d(t);let n=u(t),r;try{r=v.createWriteStream(t,{fd:n,autoClose:!0})}catch(e){throw v.closeSync(n),e}let i;r.on(`error`,e=>{i??=e});let a=C(),o=``,s=Promise.resolve(),c,l=e=>{let t=s.then(e);return s=t.catch(()=>void 0),t},f=async e=>{let t=`${o}${e}`.split(`
2
- `);o=t.pop()??``;for(let e of t)await E(r,w(`${e}\n`,a))};return{write:async e=>await l(async()=>await f(T(e))),[Symbol.asyncDispose]:async()=>{c??=l(async()=>{if(o&&=(await E(r,w(o,a)),``),await D(r),i)throw i}),await c}}}async function x(e,t,n){if(t=S(e,t),!Number.isInteger(n)||n<1||n>1024*1024)throw TypeError(`App-log tail size must be between 1 byte and 1 MiB`);let r=c(t);if(r===void 0)return``;let i=v.fstatSync(r).size,a=Math.min(i,n),o=i-a,s=+(o>0),l=Buffer.alloc(a+s);try{v.readSync(r,l,0,l.length,o-s)}finally{v.closeSync(r)}let u=l.subarray(s).toString(`utf8`);if(s===0||l[0]===10)return u;let d=u.indexOf(`
3
- `);return d<0?``:u.slice(d+1)}function S(e,t){return p({sessionsDir:e,pathname:t,basename:`app.log`,label:`App-log output`})}function C(){return(process.env.AGENT_DEVICE_APP_LOG_REDACT_PATTERNS??``).split(`,`).map(e=>e.trim()).filter(Boolean).flatMap(e=>{try{return[new RegExp(e,`gi`)]}catch{return[]}})}function w(e,t){return t.reduce((e,t)=>e.replace(t,`[REDACTED]`),e)}function T(e){return typeof e==`string`?e:Buffer.from(e).toString(`utf8`)}async function E(e,t){t&&await new Promise((n,r)=>{e.write(t,e=>e?r(e):n())})}async function D(e){e.closed||await new Promise((t,n)=>{e.once(`error`,n),e.end(()=>{e.off(`error`,n),t()})})}function O(e){return Object.freeze({appLogs:Object.freeze({resolveSession:e.resolveSessionArtifacts,readRecent:async(t,n)=>{let{outputPath:r}=e.resolveSessionArtifacts(t);return k(r,n)},readProcessMarker:async t=>{let{pidPath:n}=e.resolveSessionArtifacts(t);return await e.processes.readMarker(n)}}),networkTransports:Object.freeze({resolve:e.resolveTransport})})}function k(e,t){if(!Number.isInteger(t)||t<1||t>2e4)throw TypeError(`Network app-log scan lines must be between 1 and 20000`);let n=c(e);if(n===void 0)return Object.freeze({path:e,exists:!1,text:``,skippedLines:0});try{let r=A(v.readFileSync(n,`utf8`),t);return Object.freeze({path:e,exists:!0,...r})}finally{v.closeSync(n)}}function A(e,t){let n=e.split(`
1
+ import{_ as e}from"./sdk-contracts.js";import{c as t,l as n}from"./sdk-device.js";import{A as r,C as i,_ as a,y as o}from"./sdk-android-adb.js";import{u as s}from"./host-process.js";import{n as c,o as l,t as u,u as d}from"./verified-file.js";import{t as f}from"./app-log-files.js";import{n as p,r as m,t as h}from"./platform-runtime-app-log-process.js";import{createTemporaryTextFile as g,n as _,t as v}from"./platform-runtime-host.js";import y from"node:fs";import{setTimeout as b}from"node:timers/promises";async function x(e,t){t=C(e,t),f(t);let n=u(t),r;try{r=y.createWriteStream(t,{fd:n,autoClose:!0})}catch(e){throw y.closeSync(n),e}let i;r.on(`error`,e=>{i??=e});let a=w(),o=``,s=Promise.resolve(),c,l=e=>{let t=s.then(e);return s=t.catch(()=>void 0),t},d=async e=>{let t=`${o}${e}`.split(`
2
+ `);o=t.pop()??``;for(let e of t)await D(r,T(`${e}\n`,a))};return{write:async e=>await l(async()=>await d(E(e))),[Symbol.asyncDispose]:async()=>{c??=l(async()=>{if(o&&=(await D(r,T(o,a)),``),await O(r),i)throw i}),await c}}}async function S(e,t,n){if(t=C(e,t),!Number.isInteger(n)||n<1||n>1024*1024)throw TypeError(`App-log tail size must be between 1 byte and 1 MiB`);let r=c(t);if(r===void 0)return``;let i=y.fstatSync(r).size,a=Math.min(i,n),o=i-a,s=+(o>0),l=Buffer.alloc(a+s);try{y.readSync(r,l,0,l.length,o-s)}finally{y.closeSync(r)}let u=l.subarray(s).toString(`utf8`);if(s===0||l[0]===10)return u;let d=u.indexOf(`
3
+ `);return d<0?``:u.slice(d+1)}function C(e,t){return m({sessionsDir:e,pathname:t,basename:`app.log`,label:`App-log output`})}function w(){return(process.env.AGENT_DEVICE_APP_LOG_REDACT_PATTERNS??``).split(`,`).map(e=>e.trim()).filter(Boolean).flatMap(e=>{try{return[new RegExp(e,`gi`)]}catch{return[]}})}function T(e,t){return t.reduce((e,t)=>e.replace(t,`[REDACTED]`),e)}function E(e){return typeof e==`string`?e:Buffer.from(e).toString(`utf8`)}async function D(e,t){t&&await new Promise((n,r)=>{e.write(t,e=>e?r(e):n())})}async function O(e){e.closed||await new Promise((t,n)=>{e.once(`error`,n),e.end(()=>{e.off(`error`,n),t()})})}function k(e){return Object.freeze({appLogs:Object.freeze({resolveSession:e.resolveSessionArtifacts,readRecent:async(t,n)=>{let{outputPath:r}=e.resolveSessionArtifacts(t);return A(r,n)},readProcessMarker:async t=>{let{pidPath:n}=e.resolveSessionArtifacts(t);return await e.processes.readMarker(n)}}),networkTransports:Object.freeze({resolve:e.resolveTransport})})}function A(e,t){if(!Number.isInteger(t)||t<1||t>2e4)throw TypeError(`Network app-log scan lines must be between 1 and 20000`);let n=c(e);if(n===void 0)return Object.freeze({path:e,exists:!1,text:``,skippedLines:0});try{let r=j(y.readFileSync(n,`utf8`),t);return Object.freeze({path:e,exists:!0,...r})}finally{y.closeSync(n)}}function j(e,t){let n=e.split(`
4
4
  `),r=Math.max(0,n.length-t);return Object.freeze({text:n.slice(r).join(`
5
- `),skippedLines:r})}function j(){let e=Object.freeze({resolve:async e=>{let{createAndroidScreenRecordingTransport:t}=await import(`./platform-runtime-screen-recording-android-host.js`);return await t(e)}}),t=Object.freeze({resolve:async e=>{let{resolveWebScreenRecordingTransport:t}=await import(`./platform-runtime-screen-recording-web-host.js`);return await t(e)}}),n=Object.freeze({prepare:async e=>{let{createScreenRecordingOutputHost:t}=await import(`./platform-runtime-screen-recording-output-host.js`);await t().prepare(e)}}),r=Object.freeze({complete:async(e,t)=>{let{createScreenRecordingFinalizer:n}=await import(`./platform-runtime-screen-recording-finalizer-host.js`);return await n().complete(e,t)}});return Object.freeze({apple:M(),android:e,harmony:N(),web:t,outputs:n,finalize:r})}function M(){let e=async()=>{let{createAppleScreenRecordingHost:e}=await import(`./platform-runtime-screen-recording-apple-host.js`);return e()};return Object.freeze({availability:async t=>(await e()).availability(t),runRunner:async(t,n,r)=>await(await e()).runRunner(t,n,r),startSimulator:async(t,n,r)=>await(await e()).startSimulator(t,n,r),inspectProcess:async t=>await(await e()).inspectProcess(t),terminateProcess:async t=>await(await e()).terminateProcess(t),inspectRunner:async(t,n,r)=>await(await e()).inspectRunner(t,n,r),retrieveRunnerRecording:async(t,n,r,i)=>await(await e()).retrieveRunnerRecording(t,n,r,i),captureClockAnchor:async(t,n,r)=>await(await e()).captureClockAnchor(t,n,r),isRunnerBundleId:async t=>await(await e()).isRunnerBundleId(t)})}function N(){let e=async()=>{let{createHarmonyScreenRecordingHost:e}=await import(`./platform-runtime-screen-recording-harmony-host.js`);return e()};return Object.freeze({start:async(t,n,r)=>await(await e()).start(t,n,r),stop:async(t,n)=>await(await e()).stop(t,n),findMedia:async(t,n,r)=>await(await e()).findMedia(t,n,r),stageMedia:async(t,n,r)=>await(await e()).stageMedia(t,n,r),stagedFileSize:async(t,n,r)=>await(await e()).stagedFileSize(t,n,r),pull:async(t,n,r)=>await(await e()).pull(t,n,r),remove:async(t,n,r)=>await(await e()).remove(t,n,r),removeMedia:async(t,n,r)=>await(await e()).removeMedia(t,n,r)})}function P(){return Object.freeze({ensureConnected:async(e,t)=>{t.throwIfAborted();try{let{resolveIosPhysicalDeviceControl:n}=await import(`./physical-device-control.js`).then(e=>e.t);await n(e).ensureReady(e,t),t.throwIfAborted()}catch(e){throw t.throwIfAborted(),e}}})}function ee(){return Object.freeze({keepHot:e=>{import(`./runner-client.js`).then(e=>e.r).then(({prewarmAppleRunnerCache:t})=>t(e,{})).catch(()=>{})},markBooted:e=>{import(`./simulator.js`).then(e=>e.i).then(({markSimulatorBooted:t})=>t(e)).catch(()=>{})}})}function F(){return Object.freeze({discover:async(e,t)=>{t.throwIfAborted();let n=await l(e);return t.throwIfAborted(),n},launch:(e,t)=>{let n=[`-avd`,e];return t&&n.push(`-no-window`,`-no-audio`),o(`emulator`,n)},terminate:async e=>{await s({pids:[e],termTimeoutMs:1500,killTimeoutMs:1500})}})}function I(){return Object.freeze({apple:Object.freeze({listApps:async(e,t)=>{let{listIosApps:n}=await import(`./apps.js`).then(e=>e.t);return L(await n(e,t))}}),android:Object.freeze({listApps:async(e,t)=>{let{listAndroidApps:n}=await import(`./app-lifecycle.js`).then(e=>e.t);return(await n(e,t)).map(e=>({id:e.package,name:e.name}))}}),harmonyos:Object.freeze({listApps:async(e,t,n)=>{let{listHarmonyApps:r}=await import(`./app-lifecycle2.js`);return(await r(e,t,{signal:n})).map(e=>({id:e.package,name:e.name}))}})})}function L(e){return e.map(e=>({id:e.bundleId,name:e.name}))}function R(){return Object.freeze({android:Object.freeze({run:async(e,t,n)=>{n.throwIfAborted();let{runAndroidAdb:r}=await import(`./app-lifecycle.js`).then(e=>e.m),i=await r(e,[...t.args],{allowFailure:t.allowFailure,timeoutMs:t.timeoutMs,signal:n});return n.throwIfAborted(),{stdout:i.stdout}}}),harmonyos:Object.freeze({run:async(e,t,n)=>{n.throwIfAborted();let{runHarmonyHdc:r}=await import(`./hdc.js`).then(e=>e.t),i=await r(e,[...t.args],{allowFailure:t.allowFailure,timeoutMs:t.timeoutMs,signal:n});return n.throwIfAborted(),{stdout:i.stdout}}})})}function z(e,t){let n,r,i=async()=>(n??=t.apple({appleTools:e.appleTools}),await n),a=async()=>(r??=t.android({commands:e.commands}),await r),o=Object.freeze({shutdownTarget:async(e,t)=>await(await i()).shutdownTarget(e,t)}),s=Object.freeze({shutdownTarget:async(e,t)=>await(await a()).shutdownTarget(e,t)}),c=Object.freeze({canShutdownTarget:async e=>await B(e,i,a),shutdownTarget:async e=>await V(e,i,a)});return Object.freeze({apple:o,android:s,close:c})}async function B(e,t,n){return e.platform===`apple`?(await t()).canShutdownTarget(e):e.platform===`android`?(await n()).canShutdownTarget(e):!1}async function V(e,t,n){let r=new AbortController().signal;return e.platform===`apple`?await(await t()).shutdownTarget(e,r):e.platform===`android`?await(await n()).shutdownTarget(e,r):{success:!1,exitCode:-1,stdout:``,stderr:`Cannot shut down unsupported device ${e.platform}/${e.kind}`}}function H(){return Object.freeze({withInvalidatedAppResolutionCache:async(e,t)=>{let{invalidateIosAppResolutionCache:n}=await import(`./app-resolution.js`).then(e=>e.t);return await n(e,t)},prepareArtifact:async(e,t)=>{let{prepareIosInstallArtifact:n}=await import(`./install-artifact2.js`);return await n(e.source,t)},resolveAppBundleId:async(e,t)=>{let{resolveIosApp:n}=await import(`./app-resolution.js`).then(e=>e.t);return await n(e,t)}})}function U(){return Object.freeze({bundletoolJar:process.env.AGENT_DEVICE_BUNDLETOOL_JAR?.trim()||void 0,withInvalidatedAppResolutionCache:async(e,t)=>{let{withAndroidAppResolutionCacheInvalidated:n}=await import(`./app-lifecycle.js`).then(e=>e.u);return await n(e,t)},prepareArtifact:async(e,t)=>{let{prepareAndroidInstallArtifact:n}=await import(`./install-artifact.js`);return await n(e.source,t)},resolveAppPackage:async(e,t)=>{let{resolveAndroidApp:n}=await import(`./app-lifecycle.js`).then(e=>e.u),r=await n(e,t);if(r.type===`intent`){let{AppError:e}=await import(`./sdk-contracts.js`).then(e=>e.b);throw new e(`INVALID_ARGS`,`App uninstall requires a package name, not an intent`)}return r.value}})}function W(){return Object.freeze({runAdb:async(e,t,n,r)=>{let{runAndroidAdb:i}=await import(`./app-lifecycle.js`).then(e=>e.m),a=await i(e,[...t],{allowFailure:n.allowFailure,timeoutMs:n.timeoutMs,signal:r});return{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode}},installPackage:async(e,t,n,r)=>{let{resolveAndroidAdbProvider:i}=await import(`./sdk-android-adb.js`).then(e=>e.t),a=i(e),o=a.install?await a.install(t,{replace:n.replace,signal:r}):await a.exec([`install`,...n.replace?[`-r`]:[],t],{signal:r});return{stdout:o.stdout,stderr:o.stderr,exitCode:o.exitCode}},installBundle:async(e,t,n,r)=>{let{resolveAndroidAdbProvider:i}=await import(`./sdk-android-adb.js`).then(e=>e.t),a=i(e).installBundle;return a?(await a(t,{mode:n,signal:r}),!0):!1}})}function G(){return Object.freeze({resolveOpenTarget:async(e,t)=>await K(e,t),prewarmRunnerCache:async(e,t,n)=>{let{prewarmAppleRunnerCache:r}=await import(`./runner-client.js`).then(e=>e.r);await r(e,Y(t,n))},prewarmRunnerSession:async(e,t,n,r)=>{let{prewarmIosRunnerSession:i}=await import(`./runner-client.js`).then(e=>e.r);await i(e,{...Y(t,n),propagateError:r})},notifyRunnerAppRelaunched:async(e,t,n)=>{let{notifyIosRunnerAppRelaunched:r}=await import(`./runner-client.js`).then(e=>e.r);await r(e,Y(t,n))},stopRunnerSession:async e=>{let{stopIosRunnerSession:t}=await import(`./runner-client.js`).then(e=>e.r);await t(e)},scheduleRunnerIdleStop:e=>{import(`./runner-client.js`).then(e=>e.r).then(({scheduleIosRunnerIdleStop:t})=>t(e))},prepareRunner:async(e,t,n)=>{let{Deadline:r}=await import(`./boot-diagnostics.js`).then(e=>e.s),{prepareIosRunner:i}=await import(`./runner-client.js`).then(e=>e.r),a=Date.now();return await i(e,{...Y(t.execution,n),cleanStaleBundles:!0,buildTimeoutMs:t.timeoutMs,healthTimeoutMs:t.timeoutMs,prepareDeadline:r.fromTimeoutMs(t.timeoutMs,a),startupTimeoutMs:t.timeoutMs})},applyRuntimeHints:async(e,t)=>{let{applyRuntimeHintValues:n}=await import(`./platform-runtime-runtime-hints.js`);await n({device:e,...t})},clearRuntimeHints:async(e,t)=>{let{clearRuntimeHintValues:n}=await import(`./platform-runtime-runtime-hints.js`);await n({device:e,...t})},dismissCloseAlerts:async(e,t)=>await X(e,t),detachRunnerSessionsForShutdown:async()=>{let{detachIosSimulatorRunnerSessionsForShutdown:e}=await import(`./runner-client.js`).then(e=>e.r);await e()},finalizeRunnerSessionsForShutdown:async()=>{let{stopAllIosRunnerSessions:e}=await import(`./runner-client.js`).then(e=>e.r);await e()}})}async function K(t,n){if(n.foreground){let n=await q(t);if(n)return n;throw new e(`AMBIGUOUS_MATCH`,`open --foreground requires exactly one running app on the selected iOS simulator.`,{reason:`foreground_app_ambiguous`,hint:`Pass an explicit app instead: agent-device open <app> --platform ios.`})}let r=await J(t,n.surface),{resolveSessionAppBundleIdForTarget:i}=await import(`./platform-runtime-open-target.js`).then(e=>e.t);return{appBundleId:r.appBundleId??await i(t,n.target,n.currentAppBundleId,async()=>void 0),appName:r.appName??n.target}}async function q(e){if(!t(e)||e.kind!==`simulator`)return;let{detectSoleRunningIosSimulatorApp:n}=await import(`./app-resolution.js`).then(e=>e.t),r=await n(e);return r?{appBundleId:r.bundleId,appName:r.name}:void 0}async function J(e,t){if(!n(e)||t===`app`||t===`desktop`||t===`menubar`)return{};let{resolveFrontmostMacOsApp:r}=await import(`./helper.js`).then(e=>e.t),i=await r();return{appBundleId:i.bundleId,appName:i.appName}}function Y(e,t){return{requestId:e.requestId,logPath:e.logPath,traceLogPath:e.traceLogPath,verbose:e.verbose,iosXctestrunFile:e.iosXctestrunFile,iosXctestDerivedDataPath:e.iosXctestDerivedDataPath,iosXctestEnvDir:e.iosXctestEnvDir,runnerLeaseContext:e.runnerLeaseContext,signal:t}}async function X(e,t){if(!n(e))return;let{runMacOsAlertAction:r}=await import(`./helper.js`).then(e=>e.t);await r(`dismiss`,t.surface===`frontmost-app`?{surface:`frontmost-app`}:t.appBundleId?{bundleId:t.appBundleId}:{})}function Z(){return Object.freeze({resolveOpenTarget:async(e,t)=>await Q(e,t),inferOpenedAppBundleId:async(e,t,n)=>{let{inferAndroidPackageAfterOpen:r}=await import(`./platform-runtime-open-target.js`).then(e=>e.t);return await r(e,t,n)},resetFramePerfStats:async(e,t)=>{let{resetAndroidFramePerfStats:n}=await import(`./perf.js`).then(e=>e.o);await n(e,t)},applyRuntimeHints:async(e,t)=>{let{applyRuntimeHintValues:n}=await import(`./platform-runtime-runtime-hints.js`);await n({device:e,...t})},clearRuntimeHints:async(e,t)=>{let{clearRuntimeHintValues:n}=await import(`./platform-runtime-runtime-hints.js`);await n({device:e,...t})},activateTestIme:async(t,n)=>{let{activateAndroidTestIme:i}=await import(`./ime-lifecycle.js`).then(e=>e.n),a=await i(t,n);if(a.outcome===`helper-unavailable`){r({level:`warn`,phase:`android_test_ime_activate_failed`,data:{device:t.id,error:a.reason}});return}if(a.persistFailed&&!(!a.alreadyActive&&!a.activated))throw new e(`COMMAND_FAILED`,`Android test IME recovery records could not be persisted for ${t.name??t.id}.`,{reason:`android_test_ime_recovery_fence_failed`,deviceId:t.id})},restoreTestIme:async(t,n)=>{let{restoreAndroidTestIme:r}=await import(`./ime-lifecycle.js`).then(e=>e.n);if((await r(t,{stateDir:n.stateDir})).reason===`set-failed`)throw new e(`COMMAND_FAILED`,`Android test IME could not be restored on ${t.name??t.id}.`,{reason:`android_test_ime_restore_incomplete`,deviceId:t.id})},recoverTestImeStartup:async e=>{let{listAndroidAdbSerialsQuick:t,restoreOrphanedAndroidTestImeOnDaemonStartup:n}=await import(`./ime-lifecycle.js`).then(e=>e.n);await n({stateDir:e.stateDir,listSerials:t})},hasTestImeRecoveryEvidence:async e=>{let{readAndroidTestImeRecoveryMarkers:t}=await import(`./ime-recovery-marker.js`).then(e=>e.n);return(await t(e)).length>0}})}async function Q(e,t){let{resolveAndroidPackageForOpen:n,resolveSessionAppBundleIdForTarget:r}=await import(`./platform-runtime-open-target.js`).then(e=>e.t);return{appBundleId:await r(e,t.target,t.currentAppBundleId,n),appName:t.target}}function $(){return Object.freeze({resolve:async(e,t)=>{let{getLocalInteractor:n}=await import(`./interactors.js`).then(e=>e.n);return await n(e,t)}})}function te(e){return Object.freeze({recoverStartupResources:async t=>{await e.android.hasTestImeRecoveryEvidence(t.stateDir)&&await e.android.recoverTestImeStartup(t)},detachForDaemonShutdown:async()=>await e.apple.detachRunnerSessionsForShutdown(),finalizeDaemonShutdown:async()=>await e.apple.finalizeRunnerSessionsForShutdown()})}function ne(e){let t=m(e.sessionsDir),n=Object.freeze({mode:`local`,start:t.start}),r=g(),o=Object.freeze({which:async e=>await i(e)?e:void 0,run:async(e,t)=>{let n=await a(e.executable,[...e.args],{allowFailure:e.allowFailure,cwd:e.cwd,env:e.env?{...process.env,...e.env}:void 0,signal:t,timeoutMs:e.timeoutMs});return{stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode}}}),s=O({resolveSessionArtifacts:e.resolveSessionArtifacts,processes:t,resolveTransport:async e=>{if(e.platform!==`web`)return Object.freeze({mode:`local`});let{resolveWebNetworkTransport:t}=await import(`./platform-runtime-network-web-transport.js`);return await t(e)}}),c=G(),l=Z();return Object.freeze({commands:o,appleTools:r,toolchains:_(),artifacts:Object.freeze({resolveSession:e.resolveSessionArtifacts}),outputs:Object.freeze({openAppend:async t=>await b(e.sessionsDir,t),readTail:async(t,n)=>await x(e.sessionsDir,t,n)}),processes:t,processTransports:Object.freeze({resolve:async t=>{if(t.platform!==`android`)return n;let{resolveAndroidAppLogProcessTransport:r}=await import(`./platform-runtime-app-log-android-transport.js`);return r(e.sessionsDir,t,n)}}),...s,appInventory:I(),appState:R(),appleDeployment:H(),androidDeployment:U(),androidTools:W(),temporaryFiles:Object.freeze({create:async e=>await h(e)}),deviceReadiness:Object.freeze({applePhysical:P(),appleAutomation:ee(),androidEmulator:F()}),deviceShutdown:z({appleTools:r,commands:o},e.shutdownLoaders),screenRecording:j(),localInteractors:$(),appleApplications:c,androidApplications:l,applicationResources:te({android:l,apple:c}),clock:Object.freeze({now:()=>Date.now(),sleep:async(e,t)=>{await y(e,void 0,t?{signal:t}:void 0)}})})}export{ne as createPlatformRuntimeHost,f as recoverLegacyAppLogMarkersAfterDaemonLock};
5
+ `),skippedLines:r})}function M(){let e=Object.freeze({resolve:async e=>{let{createAndroidScreenRecordingTransport:t}=await import(`./platform-runtime-screen-recording-android-host.js`);return await t(e)}}),t=Object.freeze({resolve:async e=>{let{resolveWebScreenRecordingTransport:t}=await import(`./platform-runtime-screen-recording-web-host.js`);return await t(e)}}),n=Object.freeze({prepare:async e=>{let{createScreenRecordingOutputHost:t}=await import(`./platform-runtime-screen-recording-output-host.js`);await t().prepare(e)}}),r=Object.freeze({complete:async(e,t)=>{let{createScreenRecordingFinalizer:n}=await import(`./platform-runtime-screen-recording-finalizer-host.js`);return await n().complete(e,t)}});return Object.freeze({apple:N(),android:e,harmony:P(),web:t,outputs:n,finalize:r})}function N(){let e=async()=>{let{createAppleScreenRecordingHost:e}=await import(`./platform-runtime-screen-recording-apple-host.js`);return e()};return Object.freeze({availability:async t=>(await e()).availability(t),runRunner:async(t,n,r)=>await(await e()).runRunner(t,n,r),startSimulator:async(t,n,r)=>await(await e()).startSimulator(t,n,r),inspectProcess:async t=>await(await e()).inspectProcess(t),terminateProcess:async t=>await(await e()).terminateProcess(t),inspectRunner:async(t,n,r)=>await(await e()).inspectRunner(t,n,r),retrieveRunnerRecording:async(t,n,r,i)=>await(await e()).retrieveRunnerRecording(t,n,r,i),captureClockAnchor:async(t,n,r)=>await(await e()).captureClockAnchor(t,n,r),isRunnerBundleId:async t=>await(await e()).isRunnerBundleId(t)})}function P(){let e=async()=>{let{createHarmonyScreenRecordingHost:e}=await import(`./platform-runtime-screen-recording-harmony-host.js`);return e()};return Object.freeze({start:async(t,n,r)=>await(await e()).start(t,n,r),stop:async(t,n)=>await(await e()).stop(t,n),findMedia:async(t,n,r)=>await(await e()).findMedia(t,n,r),stageMedia:async(t,n,r)=>await(await e()).stageMedia(t,n,r),stagedFileSize:async(t,n,r)=>await(await e()).stagedFileSize(t,n,r),pull:async(t,n,r)=>await(await e()).pull(t,n,r),remove:async(t,n,r)=>await(await e()).remove(t,n,r),removeMedia:async(t,n,r)=>await(await e()).removeMedia(t,n,r)})}function F(){return Object.freeze({ensureConnected:async(e,t)=>{t.throwIfAborted();try{let{resolveIosPhysicalDeviceControl:n}=await import(`./physical-device-control.js`).then(e=>e.t);await n(e).ensureReady(e,t),t.throwIfAborted()}catch(e){throw t.throwIfAborted(),e}}})}function I(){return Object.freeze({keepHot:e=>{import(`./runner-client.js`).then(e=>e.r).then(({prewarmAppleRunnerCache:t})=>t(e,{})).catch(()=>{})},markBooted:e=>{import(`./simulator.js`).then(e=>e.i).then(({markSimulatorBooted:t})=>t(e)).catch(()=>{})}})}function L(){return Object.freeze({discover:async(e,t)=>{t.throwIfAborted();let n=await d(e);return t.throwIfAborted(),n},launch:(e,t)=>{let n=[`-avd`,e];return t&&n.push(`-no-window`,`-no-audio`),o(`emulator`,n)},terminate:async e=>{await s({pids:[e],termTimeoutMs:1500,killTimeoutMs:1500})}})}function ee(){return Object.freeze({apple:Object.freeze({listApps:async(e,t)=>{let{listIosApps:n}=await import(`./apps.js`).then(e=>e.t);return R(await n(e,t))}}),android:Object.freeze({listApps:async(e,t)=>{let{listAndroidApps:n}=await import(`./app-lifecycle.js`).then(e=>e.t);return(await n(e,t)).map(e=>({id:e.package,name:e.name}))}}),harmonyos:Object.freeze({listApps:async(e,t,n)=>{let{listHarmonyApps:r}=await import(`./app-lifecycle2.js`);return(await r(e,t,{signal:n})).map(e=>({id:e.package,name:e.name}))}})})}function R(e){return e.map(e=>({id:e.bundleId,name:e.name}))}function z(){return Object.freeze({android:Object.freeze({run:async(e,t,n)=>{n.throwIfAborted();let{runAndroidAdb:r}=await import(`./app-lifecycle.js`).then(e=>e.m),i=await r(e,[...t.args],{allowFailure:t.allowFailure,timeoutMs:t.timeoutMs,signal:n});return n.throwIfAborted(),{stdout:i.stdout}}}),harmonyos:Object.freeze({run:async(e,t,n)=>{n.throwIfAborted();let{runHarmonyHdc:r}=await import(`./hdc.js`).then(e=>e.t),i=await r(e,[...t.args],{allowFailure:t.allowFailure,timeoutMs:t.timeoutMs,signal:n});return n.throwIfAborted(),{stdout:i.stdout}}})})}function B(e,t){let n,r,i=async()=>(n??=t.apple({appleTools:e.appleTools}),await n),a=async()=>(r??=t.android({commands:e.commands}),await r),o=Object.freeze({shutdownTarget:async(e,t)=>await(await i()).shutdownTarget(e,t)}),s=Object.freeze({shutdownTarget:async(e,t)=>await(await a()).shutdownTarget(e,t)}),c=Object.freeze({canShutdownTarget:async e=>await V(e,i,a),shutdownTarget:async e=>await H(e,i,a)});return Object.freeze({apple:o,android:s,close:c})}async function V(e,t,n){return e.platform===`apple`?(await t()).canShutdownTarget(e):e.platform===`android`?(await n()).canShutdownTarget(e):!1}async function H(e,t,n){let r=new AbortController().signal;return e.platform===`apple`?await(await t()).shutdownTarget(e,r):e.platform===`android`?await(await n()).shutdownTarget(e,r):{success:!1,exitCode:-1,stdout:``,stderr:`Cannot shut down unsupported device ${e.platform}/${e.kind}`}}function U(){return Object.freeze({withInvalidatedAppResolutionCache:async(e,t)=>{let{invalidateIosAppResolutionCache:n}=await import(`./app-resolution.js`).then(e=>e.t);return await n(e,t)},prepareArtifact:async(e,t)=>{let{prepareIosInstallArtifact:n}=await import(`./install-artifact2.js`);return await n(e.source,t)},resolveAppBundleId:async(e,t)=>{let{resolveIosApp:n}=await import(`./app-resolution.js`).then(e=>e.t);return await n(e,t)}})}function W(){return Object.freeze({bundletoolJar:process.env.AGENT_DEVICE_BUNDLETOOL_JAR?.trim()||void 0,withInvalidatedAppResolutionCache:async(e,t)=>{let{withAndroidAppResolutionCacheInvalidated:n}=await import(`./app-lifecycle.js`).then(e=>e.u);return await n(e,t)},prepareArtifact:async(e,t)=>{let{prepareAndroidInstallArtifact:n}=await import(`./install-artifact.js`);return await n(e.source,t)},resolveAppPackage:async(e,t)=>{let{resolveAndroidApp:n}=await import(`./app-lifecycle.js`).then(e=>e.u),r=await n(e,t);if(r.type===`intent`){let{AppError:e}=await import(`./sdk-contracts.js`).then(e=>e.S);throw new e(`INVALID_ARGS`,`App uninstall requires a package name, not an intent`)}return r.value}})}function G(){return Object.freeze({runAdb:async(e,t,n,r)=>{let{runAndroidAdb:i}=await import(`./app-lifecycle.js`).then(e=>e.m),a=await i(e,[...t],{allowFailure:n.allowFailure,timeoutMs:n.timeoutMs,signal:r});return{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode}},installPackage:async(e,t,n,r)=>{let{resolveAndroidAdbProvider:i}=await import(`./sdk-android-adb.js`).then(e=>e.t),a=i(e),o=a.install?await a.install(t,{replace:n.replace,signal:r}):await a.exec([`install`,...n.replace?[`-r`]:[],t],{signal:r});return{stdout:o.stdout,stderr:o.stderr,exitCode:o.exitCode}},installBundle:async(e,t,n,r)=>{let{resolveAndroidAdbProvider:i}=await import(`./sdk-android-adb.js`).then(e=>e.t),a=i(e).installBundle;return a?(await a(t,{mode:n,signal:r}),!0):!1}})}function K(){return Object.freeze({resolveOpenTarget:async(e,t)=>await q(e,t),prewarmRunnerCache:async(e,t,n)=>{let{prewarmAppleRunnerCache:r}=await import(`./runner-client.js`).then(e=>e.r);await r(e,X(t,n))},prewarmRunnerSession:async(e,t,n,r)=>{let{prewarmIosRunnerSession:i}=await import(`./runner-client.js`).then(e=>e.r);await i(e,{...X(t,n),propagateError:r})},notifyRunnerAppRelaunched:async(e,t,n)=>{let{notifyIosRunnerAppRelaunched:r}=await import(`./runner-client.js`).then(e=>e.r);await r(e,X(t,n))},stopRunnerSession:async e=>{let{stopIosRunnerSession:t}=await import(`./runner-client.js`).then(e=>e.r);await t(e)},scheduleRunnerIdleStop:e=>{import(`./runner-client.js`).then(e=>e.r).then(({scheduleIosRunnerIdleStop:t})=>t(e))},prepareRunner:async(e,t,n)=>{let{Deadline:r}=await import(`./boot-diagnostics.js`).then(e=>e.s),{prepareIosRunner:i}=await import(`./runner-client.js`).then(e=>e.r),a=Date.now();return await i(e,{...X(t.execution,n),cleanStaleBundles:!0,buildTimeoutMs:t.timeoutMs,healthTimeoutMs:t.timeoutMs,prepareDeadline:r.fromTimeoutMs(t.timeoutMs,a),startupTimeoutMs:t.timeoutMs})},applyRuntimeHints:async(e,t)=>{let{applyRuntimeHintValues:n}=await import(`./platform-runtime-runtime-hints.js`);await n({device:e,...t})},clearRuntimeHints:async(e,t)=>{let{clearRuntimeHintValues:n}=await import(`./platform-runtime-runtime-hints.js`);await n({device:e,...t})},dismissCloseAlerts:async(e,t)=>await Z(e,t),detachRunnerSessionsForShutdown:async()=>{let{detachIosSimulatorRunnerSessionsForShutdown:e}=await import(`./runner-client.js`).then(e=>e.r);await e()},finalizeRunnerSessionsForShutdown:async()=>{let{stopAllIosRunnerSessions:e}=await import(`./runner-client.js`).then(e=>e.r);await e()}})}async function q(t,n){if(n.foreground){let n=await J(t);if(n)return n;throw new e(`AMBIGUOUS_MATCH`,`open --foreground requires exactly one running app on the selected iOS simulator.`,{reason:`foreground_app_ambiguous`,hint:`Pass an explicit app instead: agent-device open <app> --platform ios.`})}let r=await Y(t,n.surface),{resolveSessionAppBundleIdForTarget:i}=await import(`./platform-runtime-open-target.js`).then(e=>e.t);return{appBundleId:r.appBundleId??await i(t,n.target,n.currentAppBundleId,async()=>void 0),appName:r.appName??n.target}}async function J(e){if(!t(e)||e.kind!==`simulator`)return;let{detectSoleRunningIosSimulatorApp:n}=await import(`./app-resolution.js`).then(e=>e.t),r=await n(e);return r?{appBundleId:r.bundleId,appName:r.name}:void 0}async function Y(e,t){if(!n(e)||t===`app`||t===`desktop`||t===`menubar`)return{};let{resolveFrontmostMacOsApp:r}=await import(`./helper.js`).then(e=>e.t),i=await r();return{appBundleId:i.bundleId,appName:i.appName}}function X(e,t){return{requestId:e.requestId,logPath:e.logPath,traceLogPath:e.traceLogPath,verbose:e.verbose,iosXctestrunFile:e.iosXctestrunFile,iosXctestDerivedDataPath:e.iosXctestDerivedDataPath,iosXctestEnvDir:e.iosXctestEnvDir,runnerLeaseContext:e.runnerLeaseContext,signal:t}}async function Z(e,t){if(!n(e))return;let{runMacOsAlertAction:r}=await import(`./helper.js`).then(e=>e.t);await r(`dismiss`,t.surface===`frontmost-app`?{surface:`frontmost-app`}:t.appBundleId?{bundleId:t.appBundleId}:{})}function Q(){return Object.freeze({resolveOpenTarget:async(e,t)=>await $(e,t),inferOpenedAppBundleId:async(e,t,n)=>{let{inferAndroidPackageAfterOpen:r}=await import(`./platform-runtime-open-target.js`).then(e=>e.t);return await r(e,t,n)},resetFramePerfStats:async(e,t)=>{let{resetAndroidFramePerfStats:n}=await import(`./perf.js`).then(e=>e.o);await n(e,t)},applyRuntimeHints:async(e,t)=>{let{applyRuntimeHintValues:n}=await import(`./platform-runtime-runtime-hints.js`);await n({device:e,...t})},clearRuntimeHints:async(e,t)=>{let{clearRuntimeHintValues:n}=await import(`./platform-runtime-runtime-hints.js`);await n({device:e,...t})},activateTestIme:async(t,n)=>{let{activateAndroidTestIme:i}=await import(`./ime-lifecycle.js`).then(e=>e.n),a=await i(t,n);if(a.outcome===`helper-unavailable`){r({level:`warn`,phase:`android_test_ime_activate_failed`,data:{device:t.id,error:a.reason}});return}if(a.persistFailed&&!(!a.alreadyActive&&!a.activated))throw new e(`COMMAND_FAILED`,`Android test IME recovery records could not be persisted for ${t.name??t.id}.`,{reason:`android_test_ime_recovery_fence_failed`,deviceId:t.id})},restoreTestIme:async(t,n)=>{let{restoreAndroidTestIme:r}=await import(`./ime-lifecycle.js`).then(e=>e.n);if((await r(t,{stateDir:n.stateDir})).reason===`set-failed`)throw new e(`COMMAND_FAILED`,`Android test IME could not be restored on ${t.name??t.id}.`,{reason:`android_test_ime_restore_incomplete`,deviceId:t.id})},recoverTestImeStartup:async e=>{let{listAndroidAdbSerialsQuick:t,restoreOrphanedAndroidTestImeOnDaemonStartup:n}=await import(`./ime-lifecycle.js`).then(e=>e.n);await n({stateDir:e.stateDir,listSerials:t})},hasTestImeRecoveryEvidence:async e=>{let{readAndroidTestImeRecoveryMarkers:t}=await import(`./ime-recovery-marker.js`).then(e=>e.n);return(await t(e)).length>0}})}async function $(e,t){let{resolveAndroidPackageForOpen:n,resolveSessionAppBundleIdForTarget:r}=await import(`./platform-runtime-open-target.js`).then(e=>e.t);return{appBundleId:await r(e,t.target,t.currentAppBundleId,n),appName:t.target}}function te(){return Object.freeze({resolve:async(e,t)=>{let{getLocalInteractor:n}=await import(`./interactors.js`).then(e=>e.n);return await n(e,t)}})}function ne(e){return Object.freeze({recoverStartupResources:async t=>{await e.android.hasTestImeRecoveryEvidence(t.stateDir)&&await e.android.recoverTestImeStartup(t)},detachForDaemonShutdown:async()=>await e.apple.detachRunnerSessionsForShutdown(),finalizeDaemonShutdown:async()=>await e.apple.finalizeRunnerSessionsForShutdown()})}function re(e){let t=h(e.sessionsDir),n=Object.freeze({mode:`local`,start:t.start}),r=_(),o=Object.freeze({which:async e=>await i(e)?e:void 0,run:async(e,t)=>{let n=await a(e.executable,[...e.args],{allowFailure:e.allowFailure,cwd:e.cwd,env:e.env?{...process.env,...e.env}:void 0,signal:t,timeoutMs:e.timeoutMs});return{stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode}}}),s=k({resolveSessionArtifacts:e.resolveSessionArtifacts,processes:t,resolveTransport:async e=>{if(e.platform!==`web`)return Object.freeze({mode:`local`});let{resolveWebNetworkTransport:t}=await import(`./platform-runtime-network-web-transport.js`);return await t(e)}}),c=K(),u=Q();return Object.freeze({commands:o,appleTools:r,toolchains:v(),artifacts:Object.freeze({resolveSession:e.resolveSessionArtifacts}),outputs:Object.freeze({openAppend:async t=>await x(e.sessionsDir,t),readTail:async(t,n)=>await S(e.sessionsDir,t,n)}),processes:t,processTransports:Object.freeze({resolve:async t=>{if(t.platform!==`android`)return n;let{resolveAndroidAppLogProcessTransport:r}=await import(`./platform-runtime-app-log-android-transport.js`);return r(e.sessionsDir,t,n)}}),...s,appInventory:ee(),appState:z(),appleDeployment:U(),androidDeployment:W(),androidTools:G(),temporaryFiles:Object.freeze({create:async e=>await g(e)}),deviceReadiness:Object.freeze({applePhysical:F(),appleAutomation:I(),androidEmulator:L()}),deviceShutdown:B({appleTools:r,commands:o},e.shutdownLoaders),screenRecording:M(),snapshot:l(),localInteractors:te(),appleApplications:c,androidApplications:u,applicationResources:ne({android:u,apple:c}),clock:Object.freeze({now:()=>Date.now(),sleep:async(e,t)=>{await b(e,void 0,t?{signal:t}:void 0)}})})}export{re as createPlatformRuntimeHost,p as recoverLegacyAppLogMarkersAfterDaemonLock};
@@ -1 +1 @@
1
- import{n as e}from"./rolldown-runtime.js";import{_ as t}from"./sdk-contracts.js";import{C as n,Ct as r,St as i,at as a,ct as o,it as s,rt as c,wt as l}from"./sdk-batch-runner.js";import{C as u,D as d,E as f,T as p,s as m}from"./sdk-device.js";import{l as h,o as g,u as ee}from"./device.js";const _=Object.freeze({family:`apple`}),v=Object.freeze({..._,loadRuntime:async e=>{let{createApplePlatformRuntime:t}=await import(`./runtime4.js`);return t(e)}}),te=Object.freeze({..._,loadInventory:async e=>{let{createAppleInventorySource:t}=await import(`./inventory2.js`);return t(e)}});async function ne(e){let{createAppleShutdownRuntime:t}=await import(`./runtime5.js`);return t(e)}const y=Object.freeze({family:`android`});async function re(e,t,n){let{readAndroidAppState:r}=await import(`./app-state.js`);return await r(e,t,n)}async function b(e){let{parseAndroidForegroundApp:t}=await import(`./app-state.js`);return t(e)}const x=Object.freeze({...y,loadRuntime:async e=>{let{createAndroidPlatformRuntime:t}=await import(`./runtime2.js`);return t(e)}});function S(e){let t=Object.freeze({sdkRoots:Object.freeze([...new Set(e.sdkRoots.map(e=>e.trim()).filter(Boolean))])});return Object.freeze({...y,loadInventory:async e=>{let{createAndroidInventory:n}=await import(`./inventory.js`);return n(e,t)}})}async function C(e){let{createAndroidShutdownRuntime:t}=await import(`./runtime3.js`);return t(e)}const w=Object.freeze({family:`harmonyos`}),T=Object.freeze({...w,loadRuntime:async e=>{let{createHarmonyPlatformRuntime:t}=await import(`./runtime6.js`);return t(e)}});function ie(e){let t=Object.freeze({hdcSdkPath:E(e.hdcSdkPath),devecoSdkHome:E(e.devecoSdkHome),commandLineToolsHome:E(e.commandLineToolsHome)});return Object.freeze({...w,loadInventory:async e=>{let{createHarmonyInventory:n}=await import(`./inventory3.js`);return n(e,t)}})}function E(e){return e?.trim()||void 0}const D=Object.freeze({family:`vega`}),ae=Object.freeze({...D,loadRuntime:async e=>{let{createVegaPlatformRuntime:t}=await import(`./runtime8.js`);return t(e)}}),oe=Object.freeze({...D,loadInventory:async e=>{let{createVegaInventory:t}=await import(`./inventory5.js`);return t(e)}}),O=Object.freeze({family:`linux`}),se=Object.freeze({...O,loadRuntime:async e=>{let{createLinuxPlatformRuntime:t}=await import(`./runtime7.js`);return t(e)}}),ce=Object.freeze({...O,loadInventory:async e=>{let{createLinuxInventory:t}=await import(`./inventory4.js`);return t(e)}}),k=Object.freeze({family:`web`}),A=Object.freeze({...k,loadRuntime:async e=>{let{createWebPlatformRuntime:t}=await import(`./runtime9.js`);return t(e)}}),j=Object.freeze({...k,loadInventory:async()=>{let{createWebInventory:e}=await import(`./inventory6.js`);return e()}});function M(e){let t=new Map,n=new Map;for(let i of e.providerModules??[]){let{runtime:e,module:a}=i,o=r(a.owner);if(a.owner.provider!==e.provider)throw K(`Provider platform runtime metadata is invalid: ${o}`);if(t.has(o))throw K(`Duplicate platform runtime owner: ${o}`);if(n.has(e))throw K(`Duplicate platform module registration for ${e.provider}`);t.set(o,i),n.set(e,a)}let i=new Map,a=new Map,s=new Map,c,u=async()=>{c??=e.loadHost();try{return await c}catch(e){throw c=void 0,e}},d,f,p=Object.freeze({recoverStartupResources:async e=>{await o(e.stateDir,async()=>{await(await u()).applicationResources.recoverStartupResources(e)})},detachForDaemonShutdown:async()=>{d??=u().then(async e=>await e.applicationResources.detachForDaemonShutdown()),await d},finalizeDaemonShutdown:async()=>{f??=u().then(async e=>await e.applicationResources.finalizeDaemonShutdown()),await f}}),m=e=>{let t=r(e.owner),n=s.get(t);if(n&&n!==e)throw K(`Duplicate platform runtime owner: ${t}`);return s.set(t,e),e},h=async t=>{let n=i.get(t);if(n)return await n;let r=e.modules.get(t);if(!r)throw K(`Missing platform runtime module for ${t}`);if(r.family!==t)throw K(`Platform runtime module registered for ${t} declares ${r.family}`);let a=u().then(async e=>{let n=await r.loadRuntime(e);if(n.owner.kind!==`local-family`||n.owner.family!==t)throw K(`Platform runtime module for ${t} returned a different local owner`);return m(n)});i.set(t,a);try{return await a}catch(e){throw i.get(t)===a&&i.delete(t),e}},g=async e=>{let t=a.get(e);if(t)return await t;let n=u().then(async t=>{let n=await e.loadRuntime(t);if(!l(n.owner,e.owner))throw K(`Provider platform runtime returned a different advertised owner`);return m(n)});a.set(e,n);try{return await n}catch(t){throw a.get(e)===n&&a.delete(e),t}};return Object.freeze({applicationLifecycle:p,inspectFacts:async t=>{let r=N(e.providerRuntimes,t);if(r){let e=n.get(r);return e?await P(await g(e),t):U(r,t)}return await P(await h(t.platform),t)},bind:async r=>{if(r.intent.kind===`exact-owner`)return await F(await V(r.intent.owner,t,g,h),r);let i=N(e.providerRuntimes,r.device);if(i){let e=n.get(i);return e?await F(await g(e),r):H(i,r.device)}return await F(await h(r.device.platform),r)},shutdown:async()=>{await Promise.allSettled([...s.values()].map(async e=>await e.shutdown())),s.clear(),i.clear(),a.clear()}})}function N(e,t){let n=(e??[]).filter(e=>e.ownsDevice(t));if(n.length>1)throw K(`Multiple provider runtimes claim the selected device`);return n[0]}async function P(e,t){let n=await e.inspectFacts(t);if(!z(t,e.owner,n))throw K(`Platform runtime facts do not match the selected device and owner`);return n}async function F(e,t){let n=await e.bind(t),r=I(e,n,t);if(!r)return n;let i;try{await n[Symbol.asyncDispose]()}catch(e){i=e instanceof Error?e.message:String(e)}throw K(r,i)}function I(e,t,n){if(!l(t.owner,e.owner))return`Platform binding returned a different owner than the selected runtime`;if(!L(t.owner,n))return`Exact platform binding returned a different persisted owner`;if(!f(u(t.device),u(n.device)))return`Platform binding returned a different device identity`;if(!R(t))return`Platform binding facts do not match its device and owner`}function L(e,t){return t.intent.kind!==`exact-owner`||l(e,t.intent.owner)}function R(e){return z(e.device,e.owner,e.facts)}function z(e,t,n){return d(n.device,p(e))&&B(n.device.providerMode,t)}function B(e,t){return t.kind===`local-family`?e===`local`||e===`transport-composed`:e===`provider-runtime`}async function V(e,t,n,i){if(e.kind===`local-family`){let t=await i(e.family);if(l(t.owner,e))return t;throw G(e)}let a=t.get(r(e));if(a)return await n(a.module);throw G(e)}function H(e,t){let n=i(e.provider,`default`),r=Object.freeze({available:!1,reason:`unsupported-provider-mode`});return c(t,n,{appLog:r,appState:r,network:r,lifecycle:W(r)})}function U(e,t){let n=Object.freeze({available:!1,reason:`unsupported-provider-mode`});return s(t,i(e.provider,`default`),{appLog:n,appState:n,network:n,readiness:n,lifecycle:W(n)})}function W(e){return a({resolveOpenTarget:e,prepareApplicationOpen:e,openApplication:e,applyRuntimeHints:e,clearRuntimeHints:e,closeApplication:e,finalizeApplicationClose:e,prepareAppleRunner:e,configureProviderPortReverse:e})}function G(e){return new t(`UNSUPPORTED_OPERATION`,`The exact platform runtime owner is unavailable.`,{reason:`owner-unavailable`,owner:r(e)})}function K(e,n){return new t(`COMMAND_FAILED`,e,{reason:`runtime-contract-invalid`,...n?{cleanupError:n}:{}})}function le(e){let t=ue(e.registry,e.loadHost),n=e.provider,r=n?async(e,r)=>{r.signal.throwIfAborted();let i=await n.discover(ee(e),r.signal);return r.signal.throwIfAborted(),Y(i),i.kind===`inventory`?{devices:h(i.devices.map(e=>({...e})),e),source:`provider`}:{devices:await t.discover(e,r),source:`local`}}:async(e,n)=>({devices:await t.discover(e,n),source:`local`}),i=Object.freeze({discover:async(e,t)=>(await r(e,t)).devices,discoverWithSource:r});return Object.freeze({providerFirst:i,localOnly:t})}function ue(e,t){let n,r=async()=>{n??=t();try{return await n}catch(e){throw n=void 0,e}},i=new Map,a=async t=>{let n=i.get(t);if(n)return await n;let a=de(e.get(t),r);i.set(t,a);try{return await a}catch(e){throw i.get(t)===a&&i.delete(t),e}};return Object.freeze({discover:async(e,t)=>{if(t.signal.throwIfAborted(),e.platform)return await q(a,J(e.platform),e,t);let n=await Promise.all(g.map(async n=>{try{let r=await q(a,J(n),{...e,platform:n},t);return Array.isArray(r)?r:[]}catch{return[]}}));return t.signal.throwIfAborted(),n.flat()}})}async function de(e,t){switch(e.family){case`apple`:return await e.loadInventory(fe(await t()));case`android`:return await e.loadInventory(pe(await t()));case`harmonyos`:return await e.loadInventory(me(await t()));case`vega`:return await e.loadInventory(he(await t()));case`linux`:return await e.loadInventory(ge(await t()));case`web`:return await e.loadInventory()}}function fe(e){return Object.freeze({appleTools:e.appleTools,files:e.files,hostName:e.hostName,hostOs:e.hostOs,observations:e.observations})}function pe(e){return Object.freeze({commands:e.commands,files:e.files,homeDirectory:e.homeDirectory,toolchains:e.toolchains})}function me(e){return Object.freeze({commands:e.commands,files:e.files,toolchains:e.toolchains})}function he(e){return Object.freeze({commands:e.commands,files:e.files,homeDirectory:e.homeDirectory})}function ge(e){return Object.freeze({hostName:e.hostName,hostOs:e.hostOs})}async function q(e,t,n,r){let i=await e(t);r.signal.throwIfAborted();let a=await i.discover(n,r);return r.signal.throwIfAborted(),_e(t,a),h(a,n)}function J(e){return m(e)?`apple`:e}function _e(e,n){let r=n.find(t=>t.platform!==e);if(r)throw new t(`COMMAND_FAILED`,`Platform inventory source ${e} returned a ${r.platform} device.`,{expectedFamily:e,actualFamily:r.platform,deviceId:r.id})}function Y(e){if(typeof e==`object`&&e){let t=e;if(t.kind===`declined`&&!(`devices`in t)||t.kind===`inventory`&&Array.isArray(t.devices))return}throw new t(`COMMAND_FAILED`,`Provider device inventory returned an invalid outcome.`,{reason:`provider_inventory_contract_violation`})}var ve=e({createPlatformDeviceInventoryGateways:()=>Z,createPlatformRuntimeGateway:()=>$,parseAndroidForegroundApp:()=>be,platformModuleRegistry:()=>X,platformRuntimeModules:()=>Q,readAndroidAppStateWithHost:()=>ye});async function ye(e,t,n){return await re(e,t,n)}async function be(e){return await b(e)}const xe=S({sdkRoots:Ce(process.env.ANDROID_SDK_ROOT,process.env.ANDROID_HOME)}),Se=Object.freeze({apple:async e=>await ne(e),android:async e=>await C(e)}),X=n([te,xe,ie({hdcSdkPath:process.env.HDC_SDK_PATH,devecoSdkHome:process.env.DEVECO_SDK_HOME,commandLineToolsHome:process.env.HARMONYOS_COMMAND_LINE_TOOLS}),oe,ce,j]);function Z(e){return le({registry:X,loadHost:async()=>{let{createDeviceInventoryHost:e}=await import(`./platform-runtime-host.js`);return e()},provider:e})}const Q=new Map([[`apple`,v],[`android`,x],[`harmonyos`,T],[`vega`,ae],[`linux`,se],[`web`,A]]);function $(e){return M({modules:Q,loadHost:async()=>{let{createPlatformRuntimeHost:t}=await import(`./platform-runtime-operation-host.js`);return t({sessionsDir:e.sessionsDir,resolveSessionArtifacts:e.resolveSessionArtifacts,shutdownLoaders:Se})},providerRuntimes:e.providerRuntimes,providerModules:e.providerModules})}function Ce(...e){return e.flatMap(e=>{let t=e?.trim();return t?[t]:[]})}export{$ as n,ve as r,Z as t};
1
+ import{n as e}from"./rolldown-runtime.js";import{_ as t}from"./sdk-contracts.js";import{At as n,Ot as r,T as i,at as a,kt as o,ot as s,pt as c,ut as l}from"./sdk-batch-runner.js";import{C as u,D as d,E as f,T as p,s as m}from"./sdk-device.js";import{l as h,o as g,u as _}from"./device.js";const v=Object.freeze({family:`apple`}),ee=Object.freeze({...v,loadRuntime:async e=>{let{createApplePlatformRuntime:t}=await import(`./runtime4.js`);return t(e)}}),te=Object.freeze({...v,loadInventory:async e=>{let{createAppleInventorySource:t}=await import(`./inventory2.js`);return t(e)}});async function ne(e){let{createAppleShutdownRuntime:t}=await import(`./runtime5.js`);return t(e)}const y=Object.freeze({family:`android`});async function b(e,t,n){let{readAndroidAppState:r}=await import(`./app-state.js`);return await r(e,t,n)}async function x(e){let{parseAndroidForegroundApp:t}=await import(`./app-state.js`);return t(e)}const S=Object.freeze({...y,loadRuntime:async e=>{let{createAndroidPlatformRuntime:t}=await import(`./runtime2.js`);return t(e)}});function C(e){let t=Object.freeze({sdkRoots:Object.freeze([...new Set(e.sdkRoots.map(e=>e.trim()).filter(Boolean))])});return Object.freeze({...y,loadInventory:async e=>{let{createAndroidInventory:n}=await import(`./inventory.js`);return n(e,t)}})}async function w(e){let{createAndroidShutdownRuntime:t}=await import(`./runtime3.js`);return t(e)}const T=Object.freeze({family:`harmonyos`}),re=Object.freeze({...T,loadRuntime:async e=>{let{createHarmonyPlatformRuntime:t}=await import(`./runtime6.js`);return t(e)}});function ie(e){let t=Object.freeze({hdcSdkPath:E(e.hdcSdkPath),devecoSdkHome:E(e.devecoSdkHome),commandLineToolsHome:E(e.commandLineToolsHome)});return Object.freeze({...T,loadInventory:async e=>{let{createHarmonyInventory:n}=await import(`./inventory3.js`);return n(e,t)}})}function E(e){return e?.trim()||void 0}const D=Object.freeze({family:`vega`}),ae=Object.freeze({...D,loadRuntime:async e=>{let{createVegaPlatformRuntime:t}=await import(`./runtime8.js`);return t(e)}}),oe=Object.freeze({...D,loadInventory:async e=>{let{createVegaInventory:t}=await import(`./inventory5.js`);return t(e)}}),O=Object.freeze({family:`linux`}),se=Object.freeze({...O,loadRuntime:async e=>{let{createLinuxPlatformRuntime:t}=await import(`./runtime7.js`);return t(e)}}),ce=Object.freeze({...O,loadInventory:async e=>{let{createLinuxInventory:t}=await import(`./inventory4.js`);return t(e)}}),k=Object.freeze({family:`web`}),A=Object.freeze({...k,loadRuntime:async e=>{let{createWebPlatformRuntime:t}=await import(`./runtime9.js`);return t(e)}}),j=Object.freeze({...k,loadInventory:async()=>{let{createWebInventory:e}=await import(`./inventory6.js`);return e()}});function M(e){let t=new Map,r=new Map;for(let n of e.providerModules??[]){let{runtime:e,module:i}=n,a=o(i.owner);if(i.owner.provider!==e.provider)throw K(`Provider platform runtime metadata is invalid: ${a}`);if(t.has(a))throw K(`Duplicate platform runtime owner: ${a}`);if(r.has(e))throw K(`Duplicate platform module registration for ${e.provider}`);t.set(a,n),r.set(e,i)}let i=new Map,a=new Map,s=new Map,l,u=async()=>{l??=e.loadHost();try{return await l}catch(e){throw l=void 0,e}},d,f,p=Object.freeze({recoverStartupResources:async e=>{await c(e.stateDir,async()=>{await(await u()).applicationResources.recoverStartupResources(e)})},detachForDaemonShutdown:async()=>{d??=u().then(async e=>await e.applicationResources.detachForDaemonShutdown()),await d},finalizeDaemonShutdown:async()=>{f??=u().then(async e=>await e.applicationResources.finalizeDaemonShutdown()),await f}}),m=e=>{let t=o(e.owner),n=s.get(t);if(n&&n!==e)throw K(`Duplicate platform runtime owner: ${t}`);return s.set(t,e),e},h=async t=>{let n=i.get(t);if(n)return await n;let r=e.modules.get(t);if(!r)throw K(`Missing platform runtime module for ${t}`);if(r.family!==t)throw K(`Platform runtime module registered for ${t} declares ${r.family}`);let a=u().then(async e=>{let n=await r.loadRuntime(e);if(n.owner.kind!==`local-family`||n.owner.family!==t)throw K(`Platform runtime module for ${t} returned a different local owner`);return m(n)});i.set(t,a);try{return await a}catch(e){throw i.get(t)===a&&i.delete(t),e}},g=async e=>{let t=a.get(e);if(t)return await t;let r=u().then(async t=>{let r=await e.loadRuntime(t);if(!n(r.owner,e.owner))throw K(`Provider platform runtime returned a different advertised owner`);return m(r)});a.set(e,r);try{return await r}catch(t){throw a.get(e)===r&&a.delete(e),t}};return Object.freeze({applicationLifecycle:p,inspectFacts:async t=>{let n=N(e.providerRuntimes,t);if(n){let e=r.get(n);return e?await P(await g(e),t):U(n,t)}return await P(await h(t.platform),t)},bind:async n=>{if(n.intent.kind===`exact-owner`)return await F(await V(n.intent.owner,t,g,h),n);let i=N(e.providerRuntimes,n.device);if(i){let e=r.get(i);return e?await F(await g(e),n):H(i,n.device)}return await F(await h(n.device.platform),n)},shutdown:async()=>{await Promise.allSettled([...s.values()].map(async e=>await e.shutdown())),s.clear(),i.clear(),a.clear()}})}function N(e,t){let n=(e??[]).filter(e=>e.ownsDevice(t));if(n.length>1)throw K(`Multiple provider runtimes claim the selected device`);return n[0]}async function P(e,t){let n=await e.inspectFacts(t);if(!z(t,e.owner,n))throw K(`Platform runtime facts do not match the selected device and owner`);return n}async function F(e,t){let n=await e.bind(t),r=I(e,n,t);if(!r)return n;let i;try{await n[Symbol.asyncDispose]()}catch(e){i=e instanceof Error?e.message:String(e)}throw K(r,i)}function I(e,t,r){if(!n(t.owner,e.owner))return`Platform binding returned a different owner than the selected runtime`;if(!L(t.owner,r))return`Exact platform binding returned a different persisted owner`;if(!f(u(t.device),u(r.device)))return`Platform binding returned a different device identity`;if(!R(t))return`Platform binding facts do not match its device and owner`}function L(e,t){return t.intent.kind!==`exact-owner`||n(e,t.intent.owner)}function R(e){return z(e.device,e.owner,e.facts)}function z(e,t,n){return d(n.device,p(e))&&B(n.device.providerMode,t)}function B(e,t){return t.kind===`local-family`?e===`local`||e===`transport-composed`:e===`provider-runtime`}async function V(e,t,r,i){if(e.kind===`local-family`){let t=await i(e.family);if(n(t.owner,e))return t;throw G(e)}let a=t.get(o(e));if(a)return await r(a.module);throw G(e)}function H(e,t){let n=r(e.provider,`default`),i=Object.freeze({available:!1,reason:`unsupported-provider-mode`});return a(t,n,{appLog:i,appState:i,network:i,lifecycle:W(i)})}function U(e,t){let n=Object.freeze({available:!1,reason:`unsupported-provider-mode`});return s(t,r(e.provider,`default`),{appLog:n,appState:n,network:n,readiness:n,lifecycle:W(n)})}function W(e){return l({resolveOpenTarget:e,prepareApplicationOpen:e,openApplication:e,applyRuntimeHints:e,clearRuntimeHints:e,closeApplication:e,finalizeApplicationClose:e,prepareAppleRunner:e,configureProviderPortReverse:e})}function G(e){return new t(`UNSUPPORTED_OPERATION`,`The exact platform runtime owner is unavailable.`,{reason:`owner-unavailable`,owner:o(e)})}function K(e,n){return new t(`COMMAND_FAILED`,e,{reason:`runtime-contract-invalid`,...n?{cleanupError:n}:{}})}function le(e){let t=ue(e.registry,e.loadHost),n=e.provider,r=n?async(e,r)=>{r.signal.throwIfAborted();let i=await n.discover(_(e),r.signal);return r.signal.throwIfAborted(),Y(i),i.kind===`inventory`?{devices:h(i.devices.map(e=>({...e})),e),source:`provider`}:{devices:await t.discover(e,r),source:`local`}}:async(e,n)=>({devices:await t.discover(e,n),source:`local`}),i=Object.freeze({discover:async(e,t)=>(await r(e,t)).devices,discoverWithSource:r});return Object.freeze({providerFirst:i,localOnly:t})}function ue(e,t){let n,r=async()=>{n??=t();try{return await n}catch(e){throw n=void 0,e}},i=new Map,a=async t=>{let n=i.get(t);if(n)return await n;let a=de(e.get(t),r);i.set(t,a);try{return await a}catch(e){throw i.get(t)===a&&i.delete(t),e}};return Object.freeze({discover:async(e,t)=>{if(t.signal.throwIfAborted(),e.platform)return await q(a,J(e.platform),e,t);let n=await Promise.all(g.map(async n=>{try{let r=await q(a,J(n),{...e,platform:n},t);return Array.isArray(r)?r:[]}catch{return[]}}));return t.signal.throwIfAborted(),n.flat()}})}async function de(e,t){switch(e.family){case`apple`:return await e.loadInventory(fe(await t()));case`android`:return await e.loadInventory(pe(await t()));case`harmonyos`:return await e.loadInventory(me(await t()));case`vega`:return await e.loadInventory(he(await t()));case`linux`:return await e.loadInventory(ge(await t()));case`web`:return await e.loadInventory()}}function fe(e){return Object.freeze({appleTools:e.appleTools,files:e.files,hostName:e.hostName,hostOs:e.hostOs,observations:e.observations})}function pe(e){return Object.freeze({commands:e.commands,files:e.files,homeDirectory:e.homeDirectory,toolchains:e.toolchains})}function me(e){return Object.freeze({commands:e.commands,files:e.files,toolchains:e.toolchains})}function he(e){return Object.freeze({commands:e.commands,files:e.files,homeDirectory:e.homeDirectory})}function ge(e){return Object.freeze({hostName:e.hostName,hostOs:e.hostOs})}async function q(e,t,n,r){let i=await e(t);r.signal.throwIfAborted();let a=await i.discover(n,r);return r.signal.throwIfAborted(),_e(t,a),h(a,n)}function J(e){return m(e)?`apple`:e}function _e(e,n){let r=n.find(t=>t.platform!==e);if(r)throw new t(`COMMAND_FAILED`,`Platform inventory source ${e} returned a ${r.platform} device.`,{expectedFamily:e,actualFamily:r.platform,deviceId:r.id})}function Y(e){if(typeof e==`object`&&e){let t=e;if(t.kind===`declined`&&!(`devices`in t)||t.kind===`inventory`&&Array.isArray(t.devices))return}throw new t(`COMMAND_FAILED`,`Provider device inventory returned an invalid outcome.`,{reason:`provider_inventory_contract_violation`})}var ve=e({createPlatformDeviceInventoryGateways:()=>Z,createPlatformRuntimeGateway:()=>$,parseAndroidForegroundApp:()=>be,platformModuleRegistry:()=>X,platformRuntimeModules:()=>Q,readAndroidAppStateWithHost:()=>ye});async function ye(e,t,n){return await b(e,t,n)}async function be(e){return await x(e)}const xe=C({sdkRoots:Ce(process.env.ANDROID_SDK_ROOT,process.env.ANDROID_HOME)}),Se=Object.freeze({apple:async e=>await ne(e),android:async e=>await w(e)}),X=i([te,xe,ie({hdcSdkPath:process.env.HDC_SDK_PATH,devecoSdkHome:process.env.DEVECO_SDK_HOME,commandLineToolsHome:process.env.HARMONYOS_COMMAND_LINE_TOOLS}),oe,ce,j]);function Z(e){return le({registry:X,loadHost:async()=>{let{createDeviceInventoryHost:e}=await import(`./platform-runtime-host.js`);return e()},provider:e})}const Q=new Map([[`apple`,ee],[`android`,S],[`harmonyos`,re],[`vega`,ae],[`linux`,se],[`web`,A]]);function $(e){return M({modules:Q,loadHost:async()=>{let{createPlatformRuntimeHost:t}=await import(`./platform-runtime-operation-host.js`);return t({sessionsDir:e.sessionsDir,resolveSessionArtifacts:e.resolveSessionArtifacts,shutdownLoaders:Se})},providerRuntimes:e.providerRuntimes,providerModules:e.providerModules})}function Ce(...e){return e.flatMap(e=>{let t=e?.trim();return t?[t]:[]})}export{$ as n,ve as r,Z as t};
@@ -1 +1 @@
1
- import{_ as e}from"./sdk-contracts.js";import{B as t,R as n,at as r,it as i,ot as a,wt as o}from"./sdk-batch-runner.js";import{n as s}from"./src3.js";function c(e){return n({owner:`WebDriver`,openTargetIdentity:`bundle-id`,closeBeforeRelaunch:!0,binding:t({device:e.device,signal:e.signal,resolveInteractor:t=>e.getInteractor(e.device,t)})})}const l=Object.freeze({available:!0}),u=Object.freeze({available:!1,reason:`unsupported-provider-mode`}),d=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`WebDriver provider runtimes do not expose screen recording.`}),f=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Headless boot is unavailable for provider-owned devices.`}),p=Object.freeze({available:!1,reason:`owner-capability-missing`,hint:`WebDriver provider runtimes do not expose app inventory.`}),m=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`This WebDriver provider runtime does not expose app deployment.`}),h=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Push notifications are unavailable for WebDriver provider-owned devices.`}),g=Object.freeze({available:!1,reason:`owner-capability-missing`,hint:`The WebDriver provider session is no longer active for this device.`}),_=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`WebDriver provider runtimes do not expose a foreground app-state operation.`}),v=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Apple runner preparation is unavailable for WebDriver-owned devices.`}),y=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`WebDriver open is supported only for its owned iOS or Android mobile-device sessions.`}),b=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`WebDriver close is supported only for its owned iOS or Android mobile-device sessions.`}),x=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Runtime hints are not applied to provider-owned devices.`}),S=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`WebDriver provider runtimes do not expose port reverse.`});function C(e){let t=e.platform===`android`&&e.kind===`device`&&e.target===`mobile`||e.platform===`apple`&&e.kind===`device`&&e.target===`mobile`&&e.appleOs===`ios`,n=t?l:y,i=t?l:b;return r({resolveOpenTarget:n,prepareApplicationOpen:n,openApplication:n,applyRuntimeHints:x,clearRuntimeHints:x,closeApplication:i,finalizeApplicationClose:i,prepareAppleRunner:v,configureProviderPortReverse:S})}function w(t){return Object.freeze({owner:t.owner,ownsDevice:t.ownsDevice,inspectFacts:async e=>E(t,e),bind:async n=>{if(n.intent.kind===`exact-owner`&&!o(n.intent.owner,t.owner))throw new e(`UNSUPPORTED_OPERATION`,`WebDriver runtime owner identity does not match`);if(!t.ownsDevice(n.device))throw new e(`UNSUPPORTED_PLATFORM`,`WebDriver runtime does not own this device`);if(!D(t,n.device))throw new e(`UNSUPPORTED_OPERATION`,`The WebDriver provider session is no longer active for this device.`);return T(t,n.device,n.scope.signal)},shutdown:async()=>void 0})}function T(e,t,n){let r=t.platform===`apple`?`ios-device`:`android`,i=E(e,t),o=i.operations.deployApp,l=Object.freeze({ensureReady:async()=>({...t,booted:!0}),bootTarget:async()=>({...t,booted:!0}),...a(c({device:t,signal:n,getInteractor:(t,n)=>e.getInteractor?.(t,n)}),i.operations),networkDump:async t=>{let n=await e.host.appLogs.readRecent(t.sessionId,t.maxScanLines),i=s(n.text,{...t,path:n.path,exists:n.exists,lineNumberOffset:n.skippedLines,backend:r});return Object.freeze({source:`app-log`,backend:r,dump:i,notes:Object.freeze(i.entries.length===0?[`No HTTP(s) entries were found in recent session app logs.`]:[])})},...o.available&&e.deployment?{deployApp:async r=>await e.deployment.deployApp(t,r,n),materializeAppSource:async r=>await O(e.host,t,r,n),deployMaterializedApp:async r=>await e.deployment.deployMaterializedApp(t,r,n)}:{}});return Object.freeze({device:t,owner:e.owner,facts:i,operations:l,[Symbol.asyncDispose]:async()=>void 0})}function E(e,t){if(!D(e,t)){let n=i(t,e.owner,{appLog:g,appDeployment:g,network:g,screenRecording:g,lifecycle:r({resolveOpenTarget:g,prepareApplicationOpen:g,openApplication:g,applyRuntimeHints:g,clearRuntimeHints:g,closeApplication:g,finalizeApplicationClose:g,prepareAppleRunner:g,configureProviderPortReverse:g})});return Object.freeze({device:n.device,operations:{appLogInspect:g,appLogDoctor:g,appLogStart:g,appLogReattach:g,appLogCleanup:g,deployApp:g,materializeAppSource:g,deployMaterializedApp:g,sendPushNotification:g,appState:g,networkDump:g,screenRecordingStart:g,screenRecordingReattach:g,screenRecordingCleanup:g,ensureReady:g,bootTarget:g,bootTargetHeadless:g,listApps:g,shutdownTarget:g,...r({resolveOpenTarget:g,prepareApplicationOpen:g,openApplication:g,applyRuntimeHints:g,clearRuntimeHints:g,closeApplication:g,finalizeApplicationClose:g,prepareAppleRunner:g,configureProviderPortReverse:g})}})}let n=e.deployment?.fact(t)??m,a=i(t,e.owner,{appLog:u,appDeployment:m,network:u,screenRecording:d,lifecycle:C(t)});return Object.freeze({device:a.device,operations:{appLogInspect:u,appLogDoctor:u,appLogStart:u,appLogReattach:u,appLogCleanup:u,deployApp:n,materializeAppSource:n,deployMaterializedApp:n,sendPushNotification:h,appState:_,networkDump:l,screenRecordingStart:d,screenRecordingReattach:d,screenRecordingCleanup:d,ensureReady:l,bootTarget:l,bootTargetHeadless:f,listApps:p,shutdownTarget:{available:!1,reason:`unsupported-provider-mode`,hint:`WebDriver owns the target lifecycle for provider-owned devices.`},...C(t)}})}function D(e,t){return e.isSessionActive?.(t)??e.ownsDevice(t)}async function O(e,t,n,r){return t.platform===`apple`?await e.appleDeployment.prepareArtifact(n,{signal:r}):await e.androidDeployment.prepareArtifact(n,{signal:r})}export{w as createWebDriverPlatformRuntimeOwner};
1
+ import{_ as e}from"./sdk-contracts.js";import{At as t,B as n,H as r,ct as i,dt as a,lt as o,ot as s,ut as c}from"./sdk-batch-runner.js";import{n as l}from"./src3.js";function u(e){return n({owner:`WebDriver`,openTargetIdentity:`bundle-id`,closeBeforeRelaunch:!0,binding:r({device:e.device,signal:e.signal,resolveInteractor:t=>e.getInteractor(e.device,t)})})}const d=Object.freeze({available:!0}),f=Object.freeze({available:!1,reason:`unsupported-provider-mode`}),p=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`WebDriver provider runtimes do not expose screen recording.`}),m=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Headless boot is unavailable for provider-owned devices.`}),h=Object.freeze({available:!1,reason:`owner-capability-missing`,hint:`WebDriver provider runtimes do not expose app inventory.`}),g=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`This WebDriver provider runtime does not expose app deployment.`}),_=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Push notifications are unavailable for WebDriver provider-owned devices.`}),v=Object.freeze({available:!1,reason:`owner-capability-missing`,hint:`The WebDriver provider session is no longer active for this device.`}),y=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`This WebDriver provider runtime does not expose snapshot capture for this device.`}),b=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`WebDriver provider runtimes do not expose iOS simulator custom snapshot actions.`}),x=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`WebDriver provider runtimes do not expose a foreground app-state operation.`}),S=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Apple runner preparation is unavailable for WebDriver-owned devices.`}),C=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`WebDriver open is supported only for its owned iOS or Android mobile-device sessions.`}),w=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`WebDriver close is supported only for its owned iOS or Android mobile-device sessions.`}),T=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Runtime hints are not applied to provider-owned devices.`}),E=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`WebDriver provider runtimes do not expose port reverse.`});function D(e){let t=e.platform===`android`&&e.kind===`device`&&e.target===`mobile`||e.platform===`apple`&&e.kind===`device`&&e.target===`mobile`&&e.appleOs===`ios`,n=t?d:C,r=t?d:w;return c({resolveOpenTarget:n,prepareApplicationOpen:n,openApplication:n,applyRuntimeHints:T,clearRuntimeHints:T,closeApplication:r,finalizeApplicationClose:r,prepareAppleRunner:S,configureProviderPortReverse:E})}function O(n){return Object.freeze({owner:n.owner,ownsDevice:n.ownsDevice,inspectFacts:async e=>A(n,e),bind:async r=>{if(r.intent.kind===`exact-owner`&&!t(r.intent.owner,n.owner))throw new e(`UNSUPPORTED_OPERATION`,`WebDriver runtime owner identity does not match`);if(!n.ownsDevice(r.device))throw new e(`UNSUPPORTED_PLATFORM`,`WebDriver runtime does not own this device`);if(!M(n,r.device))throw new e(`UNSUPPORTED_OPERATION`,`The WebDriver provider session is no longer active for this device.`);return k(n,r.device,r.scope.signal)},shutdown:async()=>void 0})}function k(e,t,n){let r=t.platform===`apple`?`ios-device`:`android`,o=A(e,t),s=o.operations.deployApp,c=Object.freeze({ensureReady:async()=>({...t,booted:!0}),bootTarget:async()=>({...t,booted:!0}),...a(u({device:t,signal:n,getInteractor:(t,n)=>e.getInteractor?.(t,n)}),o.operations),...o.operations.captureSnapshot.available?i({device:t,signal:n,resolveInteractor:n=>e.getInteractor?.(t,n)}):{},networkDump:async t=>{let n=await e.host.appLogs.readRecent(t.sessionId,t.maxScanLines),i=l(n.text,{...t,path:n.path,exists:n.exists,lineNumberOffset:n.skippedLines,backend:r});return Object.freeze({source:`app-log`,backend:r,dump:i,notes:Object.freeze(i.entries.length===0?[`No HTTP(s) entries were found in recent session app logs.`]:[])})},...s.available&&e.deployment?{deployApp:async r=>await e.deployment.deployApp(t,r,n),materializeAppSource:async r=>await N(e.host,t,r,n),deployMaterializedApp:async r=>await e.deployment.deployMaterializedApp(t,r,n)}:{}});return Object.freeze({device:t,owner:e.owner,facts:o,operations:c,[Symbol.asyncDispose]:async()=>void 0})}function A(e,t){if(!M(e,t)){let n=s(t,e.owner,{appLog:v,appDeployment:v,network:v,screenRecording:v,lifecycle:c({resolveOpenTarget:v,prepareApplicationOpen:v,openApplication:v,applyRuntimeHints:v,clearRuntimeHints:v,closeApplication:v,finalizeApplicationClose:v,prepareAppleRunner:v,configureProviderPortReverse:v})});return Object.freeze({device:n.device,operations:{appLogInspect:v,appLogDoctor:v,appLogStart:v,appLogReattach:v,appLogCleanup:v,deployApp:v,materializeAppSource:v,deployMaterializedApp:v,sendPushNotification:v,appState:v,networkDump:v,screenRecordingStart:v,screenRecordingReattach:v,screenRecordingCleanup:v,...o({capture:v,customActions:v,withoutActiveApp:v}),ensureReady:v,bootTarget:v,bootTargetHeadless:v,listApps:v,shutdownTarget:v,...c({resolveOpenTarget:v,prepareApplicationOpen:v,openApplication:v,applyRuntimeHints:v,clearRuntimeHints:v,closeApplication:v,finalizeApplicationClose:v,prepareAppleRunner:v,configureProviderPortReverse:v})}})}let n=e.deployment?.fact(t)??g,r=s(t,e.owner,{appLog:f,appDeployment:g,network:f,screenRecording:p,lifecycle:D(t)});return Object.freeze({device:r.device,operations:{appLogInspect:f,appLogDoctor:f,appLogStart:f,appLogReattach:f,appLogCleanup:f,deployApp:n,materializeAppSource:n,deployMaterializedApp:n,sendPushNotification:_,appState:x,networkDump:d,screenRecordingStart:p,screenRecordingReattach:p,screenRecordingCleanup:p,...o({capture:e.snapshotAvailable!==!1&&e.getInteractor!==void 0&&j(t)?d:y,customActions:b,withoutActiveApp:e.snapshotAvailable!==!1&&e.getInteractor!==void 0&&j(t)?d:y}),ensureReady:d,bootTarget:d,bootTargetHeadless:m,listApps:h,shutdownTarget:{available:!1,reason:`unsupported-provider-mode`,hint:`WebDriver owns the target lifecycle for provider-owned devices.`},...D(t)}})}function j(e){return e.kind===`device`&&e.target===`mobile`&&(e.platform===`android`||e.platform===`apple`&&e.appleOs===`ios`)}function M(e,t){return e.isSessionActive?.(t)??e.ownsDevice(t)}async function N(e,t,n,r){return t.platform===`apple`?await e.appleDeployment.prepareArtifact(n,{signal:r}):await e.androidDeployment.prepareArtifact(n,{signal:r})}export{O as createWebDriverPlatformRuntimeOwner};
@@ -1 +1 @@
1
- import{E as e,_ as t}from"./sdk-contracts.js";import{b as n}from"./location-coordinates.js";import{A as r}from"./sdk-android-adb.js";import{a as i,i as a,n as o,r as s,t as c}from"./png-worker-contract.js";import l from"node:path";import u,{promises as d}from"node:fs";import{fileURLToPath as f}from"node:url";import{Worker as p}from"node:worker_threads";function m(e,t){try{let n=f(e),r=l.extname(n)||`.js`;return[l.join(l.dirname(n),`${t}${r}`),l.join(l.dirname(n),`internal`,`${t}${r}`)].find(e=>u.existsSync(e))??null}catch{return null}}var h=class extends Error{};let g=null,_=!1,v=!1,y=0;const b=new Map;function x(e){_=!0,!v&&(v=!0,r({level:`warn`,phase:`png_worker_unavailable`,data:{reason:e}}),process.emitWarning(`PNG worker unavailable, falling back to in-process PNG processing: ${e}`))}function S(n){let r=b.get(n.id);r&&(b.delete(n.id),T(),n.ok?r.resolve(n.result):r.reject(new t(e(n.error.code),n.error.message,n.error.details)))}function C(e,t){g===e&&(x(t.message),g=null,e.terminate().catch(()=>{}),w(new h(`PNG worker failed: ${t.message}`)))}function w(e){let t=[...b.values()];b.clear();for(let n of t)n.reject(e)}function T(){g&&(b.size>0?g.ref():g.unref())}function E(){if(_)return null;if(g)return g;let e=m(import.meta.url,`png-worker`);if(!e)return x(`worker entry module not found next to the current module`),null;try{let t=new p(e,{execArgv:e.endsWith(`.ts`)?[`--experimental-strip-types`]:[]});return t.on(`message`,S),t.on(`error`,e=>{C(t,e)}),t.on(`exit`,e=>{C(t,Error(`PNG worker exited with code ${e}`))}),t.unref(),g=t,t}catch(e){return x(`failed to spawn worker: ${e instanceof Error?e.message:String(e)}`),null}}function D(e){let t=E();if(!t)return Promise.reject(new h(`PNG worker is unavailable`));y+=1;let n=y;return new Promise((r,i)=>{b.set(n,{resolve:r,reject:i}),T();try{t.postMessage({...e,id:n})}catch(e){b.delete(n),T(),i(new h(`failed to post job to PNG worker: ${e instanceof Error?e.message:String(e)}`))}})}async function O(e,t){try{return await D(e)}catch(e){if(e instanceof h)return t();throw e}}function k(){E()}async function A(){let e=g;g=null,w(new h(`PNG worker terminated`)),e&&await e.terminate()}async function j(e,t){let n=await O({kind:`decode`,png:e,label:t},()=>{let n=a(e,t);return{kind:`decode`,width:n.width,height:n.height,data:n.data}}),r=new i.PNG({width:n.width,height:n.height});return r.data=c(n.data),r}async function M(e){return c((await O({kind:`encode`,width:e.width,height:e.height,data:e.data},()=>({kind:`encode`,png:i.PNG.sync.write(e)}))).png)}async function N(e,t,n){let{kind:r,...i}=await O({kind:`rgb-difference`,firstPng:e,secondPng:t,label:n},()=>({kind:`rgb-difference`,...o(a(e,n),a(t,n))}));return i}async function P(e){let{kind:t,...n}=await O({kind:`diff-pixels`,...e},()=>({kind:`diff-pixels`,...s(e)}));return{...n,diffData:c(n.diffData)}}async function F(e,r){let{min:i,max:a}=n;if(!Number.isFinite(r)||r<i||r>a)throw new t(`INVALID_ARGS`,`Screenshot scale must be between ${i} and ${a}`);if(r===1)return;let o=await j(await d.readFile(e),`screenshot`),s=Math.max(1,Math.round(o.width*r)),c=Math.max(1,Math.round(o.height*r));await d.writeFile(e,await M(L(o,s,c)))}async function I(e,n,r){if(!Number.isInteger(n)||n<1||!Number.isInteger(r)||r<1)throw new t(`INVALID_ARGS`,`Screenshot resize dimensions must be positive integers`);let i=await j(await d.readFile(e),`screenshot`);i.width===n&&i.height===r||await d.writeFile(e,await M(L(i,n,r)))}function L(e,t,n){let r=new i.PNG({width:t,height:n});for(let i=0;i<n;i+=1){let a=i*e.height/n,o=(i+1)*e.height/n;for(let n=0;n<t;n+=1){let s=n*e.width/t,c=(n+1)*e.width/t,l=0,u=0,d=0,f=0,p=0;for(let t=Math.floor(a);t<Math.ceil(o);t+=1){let n=Math.min(t+1,o)-Math.max(t,a);for(let r=Math.floor(s);r<Math.ceil(c);r+=1){let i=n*(Math.min(r+1,c)-Math.max(r,s)),a=(t*e.width+r)*4;l+=(e.data[a]??0)*i,u+=(e.data[a+1]??0)*i,d+=(e.data[a+2]??0)*i,f+=(e.data[a+3]??0)*i,p+=i}}let m=(i*r.width+n)*4;r.data[m]=Math.round(l/p),r.data[m+1]=Math.round(u/p),r.data[m+2]=Math.round(d/p),r.data[m+3]=Math.round(f/p)}}return r}export{j as a,A as c,P as i,F as n,M as o,N as r,k as s,I as t};
1
+ import{A as e,_ as t}from"./sdk-contracts.js";import{b as n}from"./location-coordinates.js";import{A as r}from"./sdk-android-adb.js";import{a as i,i as a,n as o,r as s,t as c}from"./png-worker-contract.js";import l from"node:path";import u,{promises as d}from"node:fs";import{fileURLToPath as f}from"node:url";import{Worker as p}from"node:worker_threads";function m(e,t){try{let n=f(e),r=l.extname(n)||`.js`;return[l.join(l.dirname(n),`${t}${r}`),l.join(l.dirname(n),`internal`,`${t}${r}`)].find(e=>u.existsSync(e))??null}catch{return null}}var h=class extends Error{};let g=null,_=!1,v=!1,y=0;const b=new Map;function x(e){_=!0,!v&&(v=!0,r({level:`warn`,phase:`png_worker_unavailable`,data:{reason:e}}),process.emitWarning(`PNG worker unavailable, falling back to in-process PNG processing: ${e}`))}function S(n){let r=b.get(n.id);r&&(b.delete(n.id),T(),n.ok?r.resolve(n.result):r.reject(new t(e(n.error.code),n.error.message,n.error.details)))}function C(e,t){g===e&&(x(t.message),g=null,e.terminate().catch(()=>{}),w(new h(`PNG worker failed: ${t.message}`)))}function w(e){let t=[...b.values()];b.clear();for(let n of t)n.reject(e)}function T(){g&&(b.size>0?g.ref():g.unref())}function E(){if(_)return null;if(g)return g;let e=m(import.meta.url,`png-worker`);if(!e)return x(`worker entry module not found next to the current module`),null;try{let t=new p(e,{execArgv:e.endsWith(`.ts`)?[`--experimental-strip-types`]:[]});return t.on(`message`,S),t.on(`error`,e=>{C(t,e)}),t.on(`exit`,e=>{C(t,Error(`PNG worker exited with code ${e}`))}),t.unref(),g=t,t}catch(e){return x(`failed to spawn worker: ${e instanceof Error?e.message:String(e)}`),null}}function D(e){let t=E();if(!t)return Promise.reject(new h(`PNG worker is unavailable`));y+=1;let n=y;return new Promise((r,i)=>{b.set(n,{resolve:r,reject:i}),T();try{t.postMessage({...e,id:n})}catch(e){b.delete(n),T(),i(new h(`failed to post job to PNG worker: ${e instanceof Error?e.message:String(e)}`))}})}async function O(e,t){try{return await D(e)}catch(e){if(e instanceof h)return t();throw e}}function k(){E()}async function A(){let e=g;g=null,w(new h(`PNG worker terminated`)),e&&await e.terminate()}async function j(e,t){let n=await O({kind:`decode`,png:e,label:t},()=>{let n=a(e,t);return{kind:`decode`,width:n.width,height:n.height,data:n.data}}),r=new i.PNG({width:n.width,height:n.height});return r.data=c(n.data),r}async function M(e){return c((await O({kind:`encode`,width:e.width,height:e.height,data:e.data},()=>({kind:`encode`,png:i.PNG.sync.write(e)}))).png)}async function N(e,t,n){let{kind:r,...i}=await O({kind:`rgb-difference`,firstPng:e,secondPng:t,label:n},()=>({kind:`rgb-difference`,...o(a(e,n),a(t,n))}));return i}async function P(e){let{kind:t,...n}=await O({kind:`diff-pixels`,...e},()=>({kind:`diff-pixels`,...s(e)}));return{...n,diffData:c(n.diffData)}}async function F(e,r){let{min:i,max:a}=n;if(!Number.isFinite(r)||r<i||r>a)throw new t(`INVALID_ARGS`,`Screenshot scale must be between ${i} and ${a}`);if(r===1)return;let o=await j(await d.readFile(e),`screenshot`),s=Math.max(1,Math.round(o.width*r)),c=Math.max(1,Math.round(o.height*r));await d.writeFile(e,await M(L(o,s,c)))}async function I(e,n,r){if(!Number.isInteger(n)||n<1||!Number.isInteger(r)||r<1)throw new t(`INVALID_ARGS`,`Screenshot resize dimensions must be positive integers`);let i=await j(await d.readFile(e),`screenshot`);i.width===n&&i.height===r||await d.writeFile(e,await M(L(i,n,r)))}function L(e,t,n){let r=new i.PNG({width:t,height:n});for(let i=0;i<n;i+=1){let a=i*e.height/n,o=(i+1)*e.height/n;for(let n=0;n<t;n+=1){let s=n*e.width/t,c=(n+1)*e.width/t,l=0,u=0,d=0,f=0,p=0;for(let t=Math.floor(a);t<Math.ceil(o);t+=1){let n=Math.min(t+1,o)-Math.max(t,a);for(let r=Math.floor(s);r<Math.ceil(c);r+=1){let i=n*(Math.min(r+1,c)-Math.max(r,s)),a=(t*e.width+r)*4;l+=(e.data[a]??0)*i,u+=(e.data[a+1]??0)*i,d+=(e.data[a+2]??0)*i,f+=(e.data[a+3]??0)*i,p+=i}}let m=(i*r.width+n)*4;r.data[m]=Math.round(l/p),r.data[m+1]=Math.round(u/p),r.data[m+2]=Math.round(d/p),r.data[m+3]=Math.round(f/p)}}return r}export{j as a,A as c,P as i,F as n,M as o,N as r,k as s,I as t};
@@ -1 +1 @@
1
- import{n as e}from"./rolldown-runtime.js";import{_ as t}from"./sdk-contracts.js";import{Br as n,Ot as r}from"./sdk-batch-runner.js";import{A as i,_ as a,f as o}from"./sdk-android-adb.js";import{t as s}from"./timeouts.js";import{t as c}from"./scoped-provider.js";import{i as l,n as ee,o as te,r as ne}from"./agent-browser-tool.js";function u(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function d(e,t){return u(e)?e[t]:void 0}function f(e,t){let n=d(e,t);return typeof n==`string`?n:void 0}function re(e,t){let n=d(e,t);return typeof n==`boolean`?n:void 0}function p(e,t){let n=e[t];return typeof n==`number`&&Number.isFinite(n)?n:void 0}const ie=[h,g,_,v,y,b,x,S,C,w,T,E,D,O,k,A,j];function ae(e){let t=ie.map(e=>`${e.toString()};`).join(``),n=se(e.action),r=m(e.durationMs),i=m(e.bucketMs);return`(()=>{${t}return ${j.name}({action:${n},durationMs:${r},bucketMs:${i}})})()`}function oe(e){let t=r(ce(e),{source:`media-elements`,backend:`agent-browser`,durationMs:0,elapsedMs:0,bucketMs:1e3,activeFallback:!1,mediaElementCount:0,sourceCount:0});return{...t,source:`media-elements`,mediaElementCount:t.mediaElementCount??0}}function se(e){switch(e){case`start`:return`'start'`;case`stop`:return`'stop'`;default:return`'status'`}}function m(e){return e===void 0||!Number.isFinite(e)?`undefined`:String(Math.trunc(e))}function h(e){return!Number.isFinite(e)||e<=0?-90:Math.max(-90,Math.min(0,Math.round(20*Math.log10(e))))}function g(e,t){e.notes.includes(t)||e.notes.push(t)}function _(){return Array.from(document.querySelectorAll(`audio,video`))}function v(e,t){if(!e||e.state===`stopped`)return e;clearInterval(e.timer),clearTimeout(e.timeout),e.timer=void 0,e.timeout=void 0,e.state=`stopped`,e.active=!1,e.reason=t,e.stoppedAt=Date.now();for(let t of e.analysers)try{t.analyser.disconnect(),t.source.disconnect(),t.audible&&t.source.connect(e.context.destination)}catch{}if(e.resumeOnGesture){for(let t of[`click`,`pointerdown`,`keydown`])window.removeEventListener(t,e.resumeOnGesture,!0);e.resumeOnGesture=void 0}return e}function y(e){let t=window.AudioContext||window.webkitAudioContext;if(!t)return;let n=window[e];if(n&&n.state!==`closed`)return n;let r=new t;return window[e]=r,r}function b(e,t,n){if(!(!t.currentSrc&&!t.src&&t.readyState===0))try{window[n]||(window[n]=new WeakMap);let r=window[n].get(t);return r||(r=e.context.createMediaElementSource(t),window[n].set(t,r)),r.disconnect(),{source:r,audible:!0}}catch{return}}function x(e,t){if(!(!t||typeof t.getAudioTracks!=`function`)&&t.getAudioTracks().length!==0)return{source:e.context.createMediaStreamSource(t),audible:!1}}function S(e,t){if(typeof t.captureStream==`function`)return x(e,t.captureStream())}function C(e,t){let n=e.context.createAnalyser();n.fftSize=2048,t.source.connect(n),n.connect(t.audible?e.context.destination:e.sink),e.analysers.push({...t,analyser:n,buffer:new Float32Array(n.fftSize)})}function w(e,t){let n=_();e.mediaElementCount=n.length;for(let r of n){if(e.seen.has(r))continue;let n=x(e,r.srcObject)??S(e,r)??b(e,r,t);if(!n){g(e,`Some media elements do not expose capturable audio to Web Audio.`);continue}e.seen.add(r),C(e,n)}e.sourceCount=e.analysers.length,e.sourceCount===0&&g(e,`No capturable page media audio sources were found yet.`)}function T(e){let t=0,n=0,r=0;for(let i of e.analysers){i.analyser.getFloatTimeDomainData(i.buffer);for(let e of i.buffer)t+=e*e,n+=1,r=Math.max(r,Math.abs(e))}return{rms:n>0?Math.sqrt(t/n):0,peak:r}}function E(e){let t=Math.ceil(e.durationMs/e.bucketMs)+2;e.rmsDbfs.length>t&&e.rmsDbfs.splice(0,e.rmsDbfs.length-t),e.peakDbfs.length>t&&e.peakDbfs.splice(0,e.peakDbfs.length-t)}function D(e,t){if(!e||e.state!==`running`)return;w(e,t);let n=T(e),r=h(n.rms),i=h(n.peak);e.rmsDbfs.push(r),e.peakDbfs.push(i),e.heard=e.heard||r>-90||i>-90,E(e),Date.now()-e.startedAt>=e.durationMs&&v(e,`duration`)}function O(e,t){return{audio:`probe`,state:`stopped`,active:!1,heard:!1,source:`media-elements`,backend:`agent-browser`,durationMs:Number(e.durationMs)||1e4,elapsedMs:0,bucketMs:Number(e.bucketMs)||1e3,sampleCount:0,mediaElementCount:_().length,sourceCount:0,rmsDbfs:[],peakDbfs:[],notes:t}}function k(e,t,n,r){return e?{audio:`probe`,state:e.state,active:e.state===`running`,heard:e.heard,source:`media-elements`,backend:`agent-browser`,durationMs:e.durationMs,elapsedMs:Math.max(0,Math.min((e.stoppedAt||Date.now())-e.startedAt,e.durationMs)),bucketMs:e.bucketMs,sampleCount:e.rmsDbfs.length,mediaElementCount:_().length,sourceCount:e.sourceCount,rmsDbfs:e.rmsDbfs.slice(),peakDbfs:e.peakDbfs.slice(),startedAt:new Date(e.startedAt).toISOString(),stoppedAt:e.stoppedAt?new Date(e.stoppedAt).toISOString():void 0,reason:e.reason,notes:[n,r,...e.notes]}:O(t,[n,r])}function A(e,t,n,r,i,a,o){t&&v(t,`restarted`);let s=y(r);if(!s)return O(e,[`Web Audio API is not available in this browser context.`]);let c=s.createGain();c.gain.value=0,c.connect(s.destination);let l={state:`running`,active:!0,context:s,sink:c,seen:new WeakSet,analysers:[],mediaElementCount:0,sourceCount:0,durationMs:Math.max(100,Number(e.durationMs)||1e4),bucketMs:Math.max(100,Number(e.bucketMs)||1e3),startedAt:Date.now(),stoppedAt:void 0,reason:void 0,heard:!1,rmsDbfs:[],peakDbfs:[],notes:[]};try{s.resume()}catch{g(l,`AudioContext could not be resumed by the probe.`)}l.resumeOnGesture=()=>{try{s.resume()}catch{g(l,`AudioContext could not be resumed from a user gesture.`)}};for(let e of[`click`,`pointerdown`,`keydown`])window.addEventListener(e,l.resumeOnGesture,{capture:!0,once:!0});return w(l,i),l.timer=setInterval(()=>D(l,i),l.bucketMs),l.timeout=setTimeout(()=>v(l,`duration`),l.durationMs),window[n]=l,k(l,e,a,o)}function j(e){let t=`__agentDeviceAudioProbe`,n=`__agentDeviceAudioProbeSources`,r=`Audio probe samples HTML media elements exposed to Web Audio; it is not whole-tab or system audio capture.`,i=`URL-backed media elements may be routed through the probe AudioContext while they are observed.`,a=window[t];return a&&a.state===`running`&&Date.now()-a.startedAt>=a.durationMs&&(D(a,n),v(a,`duration`)),e.action===`start`?A(e,a,t,`__agentDeviceAudioProbeContext`,n,r,i):e.action===`stop`?(a&&D(a,n),v(a,`manual`),k(a,e,r,i)):(a&&D(a,n),k(a,e,r,i))}function ce(e){return u(e)?u(e.result)?e.result:e:{}}function le(e,t={}){let n=ue(e),r=me(t.limit),i=t.include===`headers`||t.include===`all`,a=n.slice(-r).reverse().map(e=>fe(e,i)),o=t.include===`body`||t.include===`all`?[`agent-browser network requests does not expose request or response bodies.`]:void 0;return{entries:a,backend:`agent-browser`,redacted:!1,...o?{notes:o}:{}}}function ue(e){let t=u(e)&&Array.isArray(e.requests)?e.requests:e;return Array.isArray(t)?t.filter(de).map(e=>({headers:M(e.headers),method:f(e,`method`),mimeType:f(e,`mimeType`),requestId:f(e,`requestId`),resourceType:f(e,`resourceType`),responseHeaders:M(e.responseHeaders),status:p(e,`status`),timestamp:pe(e.timestamp),url:f(e,`url`)})):[]}function de(e){return u(e)}function fe(e,t){let r=e.timestamp===void 0?void 0:N(e.timestamp),i=n({requestId:e.requestId,resourceType:e.resourceType,mimeType:e.mimeType});return n({timestamp:r,method:e.method,url:e.url,status:e.status,requestHeaders:t?e.headers:void 0,responseHeaders:t?e.responseHeaders:void 0,metadata:Object.keys(i).length>0?i:void 0})}function M(e){if(!u(e))return;let t={};for(let[n,r]of Object.entries(e))typeof r==`string`&&(t[n]=r);return Object.keys(t).length>0?t:void 0}function pe(e){if(typeof e==`number`||typeof e==`string`)return e}function N(e){if(typeof e==`string`){let t=Number(e);return Number.isFinite(t)?N(t):e}let t=e>1e10?e:e*1e3,n=new Date(t);return Number.isNaN(n.getTime())?String(e):n.toISOString()}function me(e){return typeof e!=`number`||!Number.isInteger(e)?25:Math.max(1,Math.min(e,200))}async function he(e,t){let n=P(f(e,`snapshot`)??``,L(d(e,`refs`)));return t&&await ge(n,t),{nodes:n.map((e,t)=>({...e.node,index:t})),truncated:re(e,`truncated`)}}async function ge(e,t){for(let n=0;n<e.length;n+=8){let r=e.slice(n,n+8),i=await Promise.all(r.map(e=>t(e.ref)));for(let[e,t]of i.entries())t&&(r[e].node.rect=t)}}function P(e,t){let n=new Map(t.map(e=>[e.ref,e])),r=[],i=new Set,a=new Map;for(let t of e.split(/\r?\n/)){let e=ye(t);if(!e)continue;i.add(e);let o=n.get(e)?.data,s=_e(t),c=F(t,o,s),l=ve(a,s);l!==void 0&&(c.parentIndex=l),r.push({ref:e,node:{...c,index:r.length}}),a.set(s,r.length-1)}for(let e of t)i.has(e.ref)||r.push({ref:e.ref,node:{...I(e.data),index:r.length}});return r}function F(e,t,n){let r=be(e)??z(t,[`role`,`type`]);return{index:0,type:r,role:r,label:xe(e)??z(t,[`label`,`name`,`text`]),value:Se(e)??z(t,[`value`]),depth:n,enabled:B(t,[`enabled`]),focused:B(t,[`focused`])}}function I(e){let t=z(e,[`role`,`type`]);return{index:0,type:t,role:t,label:z(e,[`label`,`name`,`text`]),value:z(e,[`value`]),enabled:B(e,[`enabled`]),focused:B(e,[`focused`])}}function L(e){return Array.isArray(e)?e.flatMap(e=>{let t=u(e)?e:void 0,n=R(z(t,[`ref`,`id`])??String(e));return n?[{ref:n,data:t}]:[]}):u(e)?Object.entries(e).flatMap(([e,t])=>{let n=R(e);return n?[{ref:n,data:u(t)?t:void 0}]:[]}):[]}function _e(e){let t=e.match(/^\s*/)?.[0].length??0;return Math.floor(t/2)}function ve(e,t){for(let n=t-1;n>=0;--n){let t=e.get(n);if(t!==void 0)return t}}function ye(e){return R(e.match(/\bref=['"]?(@?e\d+)['"]?/i)?.[1]??e.match(/@?(e\d+)\b/i)?.[1])}function R(e){let t=e?.trim().replace(/^@/,``);return t&&/^e\d+$/i.test(t)?t.toLowerCase():null}function be(e){return e.replace(/\[[^\]]*ref[^\]]*\]/gi,``).replace(/@?e\d+\b/gi,``).replace(/^[\s|├└─>*-]+/g,``).trim().match(/^([A-Za-z][\w-]*)\b/)?.[1]}function xe(e){return e.match(/"([^"]+)"/)?.[1]??e.match(/'([^']+)'/)?.[1]}function Se(e){return Ce(e)??e.match(/\bvalue=(?:"([^"]*)"|'([^']*)'|([^\s\]]+))/i)?.slice(1).find(V)??e.match(/\bvalue:\s*(?:"([^"]*)"|'([^']*)'|([^\s\]]+))/i)?.slice(1).find(V)}function Ce(e){return e.match(/\]\s*:\s*(.+)$/)?.[1]?.trim()||void 0}function z(e,t){if(e)for(let n of t){let t=e[n];if(typeof t==`string`&&t.length>0)return t}}function B(e,t){if(e)for(let n of t){let t=e[n];if(typeof t==`boolean`)return t}}function V(e){return typeof e==`string`}const H=`agent-browser`,U="Run `agent-device web setup` to install the managed web backend.";function W(e={}){let t=e.session?.trim(),n=async(n,r)=>await Ne(n,{session:t,options:e,signal:r});return{async open(e){await n([`open`,e])},async close(){await n([`close`])},async startRecording(e){await n([`record`,`start`,e])},async stopRecording(){await n([`record`,`stop`])},async snapshot(e){return await ke(t=>n(t,e?.signal),e)},async screenshot(e,t){await n([`screenshot`,...t?.fullscreen?[`--full`]:[],e])},async setViewport(e,t){await n([`set`,`viewport`,String(e),String(t)])},async click(e,t){await G(n,e,t)},async clickRef(e){await n([`click`,q(e)])},async fill(e,t,r){await G(n,e,t),await n([`press`,Ve()]),await n([`keyboard`,`type`,r])},async fillRef(e,t){await n([`fill`,q(e),t])},async typeText(e){await n([`keyboard`,`type`,e])},async scroll(e,t){return await we(n,e,t),t?.durationMs===void 0?{}:{durationMs:t.durationMs}},async dumpNetwork(e){return le(await n([`network`,`requests`]),e)},async probeAudio(e){return oe(await n([`eval`,ae(e)]))}}}async function we(e,t,n){let r=Te(n);for(let n of r)await e(Oe(t,n.distance)),n.delayAfterMs>0&&await s(n.delayAfterMs)}function Te(e){let t=e?.pixels??e?.amount,n=e?.durationMs;if(n===void 0||n<=0)return[{distance:t,delayAfterMs:0}];let r=Math.max(1,Math.min(20,Math.ceil(n/50))),i=n/Math.max(1,r-1);return Ee(e,r).map((e,t)=>({distance:e,delayAfterMs:t<r-1?i:0}))}function Ee(e,t){let n=e?.pixels??e?.amount??300;return e?.amount!==void 0&&e.pixels===void 0?Array.from({length:t},()=>n/t):De(Math.round(n),t)}function De(e,t){let n=Math.floor(e/t),r=e-n*t;return Array.from({length:t},(e,t)=>t<r?n+1:n)}function Oe(e,t){return[`scroll`,e,...t===void 0?[]:[String(t)]]}async function G(e,t,n){await e([`mouse`,`move`,String(Math.round(t)),String(Math.round(n))]),await e([`mouse`,`down`]),await e([`mouse`,`up`])}async function ke(e,t){return await he(await e(Ae(t)),t?.includeRects?async t=>await je(e,t):void 0)}function Ae(e){return[`snapshot`,...e?.interactiveOnly?[`--interactive`]:[],...e?.raw?[]:[`--compact`],...typeof e?.depth==`number`?[`--depth`,String(e.depth)]:[],...e?.scope?[`--selector`,e.scope]:[]]}async function je(e,t){try{return He(await e([`get`,`box`,q(t)]))}catch(e){if(Me(e))return;throw e}}function Me(e){let t=e instanceof Error?e.message:String(e);return!/\bstale\b/i.test(t)&&/\bbox\b|not visible|not found|no element/i.test(t)}async function Ne(e,t){let{session:n,options:r,signal:i}=t,a=[...e,`--json`,...n?[`--session`,n]:[]],o=await Pe(a,r,i);return Ie(Le(o.stdout,o.stderr,a,o.exitCode),o,a)}async function Pe(e,t,n){let r=``,i=``,o=0;try{await Fe(t);let s=await l({stateDir:t.stateDir}),c=await a(s.command,e,{allowFailure:!0,env:s.env,timeoutMs:3e4,signal:n});r=c.stdout,i=c.stderr,o=c.exitCode}catch(t){throw Re(t,e)}return{stdout:r,stderr:i,exitCode:o}}async function Fe(e){if(!e.openWebSessionNames)return;let t=ee({stateDir:e.stateDir});if(t.installed)try{await te(t,{openWebSessionNames:e.openWebSessionNames()})}catch(e){i({level:`warn`,phase:`web_agent_browser_provider_orphan_cleanup_failed`,data:{error:e instanceof Error?e.message:String(e)}})}}function Ie(e,n,r){if(!u(e))return e;if((e.success??e.ok)===!1)throw new t(Be(e.code),ze(e),{cmd:H,args:r,hint:f(e,`hint`)??U,agentBrowserError:e.error});if(n.exitCode!==0)throw new t(`COMMAND_FAILED`,`agent-browser command failed`,o(n,{cmd:H,args:r,stdout:n.stdout.slice(0,500),stderr:n.stderr.slice(0,500),hint:f(e,`hint`)??U}));return Object.hasOwn(e,`data`)?e.data:e}function Le(e,n,r,i){try{return JSON.parse(e)}catch(a){let o=i!==0;throw new t(`COMMAND_FAILED`,o?`agent-browser command failed`:`agent-browser returned invalid JSON`,{cmd:H,args:r,...o?{exitCode:i}:{},stdout:e.slice(0,500),stderr:n.slice(0,500),hint:U},a instanceof Error?a:void 0)}}function Re(e,n){let r=ne(e);return r.code===`TOOL_MISSING`?new t(`TOOL_MISSING`,r.message,{...r.details??{},cmd:H,args:n,hint:K(r)},r):r.code===`COMMAND_FAILED`?new t(`COMMAND_FAILED`,r.message,{...r.details??{},cmd:H,args:n,hint:K(r)},r):r}function K(e){return typeof e.details?.hint==`string`?e.details.hint:U}function ze(e){let t=e.error;if(typeof t==`string`&&t.trim())return t.trim();if(u(t)){let e=f(t,`message`)??f(t,`error`);if(e)return e}return f(e,`message`)??`agent-browser command failed`}function Be(e){return typeof e==`string`&&e.length>0?e:`COMMAND_FAILED`}function q(e){return e.startsWith(`@`)?e:`@${e}`}function Ve(){return process.platform===`darwin`?`Meta+a`:`Control+a`}function He(e){let t=u(e)&&u(e.box)?e.box:e;if(u(t))return J(t)??Ue(t)}function J(e){return Y(p(e,`x`),p(e,`y`),p(e,`width`),p(e,`height`))}function Ue(e){let t=p(e,`left`),n=p(e,`top`),r=p(e,`right`),i=p(e,`bottom`);return Y(t,n,X(r,t),X(i,n))}function Y(e,t,n,r){if(!(e===void 0||t===void 0||n===void 0||r===void 0))return{x:e,y:t,width:n,height:r}}function X(e,t){return e===void 0||t===void 0?void 0:e-t}var We=e({hasScopedWebProvider:()=>Ge,resolveWebProvider:()=>Q,withWebProvider:()=>$});const Z=c(W());function Q(e){return Z.resolve(e)}function Ge(){return Z.hasScope()}async function $(e,t){return await Z.run(e,t)}export{W as i,Q as n,$ as r,We as t};
1
+ import{n as e}from"./rolldown-runtime.js";import{_ as t}from"./sdk-contracts.js";import{Jr as n,Pt as r}from"./sdk-batch-runner.js";import{A as i,_ as a,f as o}from"./sdk-android-adb.js";import{t as s}from"./timeouts.js";import{t as c}from"./scoped-provider.js";import{i as l,n as ee,o as te,r as ne}from"./agent-browser-tool.js";function u(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function d(e,t){return u(e)?e[t]:void 0}function f(e,t){let n=d(e,t);return typeof n==`string`?n:void 0}function re(e,t){let n=d(e,t);return typeof n==`boolean`?n:void 0}function p(e,t){let n=e[t];return typeof n==`number`&&Number.isFinite(n)?n:void 0}const ie=[h,g,_,v,y,b,x,S,C,w,T,E,D,O,k,A,j];function ae(e){let t=ie.map(e=>`${e.toString()};`).join(``),n=se(e.action),r=m(e.durationMs),i=m(e.bucketMs);return`(()=>{${t}return ${j.name}({action:${n},durationMs:${r},bucketMs:${i}})})()`}function oe(e){let t=r(ce(e),{source:`media-elements`,backend:`agent-browser`,durationMs:0,elapsedMs:0,bucketMs:1e3,activeFallback:!1,mediaElementCount:0,sourceCount:0});return{...t,source:`media-elements`,mediaElementCount:t.mediaElementCount??0}}function se(e){switch(e){case`start`:return`'start'`;case`stop`:return`'stop'`;default:return`'status'`}}function m(e){return e===void 0||!Number.isFinite(e)?`undefined`:String(Math.trunc(e))}function h(e){return!Number.isFinite(e)||e<=0?-90:Math.max(-90,Math.min(0,Math.round(20*Math.log10(e))))}function g(e,t){e.notes.includes(t)||e.notes.push(t)}function _(){return Array.from(document.querySelectorAll(`audio,video`))}function v(e,t){if(!e||e.state===`stopped`)return e;clearInterval(e.timer),clearTimeout(e.timeout),e.timer=void 0,e.timeout=void 0,e.state=`stopped`,e.active=!1,e.reason=t,e.stoppedAt=Date.now();for(let t of e.analysers)try{t.analyser.disconnect(),t.source.disconnect(),t.audible&&t.source.connect(e.context.destination)}catch{}if(e.resumeOnGesture){for(let t of[`click`,`pointerdown`,`keydown`])window.removeEventListener(t,e.resumeOnGesture,!0);e.resumeOnGesture=void 0}return e}function y(e){let t=window.AudioContext||window.webkitAudioContext;if(!t)return;let n=window[e];if(n&&n.state!==`closed`)return n;let r=new t;return window[e]=r,r}function b(e,t,n){if(!(!t.currentSrc&&!t.src&&t.readyState===0))try{window[n]||(window[n]=new WeakMap);let r=window[n].get(t);return r||(r=e.context.createMediaElementSource(t),window[n].set(t,r)),r.disconnect(),{source:r,audible:!0}}catch{return}}function x(e,t){if(!(!t||typeof t.getAudioTracks!=`function`)&&t.getAudioTracks().length!==0)return{source:e.context.createMediaStreamSource(t),audible:!1}}function S(e,t){if(typeof t.captureStream==`function`)return x(e,t.captureStream())}function C(e,t){let n=e.context.createAnalyser();n.fftSize=2048,t.source.connect(n),n.connect(t.audible?e.context.destination:e.sink),e.analysers.push({...t,analyser:n,buffer:new Float32Array(n.fftSize)})}function w(e,t){let n=_();e.mediaElementCount=n.length;for(let r of n){if(e.seen.has(r))continue;let n=x(e,r.srcObject)??S(e,r)??b(e,r,t);if(!n){g(e,`Some media elements do not expose capturable audio to Web Audio.`);continue}e.seen.add(r),C(e,n)}e.sourceCount=e.analysers.length,e.sourceCount===0&&g(e,`No capturable page media audio sources were found yet.`)}function T(e){let t=0,n=0,r=0;for(let i of e.analysers){i.analyser.getFloatTimeDomainData(i.buffer);for(let e of i.buffer)t+=e*e,n+=1,r=Math.max(r,Math.abs(e))}return{rms:n>0?Math.sqrt(t/n):0,peak:r}}function E(e){let t=Math.ceil(e.durationMs/e.bucketMs)+2;e.rmsDbfs.length>t&&e.rmsDbfs.splice(0,e.rmsDbfs.length-t),e.peakDbfs.length>t&&e.peakDbfs.splice(0,e.peakDbfs.length-t)}function D(e,t){if(!e||e.state!==`running`)return;w(e,t);let n=T(e),r=h(n.rms),i=h(n.peak);e.rmsDbfs.push(r),e.peakDbfs.push(i),e.heard=e.heard||r>-90||i>-90,E(e),Date.now()-e.startedAt>=e.durationMs&&v(e,`duration`)}function O(e,t){return{audio:`probe`,state:`stopped`,active:!1,heard:!1,source:`media-elements`,backend:`agent-browser`,durationMs:Number(e.durationMs)||1e4,elapsedMs:0,bucketMs:Number(e.bucketMs)||1e3,sampleCount:0,mediaElementCount:_().length,sourceCount:0,rmsDbfs:[],peakDbfs:[],notes:t}}function k(e,t,n,r){return e?{audio:`probe`,state:e.state,active:e.state===`running`,heard:e.heard,source:`media-elements`,backend:`agent-browser`,durationMs:e.durationMs,elapsedMs:Math.max(0,Math.min((e.stoppedAt||Date.now())-e.startedAt,e.durationMs)),bucketMs:e.bucketMs,sampleCount:e.rmsDbfs.length,mediaElementCount:_().length,sourceCount:e.sourceCount,rmsDbfs:e.rmsDbfs.slice(),peakDbfs:e.peakDbfs.slice(),startedAt:new Date(e.startedAt).toISOString(),stoppedAt:e.stoppedAt?new Date(e.stoppedAt).toISOString():void 0,reason:e.reason,notes:[n,r,...e.notes]}:O(t,[n,r])}function A(e,t,n,r,i,a,o){t&&v(t,`restarted`);let s=y(r);if(!s)return O(e,[`Web Audio API is not available in this browser context.`]);let c=s.createGain();c.gain.value=0,c.connect(s.destination);let l={state:`running`,active:!0,context:s,sink:c,seen:new WeakSet,analysers:[],mediaElementCount:0,sourceCount:0,durationMs:Math.max(100,Number(e.durationMs)||1e4),bucketMs:Math.max(100,Number(e.bucketMs)||1e3),startedAt:Date.now(),stoppedAt:void 0,reason:void 0,heard:!1,rmsDbfs:[],peakDbfs:[],notes:[]};try{s.resume()}catch{g(l,`AudioContext could not be resumed by the probe.`)}l.resumeOnGesture=()=>{try{s.resume()}catch{g(l,`AudioContext could not be resumed from a user gesture.`)}};for(let e of[`click`,`pointerdown`,`keydown`])window.addEventListener(e,l.resumeOnGesture,{capture:!0,once:!0});return w(l,i),l.timer=setInterval(()=>D(l,i),l.bucketMs),l.timeout=setTimeout(()=>v(l,`duration`),l.durationMs),window[n]=l,k(l,e,a,o)}function j(e){let t=`__agentDeviceAudioProbe`,n=`__agentDeviceAudioProbeSources`,r=`Audio probe samples HTML media elements exposed to Web Audio; it is not whole-tab or system audio capture.`,i=`URL-backed media elements may be routed through the probe AudioContext while they are observed.`,a=window[t];return a&&a.state===`running`&&Date.now()-a.startedAt>=a.durationMs&&(D(a,n),v(a,`duration`)),e.action===`start`?A(e,a,t,`__agentDeviceAudioProbeContext`,n,r,i):e.action===`stop`?(a&&D(a,n),v(a,`manual`),k(a,e,r,i)):(a&&D(a,n),k(a,e,r,i))}function ce(e){return u(e)?u(e.result)?e.result:e:{}}function le(e,t={}){let n=ue(e),r=me(t.limit),i=t.include===`headers`||t.include===`all`,a=n.slice(-r).reverse().map(e=>fe(e,i)),o=t.include===`body`||t.include===`all`?[`agent-browser network requests does not expose request or response bodies.`]:void 0;return{entries:a,backend:`agent-browser`,redacted:!1,...o?{notes:o}:{}}}function ue(e){let t=u(e)&&Array.isArray(e.requests)?e.requests:e;return Array.isArray(t)?t.filter(de).map(e=>({headers:M(e.headers),method:f(e,`method`),mimeType:f(e,`mimeType`),requestId:f(e,`requestId`),resourceType:f(e,`resourceType`),responseHeaders:M(e.responseHeaders),status:p(e,`status`),timestamp:pe(e.timestamp),url:f(e,`url`)})):[]}function de(e){return u(e)}function fe(e,t){let r=e.timestamp===void 0?void 0:N(e.timestamp),i=n({requestId:e.requestId,resourceType:e.resourceType,mimeType:e.mimeType});return n({timestamp:r,method:e.method,url:e.url,status:e.status,requestHeaders:t?e.headers:void 0,responseHeaders:t?e.responseHeaders:void 0,metadata:Object.keys(i).length>0?i:void 0})}function M(e){if(!u(e))return;let t={};for(let[n,r]of Object.entries(e))typeof r==`string`&&(t[n]=r);return Object.keys(t).length>0?t:void 0}function pe(e){if(typeof e==`number`||typeof e==`string`)return e}function N(e){if(typeof e==`string`){let t=Number(e);return Number.isFinite(t)?N(t):e}let t=e>1e10?e:e*1e3,n=new Date(t);return Number.isNaN(n.getTime())?String(e):n.toISOString()}function me(e){return typeof e!=`number`||!Number.isInteger(e)?25:Math.max(1,Math.min(e,200))}async function he(e,t){let n=_e(f(e,`snapshot`)??``,I(d(e,`refs`)));return t&&await ge(n,t),{nodes:n.map((e,t)=>({...e.node,index:t})),truncated:re(e,`truncated`)}}async function ge(e,t){for(let n=0;n<e.length;n+=8){let r=e.slice(n,n+8),i=await Promise.all(r.map(e=>t(e.ref)));for(let[e,t]of i.entries())t&&(r[e].node.rect=t)}}function _e(e,t){let n=new Map(t.map(e=>[e.ref,e])),r=[],i=new Set,a=new Map;for(let t of e.split(/\r?\n/)){let e=be(t);if(!e)continue;i.add(e);let o=n.get(e)?.data,s=ve(t),c=P(t,o,s),l=ye(a,s);l!==void 0&&(c.parentIndex=l),r.push({ref:e,node:{...c,index:r.length}}),a.set(s,r.length-1)}for(let e of t)i.has(e.ref)||r.push({ref:e.ref,node:{...F(e.data),index:r.length}});return r}function P(e,t,n){let r=xe(e)??R(t,[`role`,`type`]);return{index:0,type:r,role:r,label:Se(e)??R(t,[`label`,`name`,`text`]),value:Ce(e)??R(t,[`value`]),depth:n,enabled:z(t,[`enabled`]),focused:z(t,[`focused`])}}function F(e){let t=R(e,[`role`,`type`]);return{index:0,type:t,role:t,label:R(e,[`label`,`name`,`text`]),value:R(e,[`value`]),enabled:z(e,[`enabled`]),focused:z(e,[`focused`])}}function I(e){return Array.isArray(e)?e.flatMap(e=>{let t=u(e)?e:void 0,n=L(R(t,[`ref`,`id`])??String(e));return n?[{ref:n,data:t}]:[]}):u(e)?Object.entries(e).flatMap(([e,t])=>{let n=L(e);return n?[{ref:n,data:u(t)?t:void 0}]:[]}):[]}function ve(e){let t=e.match(/^\s*/)?.[0].length??0;return Math.floor(t/2)}function ye(e,t){for(let n=t-1;n>=0;--n){let t=e.get(n);if(t!==void 0)return t}}function be(e){return L(e.match(/\bref=['"]?(@?e\d+)['"]?/i)?.[1]??e.match(/@?(e\d+)\b/i)?.[1])}function L(e){let t=e?.trim().replace(/^@/,``);return t&&/^e\d+$/i.test(t)?t.toLowerCase():null}function xe(e){return e.replace(/\[[^\]]*ref[^\]]*\]/gi,``).replace(/@?e\d+\b/gi,``).replace(/^[\s|├└─>*-]+/g,``).trim().match(/^([A-Za-z][\w-]*)\b/)?.[1]}function Se(e){return e.match(/"([^"]+)"/)?.[1]??e.match(/'([^']+)'/)?.[1]}function Ce(e){return we(e)??e.match(/\bvalue=(?:"([^"]*)"|'([^']*)'|([^\s\]]+))/i)?.slice(1).find(B)??e.match(/\bvalue:\s*(?:"([^"]*)"|'([^']*)'|([^\s\]]+))/i)?.slice(1).find(B)}function we(e){return e.match(/\]\s*:\s*(.+)$/)?.[1]?.trim()||void 0}function R(e,t){if(e)for(let n of t){let t=e[n];if(typeof t==`string`&&t.length>0)return t}}function z(e,t){if(e)for(let n of t){let t=e[n];if(typeof t==`boolean`)return t}}function B(e){return typeof e==`string`}const V=`agent-browser`,H="Run `agent-device web setup` to install the managed web backend.";function U(e={}){let t=e.session?.trim(),n=async(n,r)=>await Pe(n,{session:t,options:e,signal:r});return{async open(e){await n([`open`,e])},async close(){await n([`close`])},async startRecording(e){await n([`record`,`start`,e])},async stopRecording(){await n([`record`,`stop`])},async snapshot(e){return await Ae(t=>n(t,e?.signal),e)},async screenshot(e,t){await n([`screenshot`,...t?.fullscreen?[`--full`]:[],e])},async setViewport(e,t){await n([`set`,`viewport`,String(e),String(t)])},async click(e,t){await W(n,e,t)},async hover(e,t){await G(n,e,t)},async hoverRef(e){await n([`hover`,J(e)])},async clickRef(e){await n([`click`,J(e)])},async fill(e,t,r){await W(n,e,t),await n([`press`,Ve()]),await n([`keyboard`,`type`,r])},async fillRef(e,t){await n([`fill`,J(e),t])},async typeText(e){await n([`keyboard`,`type`,e])},async scroll(e,t){return await Te(n,e,t),t?.durationMs===void 0?{}:{durationMs:t.durationMs}},async dumpNetwork(e){return le(await n([`network`,`requests`]),e)},async probeAudio(e){return oe(await n([`eval`,ae(e)]))}}}async function Te(e,t,n){let r=Ee(n);for(let n of r)await e(ke(t,n.distance)),n.delayAfterMs>0&&await s(n.delayAfterMs)}function Ee(e){let t=e?.pixels??e?.amount,n=e?.durationMs;if(n===void 0||n<=0)return[{distance:t,delayAfterMs:0}];let r=Math.max(1,Math.min(20,Math.ceil(n/50))),i=n/Math.max(1,r-1);return De(e,r).map((e,t)=>({distance:e,delayAfterMs:t<r-1?i:0}))}function De(e,t){let n=e?.pixels??e?.amount??300;return e?.amount!==void 0&&e.pixels===void 0?Array.from({length:t},()=>n/t):Oe(Math.round(n),t)}function Oe(e,t){let n=Math.floor(e/t),r=e-n*t;return Array.from({length:t},(e,t)=>t<r?n+1:n)}function ke(e,t){return[`scroll`,e,...t===void 0?[]:[String(t)]]}async function W(e,t,n){await G(e,t,n),await e([`mouse`,`down`]),await e([`mouse`,`up`])}async function G(e,t,n){await e([`mouse`,`move`,String(Math.round(t)),String(Math.round(n))])}async function Ae(e,t){return await he(await e(je(t)),t?.includeRects?async t=>await Me(e,t):void 0)}function je(e){return[`snapshot`,...e?.interactiveOnly?[`--interactive`]:[],...e?.raw?[]:[`--compact`],...typeof e?.depth==`number`?[`--depth`,String(e.depth)]:[],...e?.scope?[`--selector`,e.scope]:[]]}async function Me(e,t){try{return He(await e([`get`,`box`,J(t)]))}catch(e){if(Ne(e))return;throw e}}function Ne(e){let t=e instanceof Error?e.message:String(e);return!/\bstale\b/i.test(t)&&/\bbox\b|not visible|not found|no element/i.test(t)}async function Pe(e,t){let{session:n,options:r,signal:i}=t,a=[...e,`--json`,...n?[`--session`,n]:[]],o=await Fe(a,r,i);return Le(Re(o.stdout,o.stderr,a,o.exitCode),o,a)}async function Fe(e,t,n){let r=``,i=``,o=0;try{await Ie(t);let s=await l({stateDir:t.stateDir}),c=await a(s.command,e,{allowFailure:!0,env:s.env,timeoutMs:3e4,signal:n});r=c.stdout,i=c.stderr,o=c.exitCode}catch(t){throw ze(t,e)}return{stdout:r,stderr:i,exitCode:o}}async function Ie(e){if(!e.openWebSessionNames)return;let t=ee({stateDir:e.stateDir});if(t.installed)try{await te(t,{openWebSessionNames:e.openWebSessionNames()})}catch(e){i({level:`warn`,phase:`web_agent_browser_provider_orphan_cleanup_failed`,data:{error:e instanceof Error?e.message:String(e)}})}}function Le(e,n,r){if(!u(e))return e;if((e.success??e.ok)===!1)throw new t(q(e.code),Be(e),{cmd:V,args:r,hint:f(e,`hint`)??H,agentBrowserError:e.error});if(n.exitCode!==0)throw new t(`COMMAND_FAILED`,`agent-browser command failed`,o(n,{cmd:V,args:r,stdout:n.stdout.slice(0,500),stderr:n.stderr.slice(0,500),hint:f(e,`hint`)??H}));return Object.hasOwn(e,`data`)?e.data:e}function Re(e,n,r,i){try{return JSON.parse(e)}catch(a){let o=i!==0;throw new t(`COMMAND_FAILED`,o?`agent-browser command failed`:`agent-browser returned invalid JSON`,{cmd:V,args:r,...o?{exitCode:i}:{},stdout:e.slice(0,500),stderr:n.slice(0,500),hint:H},a instanceof Error?a:void 0)}}function ze(e,n){let r=ne(e);return r.code===`TOOL_MISSING`?new t(`TOOL_MISSING`,r.message,{...r.details??{},cmd:V,args:n,hint:K(r)},r):r.code===`COMMAND_FAILED`?new t(`COMMAND_FAILED`,r.message,{...r.details??{},cmd:V,args:n,hint:K(r)},r):r}function K(e){return typeof e.details?.hint==`string`?e.details.hint:H}function Be(e){let t=e.error;if(typeof t==`string`&&t.trim())return t.trim();if(u(t)){let e=f(t,`message`)??f(t,`error`);if(e)return e}return f(e,`message`)??`agent-browser command failed`}function q(e){return typeof e==`string`&&e.length>0?e:`COMMAND_FAILED`}function J(e){return e.startsWith(`@`)?e:`@${e}`}function Ve(){return process.platform===`darwin`?`Meta+a`:`Control+a`}function He(e){let t=u(e)&&u(e.box)?e.box:e;if(u(t))return Ue(t)??We(t)}function Ue(e){return Y(p(e,`x`),p(e,`y`),p(e,`width`),p(e,`height`))}function We(e){let t=p(e,`left`),n=p(e,`top`),r=p(e,`right`),i=p(e,`bottom`);return Y(t,n,X(r,t),X(i,n))}function Y(e,t,n,r){if(!(e===void 0||t===void 0||n===void 0||r===void 0))return{x:e,y:t,width:n,height:r}}function X(e,t){return e===void 0||t===void 0?void 0:e-t}var Ge=e({hasScopedWebProvider:()=>Ke,resolveWebProvider:()=>Q,withWebProvider:()=>$});const Z=c(U());function Q(e){return Z.resolve(e)}function Ke(){return Z.hasScope()}async function $(e,t){return await Z.run(e,t)}export{U as i,Q as n,$ as r,Ge as t};
package/dist/src/proxy.js CHANGED
@@ -1,2 +1,2 @@
1
- import{C as e,_ as t}from"./sdk-contracts.js";import{ht as n,lt as r}from"./prepare-kind.js";import{a as i,i as a}from"./agent-device-client.js";import{ct as o,dt as s,lt as c,ot as l,pt as u,r as d,st as f}from"./screenshot-result.js";import{t as p}from"./timing-safe-equal.js";import{t as m}from"./shared.js";import{randomBytes as h,randomUUID as g}from"node:crypto";import{pipeline as ee}from"node:stream/promises";import{Readable as _}from"node:stream";import v from"node:http";const y=`${l}/`,b=[`content-type`,`content-range`,`x-artifact-type`,`x-artifact-filename`,`x-artifact-hash`,`x-artifact-hash-algorithm`,f],x=[`content-type`,`content-disposition`,`x-request-id`];function S(e){let t=P(e);return v.createServer((e,n)=>{C(e,n,t).catch(e=>{X(n,e)})})}async function C(e,t,n){let r=te(e.url??`/`);if(e.method===`GET`&&r===`/health`){await w(t,n);return}if(!L(r,e.method)){t.statusCode=404,t.end(`Not found`);return}let i;if(r===`/rpc`&&(i=(await u(e,n.maxRpcBodyBytes,`Proxy request body is too large.`)).toString(`utf8`)),!U(e,n.clientToken,i)){Y(t,r,q(i));return}await E({req:e,res:t,route:r,options:n,rpcBody:i})}async function w(e,t){let n=await T(t);e.statusCode=200,e.setHeader(`content-type`,`application/json`),e.end(JSON.stringify(d(`agent-device-proxy`,{upstream:n})))}async function T(e){let t=new URL(s(e.upstreamBaseUrl,`health`)),n=await e.fetchImpl(t,{method:`GET`,headers:V({headers:{}},e.upstreamToken,`/health`),signal:AbortSignal.timeout(e.upstreamTimeoutMs)}),r=await n.text();try{return r?JSON.parse(r):{ok:n.ok,status:n.status}}catch{return{ok:n.ok,status:n.status}}}async function E(e){let{req:t,res:n,route:r,options:i,rpcBody:a}=e,o=B(i.upstreamBaseUrl,r,t.url??`/`),s=t.method??`GET`,c=V(t,i.upstreamToken,r),l=H(t,r,a,i.upstreamToken);await D({req:t,res:n,route:r,response:await i.fetchImpl(o,{method:s,headers:c,signal:AbortSignal.timeout(i.upstreamTimeoutMs),...l?{body:l,duplex:`half`}:{}}),clientToken:i.clientToken})}async function D(e){let{req:t,res:n,route:r,response:i,clientToken:a}=e;if(n.statusCode=i.status,O(i,n),k(t,n),z(r)){await A({req:t,res:n,response:i,clientToken:a});return}await N(i,n)}function O(e,t){for(let n of x){let r=e.headers.get(n);r&&t.setHeader(n,r)}}function k(e,t){t.hasHeader(`x-request-id`)||t.setHeader(`x-request-id`,J(e))}async function A(e){let{req:t,res:n,response:r,clientToken:i}=e,a=await r.text();n.setHeader(`content-type`,r.headers.get(`content-type`)??`application/json`),n.end(j(a,t,i))}function j(e,t,n){let r;try{r=JSON.parse(e)}catch{return e}if(!r||typeof r!=`object`)return e;let i=r;if(!i.upload||typeof i.upload.url!=`string`)return e;let a=M(i.upload.url,t);if(!a)return e;let s=i.upload.headers&&typeof i.upload.headers==`object`?{...i.upload.headers}:{};return Object.assign(s,o(n)),JSON.stringify({...r,upload:{...i.upload,url:a,headers:s}})}function M(e,t){let n;try{n=new URL(e)}catch{return null}if(!n.pathname.startsWith(`/upload/`))return null;let r=typeof t.headers.host==`string`?t.headers.host:``;if(!r)return null;let i=new URL(t.url??`/`,`http://127.0.0.1`).pathname,a=i.lastIndexOf(`/upload/preflight`),o=a>=0?i.slice(0,a):``,s=t.headers[`x-forwarded-proto`],c=Array.isArray(s)?s[0]:s,l=new URL(`${c||`http`}://${r}`);return l.pathname=`${o}${n.pathname}`,l.search=n.search,l.toString()}async function N(e,t){if(!e.body){t.end();return}await ee(_.fromWeb(e.body),t)}function P(e){return{upstreamBaseUrl:F(e.upstreamBaseUrl,`upstreamBaseUrl`),upstreamToken:I(e.upstreamToken,`upstreamToken`),clientToken:I(e.clientToken,`clientToken`),maxRpcBodyBytes:e.maxRpcBodyBytes??1048576,upstreamTimeoutMs:e.upstreamTimeoutMs??3e5,fetchImpl:e.fetchImpl??fetch}}function F(e,n){try{let t=new URL(e);if(t.protocol!==`http:`&&t.protocol!==`https:`)throw Error(`unsupported protocol`);return t.toString().replace(/\/+$/,``)}catch(r){throw new t(`INVALID_ARGS`,`Invalid ${n}`,{[n]:e},r)}}function I(e,n){let r=e.trim();if(!r)throw new t(`INVALID_ARGS`,`Proxy ${n} is required.`);return r}function te(e){let t=new URL(e,`http://127.0.0.1`).pathname;return t===`/agent-device`?`/`:t.startsWith(y)?`/${t.slice(y.length)}`:t}function L(e,t){return e===`/rpc`?t===`POST`:R(e,t)?!0:e===`/artifacts`||e===`/artifacts/`||e.startsWith(`/artifacts/`)?t===`GET`:!1}function R(e,t){return e===`/upload`||z(e)||e===`/upload/finalize`?t===`POST`:e.startsWith(`/upload/direct/`)?t===`PUT`:!1}function z(e){return e===`/upload/preflight`}function B(e,t,n){let r=new URL(s(e,t)),i=n.indexOf(`?`);return i>=0&&(r.search=n.slice(i)),r}function V(e,t,n){let r=new Headers;for(let t of b){let n=e.headers[t];typeof n==`string`&&n.trim()&&r.set(t,n)}n===`/rpc`&&!r.has(`content-type`)&&r.set(`content-type`,`application/json`);for(let[e,n]of Object.entries(o(t)))r.set(e,n);return r}function H(e,t,n,r){if(!(e.method===`GET`||e.method===`HEAD`))return t===`/rpc`?G(n??``,r):e}function U(e,t,n){let r=W(e,n);return r.length>0&&p(r,t)}function W(e,t){let n=typeof e.headers.authorization==`string`?e.headers.authorization:``;if(n.toLowerCase().startsWith(`bearer `))return n.slice(7);let r=e.headers[`x-agent-device-token`];if(typeof r==`string`)return r;if(t){let e=K(t);if(e)return e}return``}function G(e,t){let n=JSON.parse(e);return n.params={...n.params??{},token:t},JSON.stringify(n)}function K(e){try{let t=JSON.parse(e);return typeof t.params?.token==`string`?t.params.token:``}catch{return``}}function q(e){if(!e)return null;try{return JSON.parse(e).id??null}catch{return null}}function J(e){let t=e.headers[`x-request-id`];return typeof t==`string`&&t.trim()?t.trim().slice(0,128):g()}function Y(n,r,i){if(n.statusCode=401,n.setHeader(`content-type`,`application/json`),r===`/rpc`){n.end(JSON.stringify({jsonrpc:`2.0`,id:i,error:{code:-32001,message:`Invalid proxy token`,data:e(new t(`UNAUTHORIZED`,`Invalid proxy token`))}}));return}n.end(JSON.stringify({ok:!1,error:`Invalid proxy token`,code:`UNAUTHORIZED`}))}function X(t,n){if(t.headersSent){t.destroy(n instanceof Error?n:void 0);return}let r=e(n);t.statusCode=r.code===`INVALID_ARGS`?400:500,t.setHeader(`content-type`,`application/json`),t.end(JSON.stringify({ok:!1,error:r.message,code:r.code}))}const Z=async({positionals:e,flags:n})=>{if(e.length>0)throw new t(`INVALID_ARGS`,`proxy does not accept positional arguments.`);let r=await Q(n);return m(n,r,()=>oe(r)),await se(),!0};async function Q(e){let n=i({session:`default`,command:`proxy`,positionals:[],flags:{stateDir:e.stateDir,daemonBaseUrl:``,daemonTransport:`http`,daemonServerMode:`http`}}),r=await a(n),o=ne(r.info.httpPort),s=re(e),l=S({upstreamBaseUrl:o,upstreamToken:r.info.token,clientToken:s});await ie(l,e.proxyHost?.trim()||`127.0.0.1`,e.proxyPort??0);let u=l.address();if(!u||typeof u==`string`)throw new t(`COMMAND_FAILED`,`Proxy did not bind to a TCP address.`);let d=`http://${ae(u.address)}:${u.port}`;return{proxyBaseUrl:d,agentDeviceBaseUrl:c(d),token:s,upstreamBaseUrl:o,stateDir:n.paths.baseDir}}function ne(e){if(!e)throw new t(`COMMAND_FAILED`,`Local daemon HTTP endpoint is unavailable.`,{hint:`Retry after cleaning daemon state, or run proxy with a fresh --state-dir.`});return`http://127.0.0.1:${e}`}function re(e){return e.daemonAuthToken?.trim()||h(32).toString(`hex`)}function ie(e,t,n){return new Promise((r,i)=>{e.once(`error`,i),e.listen(n,t,()=>{e.off(`error`,i),r()})})}function ae(e){return e.includes(`:`)&&!e.startsWith(`[`)?`[${e}]`:e}function oe(e,t={}){let r=t.useColor??n(),i=$(`✓`,`green`,r),a=$(e.proxyBaseUrl,`cyan`,r),o=$(`<tunnel URL>`,`cyan`,r),s=$(e.token,`yellow`,r);return[`${i} Proxy listening at ${a}`,``,`Provide this to the agent-device instance connecting:`,``,`Daemon base URL: ${o}`,`Daemon auth token: ${s}`].join(`
1
+ import{E as e,_ as t}from"./sdk-contracts.js";import{Ct as n,_t as r}from"./script-source-bundle.js";import{a as i,i as a}from"./agent-device-client.js";import{dt as o,ft as s,gt as c,lt as l,mt as u,r as d,ut as f}from"./screenshot-result.js";import{t as p}from"./timing-safe-equal.js";import{t as m}from"./shared.js";import{randomBytes as h,randomUUID as g}from"node:crypto";import{pipeline as ee}from"node:stream/promises";import{Readable as _}from"node:stream";import v from"node:http";const y=`${l}/`,b=[`content-type`,`content-range`,`x-artifact-type`,`x-artifact-filename`,`x-artifact-hash`,`x-artifact-hash-algorithm`,f],x=[`content-type`,`content-disposition`,`x-request-id`];function S(e){let t=P(e);return v.createServer((e,n)=>{C(e,n,t).catch(e=>{X(n,e)})})}async function C(e,t,n){let r=te(e.url??`/`);if(e.method===`GET`&&r===`/health`){await w(t,n);return}if(!L(r,e.method)){t.statusCode=404,t.end(`Not found`);return}let i;if(r===`/rpc`&&(i=(await c(e,n.maxRpcBodyBytes,`Proxy request body is too large.`)).toString(`utf8`)),!U(e,n.clientToken,i)){Y(t,r,q(i));return}await E({req:e,res:t,route:r,options:n,rpcBody:i})}async function w(e,t){let n=await T(t);e.statusCode=200,e.setHeader(`content-type`,`application/json`),e.end(JSON.stringify(d(`agent-device-proxy`,{upstream:n})))}async function T(e){let t=new URL(u(e.upstreamBaseUrl,`health`)),n=await e.fetchImpl(t,{method:`GET`,headers:V({headers:{}},e.upstreamToken,`/health`),signal:AbortSignal.timeout(e.upstreamTimeoutMs)}),r=await n.text();try{return r?JSON.parse(r):{ok:n.ok,status:n.status}}catch{return{ok:n.ok,status:n.status}}}async function E(e){let{req:t,res:n,route:r,options:i,rpcBody:a}=e,o=B(i.upstreamBaseUrl,r,t.url??`/`),s=t.method??`GET`,c=V(t,i.upstreamToken,r),l=H(t,r,a,i.upstreamToken);await D({req:t,res:n,route:r,response:await i.fetchImpl(o,{method:s,headers:c,signal:AbortSignal.timeout(i.upstreamTimeoutMs),...l?{body:l,duplex:`half`}:{}}),clientToken:i.clientToken})}async function D(e){let{req:t,res:n,route:r,response:i,clientToken:a}=e;if(n.statusCode=i.status,O(i,n),k(t,n),z(r)){await A({req:t,res:n,response:i,clientToken:a});return}await N(i,n)}function O(e,t){for(let n of x){let r=e.headers.get(n);r&&t.setHeader(n,r)}}function k(e,t){t.hasHeader(`x-request-id`)||t.setHeader(`x-request-id`,J(e))}async function A(e){let{req:t,res:n,response:r,clientToken:i}=e,a=await r.text();n.setHeader(`content-type`,r.headers.get(`content-type`)??`application/json`),n.end(j(a,t,i))}function j(e,t,n){let r;try{r=JSON.parse(e)}catch{return e}if(!r||typeof r!=`object`)return e;let i=r;if(!i.upload||typeof i.upload.url!=`string`)return e;let a=M(i.upload.url,t);if(!a)return e;let s=i.upload.headers&&typeof i.upload.headers==`object`?{...i.upload.headers}:{};return Object.assign(s,o(n)),JSON.stringify({...r,upload:{...i.upload,url:a,headers:s}})}function M(e,t){let n;try{n=new URL(e)}catch{return null}if(!n.pathname.startsWith(`/upload/`))return null;let r=typeof t.headers.host==`string`?t.headers.host:``;if(!r)return null;let i=new URL(t.url??`/`,`http://127.0.0.1`).pathname,a=i.lastIndexOf(`/upload/preflight`),o=a>=0?i.slice(0,a):``,s=t.headers[`x-forwarded-proto`],c=Array.isArray(s)?s[0]:s,l=new URL(`${c||`http`}://${r}`);return l.pathname=`${o}${n.pathname}`,l.search=n.search,l.toString()}async function N(e,t){if(!e.body){t.end();return}await ee(_.fromWeb(e.body),t)}function P(e){return{upstreamBaseUrl:F(e.upstreamBaseUrl,`upstreamBaseUrl`),upstreamToken:I(e.upstreamToken,`upstreamToken`),clientToken:I(e.clientToken,`clientToken`),maxRpcBodyBytes:e.maxRpcBodyBytes??1048576,upstreamTimeoutMs:e.upstreamTimeoutMs??3e5,fetchImpl:e.fetchImpl??fetch}}function F(e,n){try{let t=new URL(e);if(t.protocol!==`http:`&&t.protocol!==`https:`)throw Error(`unsupported protocol`);return t.toString().replace(/\/+$/,``)}catch(r){throw new t(`INVALID_ARGS`,`Invalid ${n}`,{[n]:e},r)}}function I(e,n){let r=e.trim();if(!r)throw new t(`INVALID_ARGS`,`Proxy ${n} is required.`);return r}function te(e){let t=new URL(e,`http://127.0.0.1`).pathname;return t===`/agent-device`?`/`:t.startsWith(y)?`/${t.slice(y.length)}`:t}function L(e,t){return e===`/rpc`?t===`POST`:R(e,t)?!0:e===`/artifacts`||e===`/artifacts/`||e.startsWith(`/artifacts/`)?t===`GET`:!1}function R(e,t){return e===`/upload`||z(e)||e===`/upload/finalize`?t===`POST`:e.startsWith(`/upload/direct/`)?t===`PUT`:!1}function z(e){return e===`/upload/preflight`}function B(e,t,n){let r=new URL(u(e,t)),i=n.indexOf(`?`);return i>=0&&(r.search=n.slice(i)),r}function V(e,t,n){let r=new Headers;for(let t of b){let n=e.headers[t];typeof n==`string`&&n.trim()&&r.set(t,n)}n===`/rpc`&&!r.has(`content-type`)&&r.set(`content-type`,`application/json`);for(let[e,n]of Object.entries(o(t)))r.set(e,n);return r}function H(e,t,n,r){if(!(e.method===`GET`||e.method===`HEAD`))return t===`/rpc`?G(n??``,r):e}function U(e,t,n){let r=W(e,n);return r.length>0&&p(r,t)}function W(e,t){let n=typeof e.headers.authorization==`string`?e.headers.authorization:``;if(n.toLowerCase().startsWith(`bearer `))return n.slice(7);let r=e.headers[`x-agent-device-token`];if(typeof r==`string`)return r;if(t){let e=K(t);if(e)return e}return``}function G(e,t){let n=JSON.parse(e);return n.params={...n.params??{},token:t},JSON.stringify(n)}function K(e){try{let t=JSON.parse(e);return typeof t.params?.token==`string`?t.params.token:``}catch{return``}}function q(e){if(!e)return null;try{return JSON.parse(e).id??null}catch{return null}}function J(e){let t=e.headers[`x-request-id`];return typeof t==`string`&&t.trim()?t.trim().slice(0,128):g()}function Y(n,r,i){if(n.statusCode=401,n.setHeader(`content-type`,`application/json`),r===`/rpc`){n.end(JSON.stringify({jsonrpc:`2.0`,id:i,error:{code:-32001,message:`Invalid proxy token`,data:e(new t(`UNAUTHORIZED`,`Invalid proxy token`))}}));return}n.end(JSON.stringify({ok:!1,error:`Invalid proxy token`,code:`UNAUTHORIZED`}))}function X(t,n){if(t.headersSent){t.destroy(n instanceof Error?n:void 0);return}let r=e(n);t.statusCode=r.code===`INVALID_ARGS`?400:500,t.setHeader(`content-type`,`application/json`),t.end(JSON.stringify({ok:!1,error:r.message,code:r.code}))}const Z=async({positionals:e,flags:n})=>{if(e.length>0)throw new t(`INVALID_ARGS`,`proxy does not accept positional arguments.`);let r=await Q(n);return m(n,r,()=>oe(r)),await se(),!0};async function Q(e){let n=i({session:`default`,command:`proxy`,positionals:[],flags:{stateDir:e.stateDir,daemonBaseUrl:``,daemonTransport:`http`,daemonServerMode:`http`}}),r=await a(n),o=ne(r.info.httpPort),c=re(e),l=S({upstreamBaseUrl:o,upstreamToken:r.info.token,clientToken:c});await ie(l,e.proxyHost?.trim()||`127.0.0.1`,e.proxyPort??0);let u=l.address();if(!u||typeof u==`string`)throw new t(`COMMAND_FAILED`,`Proxy did not bind to a TCP address.`);let d=`http://${ae(u.address)}:${u.port}`;return{proxyBaseUrl:d,agentDeviceBaseUrl:s(d),token:c,upstreamBaseUrl:o,stateDir:n.paths.baseDir}}function ne(e){if(!e)throw new t(`COMMAND_FAILED`,`Local daemon HTTP endpoint is unavailable.`,{hint:`Retry after cleaning daemon state, or run proxy with a fresh --state-dir.`});return`http://127.0.0.1:${e}`}function re(e){return e.daemonAuthToken?.trim()||h(32).toString(`hex`)}function ie(e,t,n){return new Promise((r,i)=>{e.once(`error`,i),e.listen(n,t,()=>{e.off(`error`,i),r()})})}function ae(e){return e.includes(`:`)&&!e.startsWith(`[`)?`[${e}]`:e}function oe(e,t={}){let r=t.useColor??n(),i=$(`✓`,`green`,r),a=$(e.proxyBaseUrl,`cyan`,r),o=$(`<tunnel URL>`,`cyan`,r),s=$(e.token,`yellow`,r);return[`${i} Proxy listening at ${a}`,``,`Provide this to the agent-device instance connecting:`,``,`Daemon base URL: ${o}`,`Daemon auth token: ${s}`].join(`
2
2
  `)}function $(e,t,n){return n?r(e,t,{validateStream:!1}):e}function se(){return new Promise(()=>{})}export{Z as proxyCommand};