agent-device 0.21.17 → 0.21.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.17.apk → agent-device-android-ime-helper-0.21.18.apk} +0 -0
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.18.apk.sha256 +1 -0
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.17.manifest.json → agent-device-android-ime-helper-0.21.18.manifest.json} +4 -4
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.17.apk → agent-device-android-snapshot-helper-0.21.18.apk} +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.18.apk.sha256 +1 -0
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.17.manifest.json → agent-device-android-snapshot-helper-0.21.18.manifest.json} +6 -6
- package/dist/src/adb-executor.js +2 -2
- package/dist/src/adb-failure.js +1 -1
- package/dist/src/agent-device-client.js +1 -1
- package/dist/src/daemon-client-lease-beat.js +1 -1
- package/dist/src/daemon-client-lifecycle.js +1 -1
- package/dist/src/daemon-client-transport.js +1 -1
- package/dist/src/internal/bin.js +1 -1
- package/package.json +1 -1
- package/server.json +2 -2
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.17.apk.sha256 +0 -1
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.17.apk.sha256 +0 -1
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
00d2204c16819a569c8e657a353b165e3bf12971176078ddfdea069d0702adf9 agent-device-android-ime-helper-0.21.18.apk
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "android-ime-helper",
|
|
3
|
-
"version": "0.21.
|
|
4
|
-
"assetName": "agent-device-android-ime-helper-0.21.
|
|
5
|
-
"sha256": "
|
|
3
|
+
"version": "0.21.18",
|
|
4
|
+
"assetName": "agent-device-android-ime-helper-0.21.18.apk",
|
|
5
|
+
"sha256": "00d2204c16819a569c8e657a353b165e3bf12971176078ddfdea069d0702adf9",
|
|
6
6
|
"packageName": "com.callstack.agentdevice.imehelper",
|
|
7
|
-
"versionCode":
|
|
7
|
+
"versionCode": 21018,
|
|
8
8
|
"serviceComponent": "com.callstack.agentdevice.imehelper/.TestInputMethodService",
|
|
9
9
|
"broadcastProtocol": "android-ime-helper-v1"
|
|
10
10
|
}
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ea1eeb62917f37fa08228e609c5270279de095db2e222577e7588ef23364c046 agent-device-android-snapshot-helper-0.21.18.apk
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "android-snapshot-helper",
|
|
3
|
-
"version": "0.21.
|
|
4
|
-
"releaseTag": "v0.21.
|
|
5
|
-
"assetName": "agent-device-android-snapshot-helper-0.21.
|
|
3
|
+
"version": "0.21.18",
|
|
4
|
+
"releaseTag": "v0.21.18",
|
|
5
|
+
"assetName": "agent-device-android-snapshot-helper-0.21.18.apk",
|
|
6
6
|
"apkUrl": null,
|
|
7
|
-
"sha256": "
|
|
8
|
-
"checksumName": "agent-device-android-snapshot-helper-0.21.
|
|
7
|
+
"sha256": "ea1eeb62917f37fa08228e609c5270279de095db2e222577e7588ef23364c046",
|
|
8
|
+
"checksumName": "agent-device-android-snapshot-helper-0.21.18.apk.sha256",
|
|
9
9
|
"packageName": "com.callstack.agentdevice.snapshothelper",
|
|
10
|
-
"versionCode":
|
|
10
|
+
"versionCode": 21018,
|
|
11
11
|
"instrumentationRunner": "com.callstack.agentdevice.snapshothelper/.SnapshotInstrumentation",
|
|
12
12
|
"minSdk": 23,
|
|
13
13
|
"targetSdk": 36,
|
package/dist/src/adb-executor.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{N as e}from"./sdk-contracts.js";import{n as t,r as n,t as r}from"./device-shell.js";import{a as i,d as a,f as o,i as s,l as c,m as l,n as u,p as d,s as f,u as p}from"./adb-transport.js";import{c as m,n as
|
|
2
|
-
`).map(e=>e.trim().split(/\s+/)).filter(e=>e.length>=3).map(([,e,t])=>{let r=e;return{local:r,remote:t,ownerId:n.get(r)}})}function
|
|
1
|
+
import{N as e}from"./sdk-contracts.js";import{n as t,r as n,t as r}from"./device-shell.js";import{a as i,d as a,f as o,i as s,l as c,m as l,n as u,p as d,s as f,u as p}from"./adb-transport.js";import{c as m,i as ee,n as te,s as ne}from"./adb-failure.js";import{AsyncLocalStorage as h}from"node:async_hooks";let g;const _=new h;function v(e){g=e}function y(){if(!g)throw Error(`Android adb host port is not bound; import the platform composition wiring (src/platform-runtime-android-adb-host.ts) before using the adb/IME cluster.`);return g}async function b(e,t){let n=y(),r=_.getStore(),i=n.coerceAdbResult(r?await r(e,t):await n.execAdb(e,{...t,allowFailure:!0}));if(!t?.allowFailure&&i.exitCode!==0){let{androidAdbResultError:t}=await import(`./adb-failure.js`).then(e=>e.t),{serializeAndroidAdbInvocation:n}=await import(`./adb-transport.js`).then(e=>e.t);throw t(`adb ${n(e).join(` `)} exited with code ${i.exitCode}`,i)}return i}async function x(e,t){return await _.run(e,t)}function S(e){y().emitDiagnostic(e)}const C=new WeakSet;function w(e){return T(typeof e==`function`?{exec:e}:e)}function T(e){if(C.has(e))return e;let t={...e,exec:m(E(e.exec)),...e.pull?{pull:m(E(e.pull))}:{},...e.install?{install:m(E(e.install))}:{},...e.installBundle?{installBundle:m(e.installBundle)}:{}};return C.add(t),t}function E(e){return async(...t)=>y().coerceAdbResult(await e(...t))}const D=new WeakSet;function O(t){let n=w(t);if(n.reverse&&D.has(n.reverse))return n.reverse;let r=n.reverse??k(n.exec),i=new Map,a={async ensure(t,n){let a=i.get(t.local);if(a&&a.ownerId!==t.ownerId)throw new e(`COMMAND_FAILED`,`Android port reverse ${t.local} is already owned by ${a.ownerId??`another session`}`,{current:a,requested:t});a?.remote!==t.remote&&(await r.ensure(t,n),i.set(t.local,{...t}))},async remove(e,t){if(!i.has(e)){await r.remove(e,t);return}await r.remove(e,t),i.delete(e)},async removeAllOwned(e,t){let n=[...i.values()].filter(t=>t.ownerId===e).map(e=>e.local);if(n.length===0){await r.removeAllOwned(e,t);return}for(let e of n)await r.remove(e,t),i.delete(e)},async list(e){return r.list?await r.list(e):[...i.values()]}};return D.add(a),a}function k(e){let t=new Map;return{async ensure(n,r){if(await e([`reverse`,n.local,n.remote],{allowFailure:!1,signal:r?.signal,timeoutMs:r?.timeoutMs}),n.ownerId){let e=t.get(n.ownerId)??new Set;e.add(n.local),t.set(n.ownerId,e)}},async remove(n,r){let i=await e([`reverse`,`--remove`,n],{allowFailure:!0,signal:r?.signal,timeoutMs:r?.timeoutMs});if(i.exitCode!==0&&!re(i.stdout,i.stderr))throw te(`Failed to remove Android port reverse ${n}`,i,{local:n});for(let e of t.values())e.delete(n)},async removeAllOwned(e,n){let r=[...t.get(e)??[]];for(let e of r)await this.remove(e,n);t.delete(e)},async list(n){let r=await e([`reverse`,`--list`],{allowFailure:!0,signal:n?.signal,timeoutMs:n?.timeoutMs});return r.exitCode===0?A(r.stdout,t):[]}}}function A(e,t){let n=new Map;for(let[e,r]of t)for(let t of r)n.set(t,e);return e.split(`
|
|
2
|
+
`).map(e=>e.trim().split(/\s+/)).filter(e=>e.length>=3).map(([,e,t])=>{let r=e;return{local:r,remote:t,ownerId:n.get(r)}})}function re(e,t){let n=`${e}\n${t}`.toLowerCase();return n.includes(`listener`)&&n.includes(`not found`)}const j=new h;function M(e,t={}){return Q(ie(e.id,t.serverPort))}function ie(e,t){return m(async(n,r)=>{let i=y(),a=async(n,r)=>{let a=V(e,t,n,r);return await i.withoutAdbCommandExecutorOverride(async()=>await i.execAdb(a.invocation,a.options))};return await P(`${t??r?.serverPort??``}/${e}`,r,async e=>await a(n,e),async e=>{await a([`wait-for-device`],{allowFailure:!0,timeoutMs:e,signal:r?.signal,env:r?.env,serverPort:r?.serverPort}).catch(()=>void 0)})})}function ae(e,t=new Map){return{has:e=>(t.get(e)??0)>Date.now(),mark:n=>{let r=Date.now();for(let[e,n]of t)n<=r&&t.delete(e);t.set(n,r+e)},forget:e=>{t.delete(e)}}}const N=ae(3e4);async function P(e,t,n,r){let i=Date.now(),a=await F(e,async()=>await n(t));if(!a.offline||N.has(e))return a.outcome();let o=t?.timeoutMs,s=()=>o===void 0?1/0:Math.floor(o-(Date.now()-i)),c=Math.min(15e3,Math.floor(s()/2));if(c<1)return a.outcome();await r(c),t?.signal?.throwIfAborted();let l=s();if(l<1)return a.outcome();let u=await F(e,async()=>await n(o===void 0?t:{...t,timeoutMs:l}));return u.offline&&N.mark(e),u.outcome()}async function F(e,t){try{let n=await t(),r=I(n);return r||N.forget(e),{offline:r,outcome:()=>n}}catch(t){let n=ee(t),r=L(n);return!r&&z(n)&&N.forget(e),{offline:r,outcome:()=>{throw n}}}}function I(e){if(e.exitCode===0)return!1;let t=ne(e.stderr,e.stdout);return R(t?.reason,t?.hostRefusal)}function L(t){return t instanceof e&&R(t.details?.adbFailure,t.details?.adbHostRefusal)}function R(e,t){return e===`device_offline`&&t===!0}function z(t){if(!(t instanceof e)||t.details?.timeoutMs!==void 0)return!1;let n=t.details?.exitCode;return typeof n==`number`&&n>=0}function B(e,t){return $((n,r)=>{let i=V(e,t,n,r);return y().spawnAdb(i.invocation,i.options)})}function V(e,t,n,r){let{serverPort:i,...a}=r??{};return{invocation:H(e,n,U(e,t,i)),options:a}}function H(e,t,n){let r=p(t),i=u(r.target,e);if(n===void 0)return s(i,r.command,[`-s`,e,...t]);let a=f(r,{port:n});return s(o(a.target,e),a.command)}function U(e,t,n){let r=j.getStore();return r&&Z(r,{kind:`serial`,serial:e}),r?.serverPort===void 0?t??n:(d(t,r.serverPort),d(n,r.serverPort))}function W(e,t={}){let n=M(e,t);return{exec:n,spawn:B(e.id,t.serverPort),reverse:k(n),pull:async(e,t,r)=>await n([`pull`,e,t],r),install:async(e,t)=>{let{installArgs:r,execOptions:i}=c(t);return await n([`install`,...r,e],i)}}}function G(e,t){let n=X(e);return t?Q(t):n?.serial===e.id?Q(n.provider.exec):M(e)}function K(e,t){let n=X(e);return me(t?w(t):n?.serial===e.id?w(n.provider):W(e))}function q(e){let t=X(e);return t?.serial===e.id?{mode:`transport-composed`,...t.provider.spawn?{spawn:$(t.provider.spawn)}:{}}:{mode:`local`}}function oe(e){let t=X(e);return t?.serial===e.id?t.provider.text:void 0}function se(e){let t=X(e);return t?.serial===e.id&&t.provider.touch?t.provider:void 0}function J(e,t){if(t)return w(t);if(e)return K(e);let n=j.getStore();if(n)return w(n.provider)}async function ce(e,t,n){if(!e)return await n();let r={provider:w(e),serial:t.serial,...t.serverPort===void 0?{}:{serverPort:t.serverPort}},i=le(r),a=async()=>await j.run(r,async()=>await y().withAdbCommandExecutorOverride(i,n));return t.serverPort===void 0?await a():await x(ue(r,t.serverPort),a)}function le(e){return(t,n,r)=>{if(!de(t)||e.serverPort===void 0&&t!==`adb`)return;let o=p(n);if(Z(e,o.target.selector),o.target.selector.kind===`serial`){if(o.target.selector.serial!==e.serial)return;e.serverPort!==void 0&&a(o.target,e.serverPort);let t=i(n,e.serial);return t===void 0?void 0:y().withoutAdbCommandExecutorOverride(async()=>await e.provider.exec(t,r))}let s=e.serverPort;if(s!==void 0)return Y(e,s,o,r)}}function ue(e,t){return async(n,r)=>(Z(e,n.target.selector),Y(e,t,n,r))}async function Y(e,t,n,r){d(t,r?.serverPort);let{serverPort:i,...a}=r??{},c=o(n.target,e.serial),l=f(s(c,n.command),{port:t}),u=y();return await u.withoutAdbCommandExecutorOverride(async()=>await u.execAdb(l,{...a,allowFailure:!0}))}function X(e){let t=j.getStore();return t&&Z(t,{kind:`serial`,serial:e.id}),t}function Z(e,t){e?.serverPort!==void 0&&l(t,e.serial)}function de(e){return n(e)===`adb`}async function fe(e,n,r){return await e(t(`adb`,`shell`,n),r)}async function pe(e,n,r){return await e(t(`adb`,`exec-out`,n),r)}function Q(e){return async(t,n)=>(r(t,`adb`),await e(t,n))}function $(e){return(t,n)=>(r(t,`adb`),e(t,n))}function me(e){return{...e,exec:Q(e.exec),...e.spawn?{spawn:$(e.spawn)}:{}}}async function he(t,n,r){let{device:i,provider:a,...o}=r??{},s=J(i,a),c=s?.pull,l=y();if(c)return await l.withoutAdbCommandExecutorOverride(async()=>await c(t,n,o));let u=s?.exec;if(!u)throw new e(`COMMAND_FAILED`,`Android adb pull requires an adb provider`);return await l.withoutAdbCommandExecutorOverride(async()=>await u([`pull`,t,n],o))}async function ge(t,n){let{device:r,provider:i,...a}=n??{},o=J(r,i),s=o?.install,l=y();if(s)return await l.withoutAdbCommandExecutorOverride(async()=>await s(t,a));let u=o?.exec;if(!u)throw new e(`COMMAND_FAILED`,`Android adb install requires an adb provider`);let{installArgs:d,execOptions:f}=c(a);return await l.withoutAdbCommandExecutorOverride(async()=>await u([`install`,...d,t],f))}export{b as _,G as a,se as c,fe as d,ce as f,y as g,S as h,W as i,q as l,v as m,he as n,K as o,O as p,M as r,oe as s,ge as t,pe as u,x as v};
|
package/dist/src/adb-failure.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime.js";import{N as t}from"./sdk-contracts.js";import{r as n}from"./exec.js";import"./command.js";var r=e({androidAdbResultError:()=>
|
|
1
|
+
import{r as e}from"./rolldown-runtime.js";import{N as t}from"./sdk-contracts.js";import{r as n}from"./exec.js";import"./command.js";var r=e({androidAdbResultError:()=>p,androidDiscoveryCommandError:()=>h,attachAdbFailureHint:()=>u,attachAndroidDiscoveryTimeout:()=>g,attachAndroidHelperInstallTimeoutHint:()=>d,classifyAndroidAdbFailure:()=>l,withAdbFailureHints:()=>m});const i={reason:`device_offline`,hint:`The device is connected but offline — wait for it to finish booting or run adb reconnect, then retry.`,retriable:!0},a=/^(?:adb|error): device (?:'[^']*' )?offline$/,o=Object.freeze({...i,hostRefusal:!0}),s=[[/device unauthorized|device still authorizing/,{reason:`device_unauthorized`,hint:`USB debugging is not authorized — accept the authorization prompt on the device screen (re-plug the cable if none appears), then retry.`}],[/device offline/,i],[/more than one (?:device\/emulator|device and emulator)/,{reason:`multiple_devices`,hint:`Multiple Android devices are connected — pass --serial <serial> (see adb devices) to select one.`}],[/no devices\/emulators found|no devices found/,{reason:`no_devices`,hint:`No Android devices detected — boot an emulator or connect a device and verify it appears in adb devices.`}],[/device (?:'[^']*' )?not found/,{reason:`device_not_found`,hint:`The device disconnected or is restarting — verify it is listed in adb devices, then retry.`,retriable:!0}],[/adb server version \(\d+\) doesn't match this client/,{reason:`server_version_mismatch`,hint:`Multiple adb installs conflict — adb restarts its server automatically, so retry; align PATH to a single adb to stop recurrences.`,retriable:!0}],[/transport error|connection reset|broken pipe|protocol fault/,{reason:`connection_dropped`,hint:`The adb connection dropped — retry; if it persists, run adb kill-server and reconnect the device.`,retriable:!0}],[/install_failed_insufficient_storage/,{reason:`install_insufficient_storage`,hint:`The device is out of storage — free up space or uninstall unused apps, then retry the install.`},!0],[/install_failed_update_incompatible/,{reason:`install_update_incompatible`,hint:`The installed app has an incompatible signature — uninstall the existing app first, then retry the install.`},!0],[/install_failed_version_downgrade/,{reason:`install_version_downgrade`,hint:`The APK is older than the installed app — uninstall the app first (or install with downgrade allowed), then retry.`},!0],[/install_failed_\w+|install_parse_failed_\w+/,{reason:`install_failed`,hint:`The Android package installer rejected the APK — see the INSTALL_FAILED code in the error output for the exact cause.`},!0]],c=Object.freeze({reason:`timeout`,hint:`adb timed out — the adb server may be wedged. Run adb kill-server && adb start-server, check adb devices, then retry.`});function l(e,t=``){let n=e.toLowerCase(),r=t.toLowerCase();if(r===``&&a.test(n.trim()))return o;for(let[e,t,i]of s)if(e.test(n)||i&&e.test(r))return t}function u(e){if(!(e instanceof t)||e.code!==`COMMAND_FAILED`)return e;let n=f(e);return n&&(e.details={...e.details,adbFailure:n.reason,...n.hostRefusal?{adbHostRefusal:!0}:{},...typeof e.details?.hint==`string`?{}:{hint:n.hint},...n.retriable!==void 0&&e.details?.retriable===void 0?{retriable:n.retriable}:{}}),e}function d(e){if(!n(e))return e;let t=e.details?.hint;if(typeof t==`string`&&t!==c.hint)return e;let r=u(e);return r.details={...r.details,hint:`The helper install timed out — some OEM builds (ColorOS is one) hold the first install of each package behind a system install-confirmation dialog and adb waits for it. Check the device screen, confirm any pending install prompt, then retry; if none is showing, run adb kill-server && adb start-server and retry.`},r}function f(e){return typeof e.details?.timeoutMs==`number`?c:l(typeof e.details?.stderr==`string`?e.details.stderr:``,typeof e.details?.stdout==`string`?e.details.stdout:``)}function p(e,n,r){let i=n.exitCode===0?{stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode,...r}:{stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode,processExitError:!0,...r};return u(new t(`COMMAND_FAILED`,e,i))}function m(e){return async(...t)=>{try{return await e(...t)}catch(e){throw u(e)}}}function h(e,n,r){let i=l(n.stderr,n.stdout);return new t(`COMMAND_FAILED`,e,{stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode,processExitError:!0,hint:i?.hint??r,...i?{adbFailure:i.reason}:{},...i?.retriable===void 0?{}:{retriable:i.retriable}})}function g(e){return n(e)&&(e.details={...e.details,adbFailure:c.reason,...typeof e.details?.hint==`string`?{}:{hint:c.hint}}),e}export{g as a,m as c,u as i,p as n,d as o,h as r,l as s,r as t};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime.js";import{N as t,Q as n,Y as r,c as i,s as a}from"./sdk-contracts.js";import"./capture.js";import{n as o}from"./snapshot-capture-annotations.js";import{C as s,D as c,E as l,S as u,T as d,_ as f,b as p,g as ee,k as m,w as te,x as h}from"./sdk-batch-runner.js";import{n as ne}from"./snapshot-diagnostics.js";import{_ as re,d as ie,u as ae,v as g}from"./sdk-device.js";import{a as oe,o as se,p as ce}from"./lease-scope.js";import{an as le,w as ue}from"./sdk-batch.js";import{n as _,t as v}from"./catalog.js";import{B as de,T as fe,i as pe,z as me}from"./registry.js";import{n as he}from"./success-text.js";import{c as y,n as ge,r as _e}from"./diagnostics.js";import{t as b}from"./command-metadata.js";import"./diagnostics2.js";import{
|
|
1
|
+
import{r as e}from"./rolldown-runtime.js";import{N as t,Q as n,Y as r,c as i,s as a}from"./sdk-contracts.js";import"./capture.js";import{n as o}from"./snapshot-capture-annotations.js";import{C as s,D as c,E as l,S as u,T as d,_ as f,b as p,g as ee,k as m,w as te,x as h}from"./sdk-batch-runner.js";import{n as ne}from"./snapshot-diagnostics.js";import{_ as re,d as ie,u as ae,v as g}from"./sdk-device.js";import{a as oe,o as se,p as ce}from"./lease-scope.js";import{an as le,w as ue}from"./sdk-batch.js";import{n as _,t as v}from"./catalog.js";import{B as de,T as fe,i as pe,z as me}from"./registry.js";import{n as he}from"./success-text.js";import{c as y,n as ge,r as _e}from"./diagnostics.js";import{t as b}from"./command-metadata.js";import"./diagnostics2.js";import{g as x,i as ve,l as ye}from"./daemon-client-transport.js";import{t as S}from"./daemon-resolution.js";import{a as be,i as xe,n as Se,o as Ce,r as we,s as Te,t as C}from"./daemon-client-lifecycle.js";import{r as w}from"./session-paths.js";import{n as T,t as E}from"./client-metro.js";import{t as D}from"./screenshot-result.js";import O from"node:path";import k from"node:fs";function A(e){let t=e.appId??e.bundleId??e.packageName;return{session:e.session,appId:t,appBundleId:e.bundleId,package:e.packageName}}function j(e,t,n){return{deviceId:t,deviceName:n,...g(e)?{serial:t}:e===`ios`?{udid:t}:{}}}function M(e,t){let n=u(e,`bundleId`),r=u(e,`package`);return{app:l(e,`app`),appPath:l(e,`appPath`),platform:d(e,`platform`),appId:n??r,bundleId:n,package:r,identifiers:A({session:t,bundleId:n,packageName:r})}}function Ee(e,n){let r=u(e,`bundleId`),i=u(e,`packageName`),a=r??i??u(e,`appId`),o=u(e,`launchTarget`)??i??r??a;if(!o)throw new t(`COMMAND_FAILED`,`Daemon response is missing "launchTarget".`,{response:e});return{appName:u(e,`appName`),appId:a,bundleId:r,packageName:i,launchTarget:o,installablePath:u(e,`installablePath`),archivePath:u(e,`archivePath`),materializationId:u(e,`materializationId`),materializationExpiresAt:u(e,`materializationExpiresAt`),identifiers:A({session:n,bundleId:r,packageName:i,appId:a})}}function De(e){return{released:e.released===!0,materializationId:l(e,`materializationId`),identifiers:{}}}function N(e){let{record:t,platform:n,id:r,name:i,target:a}=F(e,`name`),o=P(t);return{platform:n,target:a,kind:s(t,`kind`),id:r,name:i,booted:typeof t.booted==`boolean`?t.booted:void 0,...ie(n)&&o?{appleOs:o}:{},identifiers:j(n,r,i),...Oe(t),...I(n,r)}}function Oe(e){let t=e.claimedBy;if(!t||typeof t!=`object`||Array.isArray(t))return{};let n=t,r=n.session,i=n.workspace;return typeof r!=`string`||typeof i!=`string`?{}:{claimedBy:{session:r,workspace:i}}}function ke(e){let{record:t,platform:n,id:r,name:i,target:a}=F(e,`name`),o=l(t,`device`),s=P(t),c={session:i,...j(n,r,o)};return{name:i,address:u(t,`address`),createdAt:te(t,`createdAt`),sessionStateDir:u(t,`sessionStateDir`),runnerLogPath:u(t,`runnerLogPath`),device:{platform:n,target:a,id:r,name:o,...s?{appleOs:s}:{},identifiers:c,...I(n,r,{simulatorSetPath:h(t,`ios_simulator_device_set`)})},identifiers:c}}function P(e){let t=e.appleOs;return ae(t)?t:void 0}function F(e,t){let n=ee(e);return{record:n,platform:d(n,`platform`),id:l(n,`id`),name:l(n,t),target:p(n,`target`)}}function I(e,t,n={}){if(e===`ios`)return{ios:{udid:t,...n.simulatorSetPath===void 0?{}:{simulatorSetPath:n.simulatorSetPath}}};if(!g(e))return{};let r=n.serial??t;return e===`android`?{android:{serial:r}}:e===`harmonyos`?{harmonyos:{serial:r}}:{vega:{serial:r}}}function Ae(e){if(!f(e))return;let t=e.platform,n=u(e,`metroHost`),r=typeof e.metroPort==`number`?e.metroPort:void 0,a=u(e,`bundleUrl`),o=u(e,`launchUrl`);return{platform:i(t)?t:void 0,metroHost:n,metroPort:r,bundleUrl:a,launchUrl:o}}function je(e){let t=e.platform,n=u(e,`id`),r=u(e,`device`);if(!re(t)||!n||!r)return;let i=p(e,`target`),a=g(t)?u(e,`serial`)??n:void 0;return{platform:t,target:i,id:n,name:r,identifiers:{...j(t,n,r),...a?{serial:a}:{}},...I(t,t===`ios`?u(e,`device_udid`)??n:n,{simulatorSetPath:h(e,`ios_simulator_device_set`),serial:a})}}const Me=[`explicit-selector`,`existing-session`,`single-booted-local`,`single-bootable-local`,`single-app-installed-local`,`preferred-local`,`single-provider-device`],Ne=[`session`,`local`,`provider`];function Pe(e){if(!f(e))return;let{reason:t,source:n,candidateCount:r,bootOccurred:i}=e;if(!(!Me.includes(t)||!Ne.includes(n)||typeof r!=`number`||!Number.isInteger(r)||r<0||typeof i!=`boolean`))return{reason:t,source:n,candidateCount:r,bootOccurred:i}}function Fe(e){if(f(e)&&typeof e.durationMs==`number`&&typeof e.measuredAt==`string`&&typeof e.method==`string`)return{durationMs:e.durationMs,measuredAt:e.measuredAt,method:e.method,appTarget:u(e,`appTarget`),appBundleId:u(e,`appBundleId`)}}function L(e){if(!f(e)||typeof e.success!=`boolean`||typeof e.exitCode!=`number`||typeof e.stdout!=`string`||typeof e.stderr!=`string`)return;let t=R(e.error);return{success:e.success,exitCode:e.exitCode,stdout:e.stdout,stderr:e.stderr,...t?{error:t}:{}}}const Ie=[`hint`,`diagnosticId`,`logPath`,`supportedOn`];function R(e){if(!f(e)||typeof e.code!=`string`||typeof e.message!=`string`)return;let t={code:e.code,message:e.message};Object.assign(t,Le(e.cause));for(let n of Ie){let r=e[n];typeof r==`string`&&(t[n]=r)}return f(e.details)&&(t.details=e.details),typeof e.retriable==`boolean`&&(t.retriable=e.retriable),t}function Le(e){let t=n(e);return t?{cause:t}:void 0}function Re(e){let t=R(e.initialSnapshotError);return{...e.snapshot&&typeof e.snapshot==`object`?{snapshot:e.snapshot}:{},...t?{initialSnapshotError:t}:{}}}function ze(e){return Array.isArray(e)?e:[]}function Be(e){let t=oe(e);return m({requestId:e.requestId,cwd:e.cwd,sessionExplicit:e.session!==void 0,debug:e.debug,includeCost:e.cost,responseLevel:e.responseLevel,lockPolicy:e.lockPolicy,lockPlatform:e.lockPlatform,...ce(t),sessionIsolation:e.sessionIsolation,installSource:e.installSource,retainMaterializedPaths:e.retainMaterializedPaths,materializedPathRetentionMs:e.materializedPathRetentionMs,materializationId:e.materializationId})}function z(e){return e??`default`}const B={...pe(),batch:fe(Ve)};async function Ve(e,n,r){let i=B[e];if(!i)throw Error(`Missing daemon writer for batch command: ${e}`);let a=b(e);if(!a)throw Error(`Missing command metadata for batch command: ${e}`);try{return await V(i,a,a.readInput(n))}catch(n){let i=n instanceof Error?n.message:String(n);throw new t(`INVALID_ARGS`,`Batch step ${r} ${e} input is invalid: ${i}`,void 0,n)}}async function He(e,t){let n=B[e];if(!n)throw Error(`Missing daemon writer for command: ${e}`);return await V(n,b(e),t)}async function V(e,t,n){let r=await e(n);return{...r,...t?{metadataFlags:de(t,r.options)}:{}}}async function H(e,t={}){let n=e.meta?.requestId??ge(),r=!!(e.meta?.debug||e.flags?.verbose),i=e.flags,{daemonAuthToken:a,...o}=i??{},s=i?{...e,flags:o}:e,c=Te(s,t.authToken??a),l=le(ue(s.command),s),u=await y(`daemon_startup`,async()=>await xe(c),{requestId:n,session:e.session}),d=u.info,f=await Qe(d,c,s);Xe(s.command);let p=Ue(s,f,d.token,n,r);return _e({level:`info`,phase:`daemon_request_prepare`,data:{requestId:n,command:s.command,session:s.session}}),await qe(s,u,c,async()=>Ye(Je(await y(`daemon_request`,async()=>await ve(d,p,c.transportPreference,c.paths,l,{onProgress:t.onProgress}),{requestId:n,command:e.command}),c),s,c))}function Ue(e,t,n,r,i){return{...e,positionals:t.positionals,flags:t.flags,token:n,meta:We(e,t,r,i)}}function We(e,t,n,r){let i=e.meta??{};return{...i,requestId:n,debug:r,...Ge(i,e.flags),...Ke(t)}}function Ge(e,t){return{includeCost:e.includeCost,cwd:e.cwd,sessionExplicit:e.sessionExplicit,tenantId:e.tenantId??t?.tenant,runId:e.runId??t?.runId,leaseId:e.leaseId??t?.leaseId,sessionIsolation:e.sessionIsolation??t?.sessionIsolation,lockPolicy:e.lockPolicy,lockPlatform:e.lockPlatform}}function Ke(e){return{...e.uploadedArtifactId?{uploadedArtifactId:e.uploadedArtifactId}:{},...e.clientArtifactPaths?{clientArtifactPaths:e.clientArtifactPaths}:{},...e.installSource?{installSource:e.installSource}:{}}}async function qe(e,n,r,i){let a,o=!1,s;try{a=await i()}catch(e){o=!0,s=e}let c=await we(e,n,r,a);if(o)throw s;if(!c)throw new t(`COMMAND_FAILED`,`Daemon request produced no response after cleanup`);return c}function Je(e,t){return e.ok||!t.ownedStateDir||!Ce(e)?e:Se(e,t.paths.baseDir)}function Ye(e,t,n){return!e.ok||!be(t,e)?e:C(e,n.ownedStateDir?n.paths.baseDir:void 0)}function Xe(e){!Ze(e)||process.stderr.isTTY!==!0||process.env.CI||process.stderr.write(e===_.reinstall?`Reinstalling...
|
|
2
2
|
`:`Installing...
|
|
3
3
|
`)}function Ze(e){return e===_.install||e===_.reinstall||e===v.installSource}async function Qe(e,t,n){let r=se(n);if(!ye(e)||!r.leaseId)return await x(n,e,new AbortController().signal);let{buildUploadLeaseHeartbeat:i,runProtectedLeaseWork:a}=await import(`./daemon-client-lease-beat.js`);return await a({heartbeat:i(e,t,n),task:t=>x(n,e,t)})}function U(e,t){return O.join(e,`metro-sessions`,`${w(t)}.json`)}function W(e){let t=U(e.stateDir,e.session);k.mkdirSync(O.dirname(t),{recursive:!0}),k.writeFileSync(t,`${JSON.stringify(e.hints,null,2)}\n`,`utf8`)}function $e(e){let t=U(e.stateDir,e.session),n;try{n=k.readFileSync(t,`utf8`)}catch{return}let r;try{r=JSON.parse(n)}catch{return}if(!r||typeof r!=`object`||Array.isArray(r))return;let i=r,a={};return typeof i.metroHost==`string`&&i.metroHost&&(a.metroHost=i.metroHost),typeof i.metroPort==`number`&&Number.isInteger(i.metroPort)&&(a.metroPort=i.metroPort),typeof i.bundleUrl==`string`&&i.bundleUrl&&(a.bundleUrl=i.bundleUrl),Object.keys(a).length>0?a:void 0}function G(e){k.rmSync(U(e.stateDir,e.session),{force:!0})}function et(e){let n=async(t,n)=>await e(v.humanControl,t,n);return{allocate:async t=>q(await e(v.leaseAllocate,[],{...t,leaseId:void 0})),heartbeat:async t=>q(await e(v.leaseHeartbeat,[],t)),release:async t=>{let n=await e(v.leaseRelease,[],t);return{released:n.released===!0,provider:f(n.provider)?n.provider:void 0}},humanControl:{list:async e=>{let r=await n([`list`],e);if(!Array.isArray(r.holds))throw new t(`COMMAND_FAILED`,`Daemon did not return human-control holds.`);return r.holds.map(K)},put:async(e,t={},r)=>K((await n([`put`,e,JSON.stringify(t)],r)).hold),remove:async(e,t)=>(await n([`remove`,e],t)).released===!0}}}function K(e){if(!f(e)||!f(e.scope)||e.state!==`active`&&e.state!==`activating`||typeof e.createdAt!=`number`||typeof e.updatedAt!=`number`)throw new t(`COMMAND_FAILED`,`Daemon returned an invalid human-control hold.`);return{id:l(e,`id`),scope:{backend:l(e.scope,`backend`),leaseProvider:u(e.scope,`leaseProvider`),deviceKey:l(e.scope,`deviceKey`)},state:e.state,reason:u(e,`reason`),createdAt:e.createdAt,updatedAt:e.updatedAt,...typeof e.expiresAt==`number`?{expiresAt:e.expiresAt}:{}}}function q(e){let t=e.lease;if(!f(t))throw Error(`Invalid lease response from daemon`);return{leaseId:l(t,`leaseId`),tenantId:l(t,`tenantId`),runId:l(t,`runId`),backend:l(t,`backend`),leaseProvider:u(t,`leaseProvider`),clientId:u(t,`clientId`),deviceKey:u(t,`deviceKey`),createdAt:typeof t.createdAt==`number`?t.createdAt:void 0,heartbeatAt:typeof t.heartbeatAt==`number`?t.heartbeatAt:void 0,expiresAt:typeof t.expiresAt==`number`?t.expiresAt:void 0}}var tt=e({createAgentDeviceClient:()=>J});function J(e={},n={}){let i=n.transport??H,o=t=>a(t.responseLevel??e.responseLevel),s=async(t,n=[],a={},o,s)=>{let c=Q(e,a),l={session:z(c.session),command:t,positionals:n,...s?{input:s}:{},flags:me(c,o),runtime:c.runtime,meta:Be(c)},u=await i(l,{authToken:c.daemonAuthToken});return u.ok||r(u.error),u.data??{}},c=async(e={})=>{let t=await s(v.sessionList,[],e);return(Array.isArray(t.sessions)?t.sessions:[]).map(ke)},d=async(e,t={})=>{let n=await He(e,t);return await s(n.command,n.positionals,n.options,n.metadataFlags,n.input)},f=(t={})=>z(Q(e,t).session);return{command:{wait:async e=>await d(`wait`,e),alert:async(e={})=>await d(`alert`,e),appState:async(e={})=>await d(`appstate`,e),back:async(e={})=>await d(`back`,e),home:async(e={})=>await d(`home`,e),orientation:async e=>await d(`orientation`,e),fold:async e=>await d(`fold`,e),appSwitcher:async(e={})=>await d(`app-switcher`,e),actionButton:async(e={})=>await d(`action-button`,e),keyboard:async(e={})=>await d(`keyboard`,e),clipboard:async e=>await d(`clipboard`,e),tvRemote:async e=>await d(`tv-remote`,e),reactNative:async e=>await d(`react-native`,e),doctor:async(e={})=>await d(`doctor`,e),prepare:async e=>await d(`prepare`,e),viewport:async e=>await d(`viewport`,e)},devices:{list:async(e={})=>{let t=await d(`devices`,e);return(Array.isArray(t.devices)?t.devices:[]).map(N)},capabilities:async(e={})=>{let t=await d(`capabilities`,e),n=Array.isArray(t.availableCommands)?t.availableCommands.filter(e=>typeof e==`string`):[];return{device:N(t.device),availableCommands:n}},boot:async(e={})=>await d(`boot`,e),shutdown:async(e={})=>await d(`shutdown`,e)},sessions:{list:async(e={})=>await c(e),stateDir:async(t={})=>{let n=Q(e,t);return S(n.stateDir??process.env.AGENT_DEVICE_STATE_DIR).baseDir},close:async(t={})=>{let n=f(t);try{let e=await d(`close`,t);return{session:n,shutdown:L(e.shutdown),provider:Z(e.provider),savedScript:u(e,`savedScript`),identifiers:{session:n}}}finally{mt(e,t)}},saveScript:async(e={})=>{let n=await s(v.sessionSaveScript,e.path===void 0?[]:[e.path],e,{force:e.force}),r=n.actionCount;if(typeof r!=`number`||!Number.isInteger(r)||r<0)throw new t(`COMMAND_FAILED`,`Daemon returned an invalid saved-script action count.`);let i=l(n,`session`);return{session:i,savedScript:l(n,`savedScript`),actionCount:r,identifiers:{session:i}}},artifacts:async(e={})=>await d(`artifacts`,e)},apps:{install:async e=>M(await d(`install`,e),f(e)),reinstall:async e=>M(await d(`reinstall`,e),f(e)),installFromSource:async e=>Ee(await d(`install-from-source`,e),f(e)),list:async(e={})=>{let t=await d(`apps`,e);return Array.isArray(t.apps)?t.apps.filter(e=>typeof e==`string`):[]},open:async t=>{let n=f(t),r=await d(`open`,t);pt({config:e,options:t,runtime:Q(e,t).runtime,sessionReused:r.sessionReused===!0});let i=je(r),a=u(r,`appBundleId`),o=a,s=he(r);return{session:n,...s.length>0?{warnings:s}:{},sessionStateDir:u(r,`sessionStateDir`),runnerLogPath:u(r,`runnerLogPath`),requestLogPath:u(r,`requestLogPath`),eventLogPath:u(r,`eventLogPath`),appName:u(r,`appName`),appBundleId:a,appId:o,selection:Pe(r.selection),startup:Fe(r.startup),runtime:Ae(r.runtime),device:i,...Re(r),identifiers:{session:n,deviceId:i?.id,deviceName:i?.name,udid:i?.ios?.udid,serial:i?.android?.serial,appId:o,appBundleId:a}}},close:async(e={})=>{let t=f(e),n=await d(`close`,e);return{session:t,closedApp:e.app,shutdown:L(n.shutdown),savedScript:u(n,`savedScript`),identifiers:{session:t}}},push:async e=>await d(`push`,e),triggerEvent:async e=>await d(`trigger-app-event`,e)},materializations:{release:async e=>De(await s(v.releaseMaterializedPaths,[],{...e,materializationId:e.materializationId}))},leases:et(s),metro:{prepare:async t=>{let n=await E({projectRoot:t.projectRoot??e.cwd,kind:t.kind,publicBaseUrl:t.publicBaseUrl,proxyBaseUrl:t.proxyBaseUrl,proxyBearerToken:t.bearerToken,bridgeScope:t.bridgeScope,launchUrl:t.launchUrl,companionProfileKey:t.companionProfileKey,companionConsumerKey:t.companionConsumerKey,metroPort:t.port,listenHost:t.listenHost,statusHost:t.statusHost,startupTimeoutMs:t.startupTimeoutMs,probeTimeoutMs:t.probeTimeoutMs,reuseExisting:t.reuseExisting,installDependenciesIfNeeded:t.installDependenciesIfNeeded,runtimeFilePath:t.runtimeFilePath,logPath:t.logPath});return ut(e,n),n},reload:async(t={})=>await T({metroHost:t.metroHost,metroPort:t.metroPort,bundleUrl:t.bundleUrl,runtime:e.runtime??dt(e),timeoutMs:t.timeoutMs})},capture:{snapshot:async(e={})=>{let t=f(e),n=await d(`snapshot`,e);return o(e)?n:ct(n,t)},screenshot:async(e={})=>{let t=f(e),n=await d(`screenshot`,e);return o(e)?n:D(n,t)},diff:async e=>await d(`diff`,e)},interactions:{click:async e=>await d(`click`,e),press:async e=>await d(`press`,e),longPress:async e=>await d(`longpress`,e),hover:async e=>await d(`hover`,e),swipe:async e=>await d(`swipe`,e),pan:async e=>await d(`gesture`,nt(e)),drag:async e=>await d(`gesture`,rt(e)),fling:async e=>await d(`gesture`,it(e)),swipeGesture:async e=>await d(`gesture`,at(e)),focus:async e=>await d(`focus`,e),type:async e=>await d(`type`,e),fill:async e=>await d(`fill`,e),scroll:async e=>await d(`scroll`,e),pinch:async e=>await d(`gesture`,Y(e)),rotateGesture:async e=>await d(`gesture`,ot(e)),transformGesture:async e=>await d(`gesture`,st(e)),get:async e=>await d(`get`,e),is:async e=>await d(`is`,e),find:async e=>await d(`find`,e)},replay:{run:async e=>await d(`replay`,e),test:async e=>await d(`test`,e)},batch:{run:async e=>await d(`batch`,e)},observability:{perf:async e=>await d(`perf`,e),logs:async(e={})=>await d(`logs`,e),events:async(e={})=>await d(`events`,e),network:async(e={})=>await d(`network`,e),audio:async(e={})=>await d(`audio`,e)},debug:{symbols:async t=>{let{symbolicateCrashArtifact:n}=await import(`./debug-symbols-facade.js`);return n({cwd:t.cwd??e.cwd,...t})}},recording:{record:async e=>await d(`record`,e),trace:async e=>await d(`trace`,e)},settings:{update:async e=>await d(`settings`,e)}}}function nt(e){let{x:t,y:n,dx:r,dy:i,...a}=e;return{...a,kind:`pan`,origin:{x:t,y:n},delta:{x:r,y:i}}}function rt(e){return{...e,kind:`drag`}}function it(e){let{x:t,y:n,...r}=e;return{...r,kind:`fling`,origin:{x:t,y:n}}}function at(e){return{...e,kind:`swipe`}}function Y(e){let{x:t,y:n,...r}=e;return X(t,n,`pinch`),{...r,kind:`pinch`,...t===void 0&&n===void 0?{}:{origin:{x:t,y:n}}}}function ot(e){let{x:t,y:n,...r}=e;return X(t,n,`rotate`),{...r,kind:`rotate`,...t===void 0&&n===void 0?{}:{origin:{x:t,y:n}}}}function st(e){let{x:t,y:n,dx:r,dy:i,...a}=e;return{...a,kind:`transform`,origin:{x:t,y:n},delta:{x:r,y:i}}}function X(e,n,r){if(e===void 0!=(n===void 0))throw new t(`INVALID_ARGS`,`gesture ${r} center requires both x and y`)}function ct(e,t){let n=u(e,`appBundleId`);return{nodes:ze(e.nodes),...typeof e.truncated==`boolean`?{truncated:e.truncated}:{},appName:u(e,`appName`),appBundleId:n,...lt(e),identifiers:{session:t,appId:n,appBundleId:n}}}function lt(e){let t=Z(e.visibility),n=Z(e.unchanged),r=c(e.keyboard),i=ne(e.snapshotDiagnostics);return{...r?{keyboard:r}:{},...t?{visibility:t}:{},...o(e),...n?{unchanged:n}:{},...i?{snapshotDiagnostics:i}:{},...typeof e.fallbackScreenshotPath==`string`?{fallbackScreenshotPath:e.fallbackScreenshotPath}:{},...typeof e.refsGeneration==`number`?{refsGeneration:e.refsGeneration}:{}}}function Z(e){return f(e)?e:void 0}function Q(e,t){return{...e,...t}}function $(e,t={}){let n=Q(e,t);return{stateDir:S(n.stateDir??process.env.AGENT_DEVICE_STATE_DIR).baseDir,session:z(n.session)}}function ut(e,t){try{let n=new URL(t.statusUrl),r=Number.parseInt(n.port,10);if(!n.hostname||!Number.isInteger(r))return;let i=t.bridge?void 0:t.iosRuntime.bundleUrl??t.androidRuntime.bundleUrl;W({...$(e),hints:{metroHost:n.hostname,metroPort:r,bundleUrl:i}})}catch{}}function dt(e){try{return $e($(e))}catch{return}}function ft(e){if(!e)return;let{metroHost:t,metroPort:n,bundleUrl:r}=e;if(t!==void 0||n!==void 0||r!==void 0)return{metroHost:t,metroPort:n,bundleUrl:r}}function pt(e){try{let t=$(e.config,e.options),n=ft(e.runtime);if(n){W({...t,hints:n});return}e.sessionReused||G(t)}catch{}}function mt(e,t){try{G($(e,t))}catch{}}export{J as n,H as r,tt as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{N as e}from"./sdk-contracts.js";import{o as t,p as n,r,t as i}from"./lease-scope.js";import{an as a,w as o}from"./sdk-batch.js";import{t as s}from"./catalog.js";import{n as c,r as l}from"./diagnostics.js";import"./diagnostics2.js";import{
|
|
1
|
+
import{N as e}from"./sdk-contracts.js";import{o as t,p as n,r,t as i}from"./lease-scope.js";import{an as a,w as o}from"./sdk-batch.js";import{t as s}from"./catalog.js";import{n as c,r as l}from"./diagnostics.js";import"./diagnostics2.js";import{i as u,l as d}from"./daemon-client-transport.js";const f=new Set([`LEASE_SCOPE_REQUIRED`,`LEASE_SCOPE_MISMATCH`]);function p(t){return r(t)||t instanceof e&&(f.has(t.details?.reason)||t.code===`INVALID_ARGS`)}async function m(e){let{heartbeat:t}=e;if(!t)return await e.task(new AbortController().signal);let n=new AbortController,r=i,a=h(r),o,s=!1,c,u,d=new Promise((e,t)=>{u=t}),f=()=>{let e=e=>{s||(o&&clearTimeout(o),o=setTimeout(f,e))};e(a),(async()=>{let i=r;try{let n=g(await t(i));if(n===void 0||n===r)return;let o=h(n);r=n,a=o,e(o)}catch(e){if(p(e)){if(c=e,s){l({level:`warn`,phase:`lease_lost_after_phase`,data:{message:e instanceof Error?e.message:String(e)}});return}n.abort(),u?.(e);return}l({level:`warn`,phase:`lease_heartbeat_failed`,data:{message:e instanceof Error?e.message:String(e)}})}})().catch(()=>void 0)};o=setTimeout(f,0),d.catch(()=>void 0);let m=await _((async()=>await Promise.race([e.task(n.signal),d]))());if(s=!0,o&&clearTimeout(o),c!==void 0)throw c;if(!m.ok)throw m.error;return m.value}function h(e){return Math.max(1e3,Math.floor(e/3))}function g(e){let t=e?.data?.lease,n=t?.expiresAt,r=t?.heartbeatAt;if(typeof n==`number`&&typeof r==`number`)return n>r?n-r:void 0}async function _(e){try{return{ok:!0,value:await e}}catch(e){return{ok:!1,error:e}}}function v(e,t){return{command:s.leaseHeartbeat,positionals:[],session:t.session,token:t.token,meta:{...n(e),sessionIsolation:t.sessionIsolation,requestId:t.requestId}}}function y(e,n,r){if(!d(e))return;let i=t(r);if(!i.leaseId)return;let l=a(o(s.leaseHeartbeat),{positionals:[]});return async t=>await u(e,v(i,{session:r.session,sessionIsolation:r.meta?.sessionIsolation,requestId:c(),token:e.token}),n.transportPreference,n.paths,l===void 0?t:Math.min(l,t))}export{y as buildUploadLeaseHeartbeat,m as runProtectedLeaseWork};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{N as e,U as t}from"./sdk-contracts.js";import{n}from"./catalog.js";import{r}from"./diagnostics.js";import{C as i}from"./owner-identity.js";import{d as a}from"./exec.js";import{t as o}from"./timeouts.js";import"./diagnostics2.js";import"./command.js";import{c as s,d as c,f as l,g as u,h as d,i as f,l as p,m,o as h,p as g,r as _,s as v,u as ee}from"./daemon-client-transport.js";import{i as y}from"./replay-divergence.js";import{s as b}from"./device-shell.js";import"./process.js";import"./retry.js";import{t as x}from"./session-repair-tombstone.js";import{a as S,i as C,o as w,r as T}from"./version.js";import{t as E}from"./ttl-memo.js";import{n as te,r as ne,t as re}from"./daemon-resolution.js";import{i as ie,n as ae}from"./code-signature.js";import D from"node:path";import O from"node:fs";import k from"node:os";import A from"node:net";const j=E();function M(){let t=j.get(`local`);if(t)return t;let n=T(),r=[D.join(n,`dist`,`src`,`internal`,`daemon.js`),D.join(n,`dist`,`src`,`daemon.js`)],i=r[0];if(i===void 0)throw new e(`COMMAND_FAILED`,`Daemon dist path list is empty`);let a=r.find(e=>O.existsSync(e))??i,o=D.join(n,w),s=r.some(e=>O.existsSync(e)),c=O.existsSync(o);if(!s&&!c)throw new e(`COMMAND_FAILED`,`Daemon entry not found`,{distPaths:r,srcPath:o});let l={root:n,distPath:a,distPaths:r,srcPath:o,useSrc:(process.execArgv.includes(`--experimental-strip-types`)||!s)&&c};return j.set(`local`,l),l}async function N(){let e=M(),t=ie(e.root);if(t===`installed`)return{origin:t};if(!e.useSrc)return{origin:t,codeSignature:ae(e.distPath,e.root)};let{resolveCachedDaemonCodeSignature:n}=await import(`./code-signature-cache.js`);return{origin:t,codeSignature:await n(e.srcPath,e.root)}}async function P(e,t){let n=S();if(e.version!==n)return e.version&&C(e.version,n)&&await t.onAnyAdvertisedTransport()?{kind:`refuseNewer`,daemonVersion:e.version,clientVersion:n}:{kind:`replace`,reason:`version mismatch (client v${n})`};let r=F(await N(),e);return r?{kind:`replace`,reason:r}:t.viaClientTransport?{kind:`reuse`}:{kind:`replace`,reason:`unreachable`}}function F(e,t){return e.origin===`installed`?t.codeOrigin===`installed`?void 0:I(e,t):t.codeOrigin===`installed`?I(e,t):t.codeSignature===e.codeSignature?void 0:`code-signature mismatch`}function I(e,t){return`code origin mismatch (daemon ${t.codeOrigin??`unreported`}, client ${e.origin})`}const L=15e3,R=new A.BlockList;R.addSubnet(`127.0.0.0`,8,`ipv4`),R.addAddress(`::1`,`ipv6`),R.addSubnet(`::ffff:127.0.0.0`,104,`ipv6`);function z(e,t){let n=B(e),r=V(e,t),i=H(e,r.remoteBaseUrl),a=U(e,n,r.rawBaseUrl),o=a?W():n;return{paths:re(o),transportPreference:i.preference,serverMode:i.serverMode,ownedStateDir:a,remoteBaseUrl:r.remoteBaseUrl,remoteAuthToken:r.authToken}}function B(e){return e.flags?.stateDir??process.env.AGENT_DEVICE_STATE_DIR}function V(e,t){let n=e.flags?.daemonBaseUrl??process.env.AGENT_DEVICE_DAEMON_BASE_URL,r=ye(n),i=t??process.env.AGENT_DEVICE_DAEMON_AUTH_TOKEN;return be(r,i),{rawBaseUrl:n,remoteBaseUrl:r,authToken:i}}function H(t,n){let r=t.flags?.daemonTransport??process.env.AGENT_DEVICE_DAEMON_TRANSPORT,i=ne(r);if(n&&i===`socket`)throw new e(`INVALID_ARGS`,`Remote daemon base URL only supports HTTP transport. Remove --daemon-transport socket.`,{daemonBaseUrl:n});let a=t.flags?.daemonServerMode??process.env.AGENT_DEVICE_DAEMON_SERVER_MODE??(r===`dual`?`dual`:void 0);return{preference:i,serverMode:te(a)}}function U(e,t,n){return X(e.command)&&!t&&!n}function W(){return O.mkdtempSync(D.join(k.tmpdir(),`agent-device-replay-daemon-`))}async function G(e){if(e.remoteBaseUrl)return await oe(e);let t=await K(e);return await se(t.info,e.paths.baseDir),t}async function K(e){let t=await q(e);return t?{info:t,startedByClient:!1}:(v(e.paths),await de(e))}async function oe(t){let n={transport:`http`,token:t.remoteAuthToken??``,pid:0,baseUrl:t.remoteBaseUrl},r=await _(n);if(r.reachable)return n.remoteInstanceId=r.instanceId,n.remoteUpstreamInstanceId=r.upstream?.instanceId,{info:n,startedByClient:!1};throw new e(`COMMAND_FAILED`,`Remote daemon is unavailable`,{daemonBaseUrl:t.remoteBaseUrl,hint:`Verify AGENT_DEVICE_DAEMON_BASE_URL points to a reachable daemon with GET /health and POST /rpc. If this CLI was connected with connect proxy, run agent-device disconnect to return to the local daemon.`})}async function q(e){let t=c(e.paths.infoPath);if(!t)return null;let n=await J(t,e.transportPreference),r=await P(t,{viaClientTransport:n,onAnyAdvertisedTransport:async()=>n||await J(t,`auto`)});if(r.kind===`reuse`)return t;if(r.kind===`refuseNewer`)throw le(t,r,e.paths.baseDir);return ue(t,r.reason,e.paths.baseDir),await u(t),g(e.paths.infoPath),null}async function se(t,n){if(!process.env.AGENT_DEVICE_DAEMON_POLICY?.trim())return;let{loadDaemonPolicy:r}=await import(`./daemon-policy-file.js`).then(e=>e.t),i=r(process.env)?.digest;if(i!==t.policyDigest)throw new e(`COMMAND_FAILED`,`The running daemon does not enforce the daemon policy named by AGENT_DEVICE_DAEMON_POLICY.`,{reason:`DAEMON_POLICY_MISMATCH`,expectedPolicyDigest:i,daemonPolicyDigest:t.policyDigest??null,hint:`Stop the running daemon (agent-device daemon stop --state-dir ${b(n)}), then retry so a daemon starts with this policy.`})}async function J(e,t){try{return await f(e,t)}catch(e){if(ce(e))return!1;throw e}}function ce(t){return t instanceof e&&t.code===`COMMAND_FAILED`&&(t.message===`Daemon HTTP endpoint is unavailable`||t.message===`Daemon socket endpoint is unavailable`)}function le(t,n,r){let{daemonVersion:i,clientVersion:a}=n;return new e(`COMMAND_FAILED`,`Daemon (pid ${t.pid}, v${i}) is newer than this client (v${a}); refusing to replace it.`,{daemonPid:t.pid,daemonVersion:i,clientVersion:a,hint:`Use the agent-device v${i} CLI that started it, or stop it deliberately: agent-device daemon stop --state-dir ${b(r)}`})}function ue(e,t,n){try{let r=e.version?`pid ${e.pid}, v${e.version}`:`pid ${e.pid}`;process.stderr.write(`Replacing daemon (${r}) in ${n}: ${t}\n`)}catch{}}async function de(t){let n=0,r=[],i,a;for(let e=1;e<=2;e+=1){let c;try{c=_e(t),a={pid:c.pid}}catch(n){if(i=n instanceof Error?n.message:String(n),r.push(await h(t.paths,`start_error`)),e<2){await o(150);continue}break}let u=await Q(L,t,c);if(u.kind===`ready`)return u.daemon;if(u.kind===`early_exit`){if(a=u.exit,i=$(u.exit),r.push(await h(t.paths,`start_error`)),e<2){await o(150);continue}break}if(await l(t.paths)){n+=1;continue}let d=s(t.paths),f=e<2,p=await h(t.paths,`startup_timeout`,{stopLiveProcesses:!1});if(r.push(p),p.retainedInfoProcess||p.retainedLockProcess){let e=await Q(L,t,c);if(e.kind===`ready`)return e.daemon;e.kind===`early_exit`&&(a=e.exit,i=$(e.exit));break}if(!f)break;!d.hasInfo&&!d.hasLock&&await o(150)}let c=s(t.paths),u=ve(t.paths.logPath);throw new e(`COMMAND_FAILED`,`Failed to start daemon`,{kind:`daemon_startup_failed`,stateDir:t.paths.baseDir,infoPath:t.paths.infoPath,lockPath:t.paths.lockPath,logPath:t.paths.logPath,startupTimeoutMs:L,startupAttempts:2,lockRecoveryCount:n,cleanupResults:r,startError:i,daemonProcess:a,...u?{daemonLogTail:u}:{},metadataState:c,hint:d(c,t.paths)})}async function fe(e,t,n,i){if(!X(e.command)||!t.startedByClient&&!n.ownedStateDir||ee(t.info)||Y(i)||Z(e,i))return i;let a={pid:t.info.pid,removedInfo:!1,removedLock:!1,removedStateDir:!1,error:void 0},o=i;try{await u(t.info)}catch(e){a.error=e instanceof Error?e.message:String(e)}finally{let e=O.existsSync(n.paths.infoPath);g(n.paths.infoPath),a.removedInfo=e&&!O.existsSync(n.paths.infoPath);let t=O.existsSync(n.paths.lockPath);if(m(n.paths.lockPath),a.removedLock=t&&!O.existsSync(n.paths.lockPath),n.ownedStateDir){let e=x(n.paths.sessionsDir);e?o=pe(i,e):(O.rmSync(n.paths.baseDir,{recursive:!0,force:!0}),a.removedStateDir=!O.existsSync(n.paths.baseDir))}}return r({level:a.error?`warn`:`info`,phase:`daemon_replay_cleanup`,data:a}),o}function pe(n,r){if(n&&!n.ok)return n;let{sessionName:i,tombstone:a}=r,o=a.sourcePath?`re-run: replay ${a.sourcePath} --save-script`:`re-run your replay <script> --save-script from the start`,s=`The repair transaction for session "${i}" completed, but committing its healed script failed at teardown: ${a.commitFailure.message}. ${o}.`;return{ok:!1,error:t(new e(`REPAIR_COMMIT_FAILED`,s))}}function Y(e){return!e||e.ok||e.error.code!==`REPLAY_DIVERGENCE`?!1:y(e.error.details?.divergence)?.repairSessionHeld===!0}function me(e,t){let n=`This repair session's daemon was kept alive to continue the repair; pass --state-dir ${t} on your next command (press, replay --from, or close --save-script) to reach it.`,r=e.error.hint;return{...e,error:{...e.error,hint:r?`${r} ${n}`:n}}}function X(e){return e===n.replay||e===n.test}function Z(e,t){return e.command!==n.replay||!t||!t.ok?!1:t.data?.sessionActive===!0}function he(e,t){let n=e.data??{},r=typeof n.session==`string`?n.session:void 0,i=[...t?[`--state-dir ${b(t)}`]:[],...r?[`--session ${b(r)}`]:[]];if(i.length===0)return e;let a=`This session's daemon was kept alive because its script left the session active; pass ${i.join(` `)} on your next command to reach it.`,o=typeof n.message==`string`?n.message:void 0;return{...e,data:{...n,hint:a,message:o?`${o} ${a}`:a}}}async function Q(e,t,n){let r=Date.now(),i;for(n.exited.then(e=>{i=e});Date.now()-r<e;){let e=c(t.paths.infoPath);if(e&&await f(e,t.transportPreference)){if(ge(e,n))return{kind:`ready`,daemon:{info:e,startedByClient:!0}};let r=await q(t);if(r)return{kind:`ready`,daemon:{info:r,startedByClient:!1}}}if(i&&!p(t.paths,i.pid))return{kind:`early_exit`,exit:i};await o(100)}return{kind:`timeout`}}function ge(e,t){return e.pid===t.pid&&t.startTime!==void 0&&e.processStartTime===t.startTime}function _e(e){let t=M(),n=t.useSrc?[`--experimental-strip-types`,t.srcPath]:[t.distPath],r={...process.env,AGENT_DEVICE_STATE_DIR:e.paths.baseDir,AGENT_DEVICE_DAEMON_SERVER_MODE:e.serverMode};O.mkdirSync(e.paths.baseDir,{recursive:!0});let o=O.openSync(e.paths.logPath,`a`),s=O.openSync(e.paths.logPath,`a`);try{let e=a(process.execPath,n,{env:r,stdio:[`ignore`,o,s]});return{...e,startTime:i(e.pid)??void 0}}finally{O.closeSync(o),O.closeSync(s)}}function $(e){return e.error?`daemon process ${e.pid} failed to start: ${e.error}`:e.signal?`daemon process ${e.pid} exited before readiness with signal ${e.signal}`:`daemon process ${e.pid} exited before readiness with code ${e.exitCode??0}`}function ve(e){try{if(!O.existsSync(e))return;let t=O.statSync(e);if(t.size<=0)return;let n=Math.min(t.size,64e3),r=O.openSync(e,`r`);try{let e=Buffer.alloc(n);O.readSync(r,e,0,n,t.size-n);let i=e.toString(`utf8`).trim();return i.length>0?i:void 0}finally{O.closeSync(r)}}catch{return}}function ye(t){if(!t)return;let n;try{n=new URL(t)}catch(n){throw new e(`INVALID_ARGS`,`Invalid daemon base URL`,{daemonBaseUrl:t},n instanceof Error?n:void 0)}if(n.protocol!==`http:`&&n.protocol!==`https:`)throw new e(`INVALID_ARGS`,`Daemon base URL must use http or https`,{daemonBaseUrl:t});return n.toString().replace(/\/+$/,``)}function be(t,n){if(!t)return;let r=new URL(t).hostname;if(!xe(r)&&!(typeof n==`string`&&n.trim().length>0))throw new e(`INVALID_ARGS`,`Remote daemon base URL for non-loopback hosts requires daemon authentication`,{daemonBaseUrl:t,hint:`Provide --daemon-auth-token or AGENT_DEVICE_DAEMON_AUTH_TOKEN when using a non-loopback remote daemon URL.`})}function xe(e){let t=e.trim().toLowerCase().replace(/^\[(.*)\]$/,`$1`);return t===`localhost`?!0:A.isIPv4(t)?R.check(t,`ipv4`):A.isIPv6(t)?R.check(t,`ipv6`):!1}export{Z as a,G as i,me as n,Y as o,fe as r,z as s,he as t};
|
|
1
|
+
import{N as e,U as t}from"./sdk-contracts.js";import{n}from"./catalog.js";import{r}from"./diagnostics.js";import{C as i,p as a}from"./owner-identity.js";import{d as o}from"./exec.js";import{t as s}from"./timeouts.js";import"./diagnostics2.js";import"./command.js";import{a as c,c as l,d as u,f as d,h as f,l as p,m,n as h,o as g,p as _,r as v,s as y,t as b,u as x}from"./daemon-client-transport.js";import{i as S}from"./replay-divergence.js";import{s as C}from"./device-shell.js";import"./process.js";import"./retry.js";import{t as w}from"./session-repair-tombstone.js";import{a as T,i as ee,o as te,r as ne}from"./version.js";import{t as re}from"./ttl-memo.js";import{n as ie,r as ae,t as oe}from"./daemon-resolution.js";import{i as se,n as E}from"./code-signature.js";import D from"node:path";import O from"node:fs";import k from"node:os";import A from"node:net";const j=re();function M(){let t=j.get(`local`);if(t)return t;let n=ne(),r=[D.join(n,`dist`,`src`,`internal`,`daemon.js`),D.join(n,`dist`,`src`,`daemon.js`)],i=r[0];if(i===void 0)throw new e(`COMMAND_FAILED`,`Daemon dist path list is empty`);let a=r.find(e=>O.existsSync(e))??i,o=D.join(n,te),s=r.some(e=>O.existsSync(e)),c=O.existsSync(o);if(!s&&!c)throw new e(`COMMAND_FAILED`,`Daemon entry not found`,{distPaths:r,srcPath:o});let l={root:n,distPath:a,distPaths:r,srcPath:o,useSrc:(process.execArgv.includes(`--experimental-strip-types`)||!s)&&c};return j.set(`local`,l),l}async function N(){let e=M(),t=se(e.root);if(t===`installed`)return{origin:t};if(!e.useSrc)return{origin:t,codeSignature:E(e.distPath,e.root)};let{resolveCachedDaemonCodeSignature:n}=await import(`./code-signature-cache.js`);return{origin:t,codeSignature:await n(e.srcPath,e.root)}}async function P(e,t){let n=T();if(e.version!==n)return e.version&&ee(e.version,n)&&await t.onAnyAdvertisedTransport()?{kind:`refuseNewer`,daemonVersion:e.version,clientVersion:n}:{kind:`replace`,reason:`version mismatch (client v${n})`};let r=F(await N(),e);return r?{kind:`replace`,reason:r}:await t.onClientTransport()?{kind:`reuse`}:{kind:`replace`,reason:`unreachable`}}function F(e,t){return e.origin===`installed`?t.codeOrigin===`installed`?void 0:I(e,t):t.codeOrigin===`installed`?I(e,t):t.codeSignature===e.codeSignature?void 0:`code-signature mismatch`}function I(e,t){return`code origin mismatch (daemon ${t.codeOrigin??`unreported`}, client ${e.origin})`}const L=15e3,R=new A.BlockList;R.addSubnet(`127.0.0.0`,8,`ipv4`),R.addAddress(`::1`,`ipv6`),R.addSubnet(`::ffff:127.0.0.0`,104,`ipv6`);function z(e,t){let n=B(e),r=V(e,t),i=H(e,r.remoteBaseUrl),a=U(e,n,r.rawBaseUrl),o=a?W():n;return{paths:oe(o),transportPreference:i.preference,serverMode:i.serverMode,ownedStateDir:a,remoteBaseUrl:r.remoteBaseUrl,remoteAuthToken:r.authToken}}function B(e){return e.flags?.stateDir??process.env.AGENT_DEVICE_STATE_DIR}function V(e,t){let n=e.flags?.daemonBaseUrl??process.env.AGENT_DEVICE_DAEMON_BASE_URL,r=xe(n),i=t??process.env.AGENT_DEVICE_DAEMON_AUTH_TOKEN;return Se(r,i),{rawBaseUrl:n,remoteBaseUrl:r,authToken:i}}function H(t,n){let r=t.flags?.daemonTransport??process.env.AGENT_DEVICE_DAEMON_TRANSPORT,i=ae(r);if(n&&i===`socket`)throw new e(`INVALID_ARGS`,`Remote daemon base URL only supports HTTP transport. Remove --daemon-transport socket.`,{daemonBaseUrl:n});let a=t.flags?.daemonServerMode??process.env.AGENT_DEVICE_DAEMON_SERVER_MODE??(r===`dual`?`dual`:void 0);return{preference:i,serverMode:ie(a)}}function U(e,t,n){return X(e.command)&&!t&&!n}function W(){return O.mkdtempSync(D.join(k.tmpdir(),`agent-device-replay-daemon-`))}async function G(e){if(e.remoteBaseUrl)return await le(e);let t=await ce(e);return await ue(t.info,e.paths.baseDir),t}async function ce(e){let t=await K(e);return t?{info:t,startedByClient:!1}:(g(e.paths),await pe(e))}async function le(t){let n={transport:`http`,token:t.remoteAuthToken??``,pid:0,baseUrl:t.remoteBaseUrl},r=await b(n);if(r.reachable)return n.remoteInstanceId=r.instanceId,n.remoteUpstreamInstanceId=r.upstream?.instanceId,{info:n,startedByClient:!1};throw new e(`COMMAND_FAILED`,`Remote daemon is unavailable`,{daemonBaseUrl:t.remoteBaseUrl,hint:`Verify AGENT_DEVICE_DAEMON_BASE_URL points to a reachable daemon with GET /health and POST /rpc. If this CLI was connected with connect proxy, run agent-device disconnect to return to the local daemon.`})}async function K(e){let t=x(e.paths.infoPath);if(!t)return null;let n=await P(t,{onClientTransport:()=>q(t,e.transportPreference),onAnyAdvertisedTransport:()=>q(t,`auto`)});if(n.kind===`reuse`)return t;if(n.kind===`refuseNewer`)throw de(t,n,e.paths.baseDir);return fe(t,n.reason,e.paths.baseDir),await f(t),d(e.paths.infoPath),null}async function q(e,t){if(await J(e,t))return!0;for(let n=1;n<=3;n+=1){if(!a(e.pid))return!1;if(await s(200),await J(e,t))return r({level:`warn`,phase:`daemon_probe_recovered`,data:{pid:e.pid,retry:n}}),!0}return!1}async function ue(t,n){if(!process.env.AGENT_DEVICE_DAEMON_POLICY?.trim())return;let{loadDaemonPolicy:r}=await import(`./daemon-policy-file.js`).then(e=>e.t),i=r(process.env)?.digest;if(i!==t.policyDigest)throw new e(`COMMAND_FAILED`,`The running daemon does not enforce the daemon policy named by AGENT_DEVICE_DAEMON_POLICY.`,{reason:`DAEMON_POLICY_MISMATCH`,expectedPolicyDigest:i,daemonPolicyDigest:t.policyDigest??null,hint:`Stop the running daemon (agent-device daemon stop --state-dir ${C(n)}), then retry so a daemon starts with this policy.`})}async function J(e,t){try{return await h(e,t)}catch(e){if(v(e))return!1;throw e}}function de(t,n,r){let{daemonVersion:i,clientVersion:a}=n;return new e(`COMMAND_FAILED`,`Daemon (pid ${t.pid}, v${i}) is newer than this client (v${a}); refusing to replace it.`,{daemonPid:t.pid,daemonVersion:i,clientVersion:a,hint:`Use the agent-device v${i} CLI that started it, or stop it deliberately: agent-device daemon stop --state-dir ${C(r)}`})}function fe(e,t,n){try{let r=e.version?`pid ${e.pid}, v${e.version}`:`pid ${e.pid}`;process.stderr.write(`Replacing daemon (${r}) in ${n}: ${t}\n`)}catch{}}async function pe(t){let n=0,r=[],i,a;for(let e=1;e<=2;e+=1){let o;try{o=ye(t),a={pid:o.pid}}catch(n){if(i=n instanceof Error?n.message:String(n),r.push(await c(t.paths,`start_error`)),e<2){await s(150);continue}break}let l=await Q(L,t,o);if(l.kind===`ready`)return l.daemon;if(l.kind===`early_exit`){if(a=l.exit,i=$(l.exit),r.push(await c(t.paths,`start_error`)),e<2){await s(150);continue}break}if(await u(t.paths)){n+=1;continue}let d=y(t.paths),f=e<2,p=await c(t.paths,`startup_timeout`,{stopLiveProcesses:!1});if(r.push(p),p.retainedInfoProcess||p.retainedLockProcess){let e=await Q(L,t,o);if(e.kind===`ready`)return e.daemon;e.kind===`early_exit`&&(a=e.exit,i=$(e.exit));break}if(!f)break;!d.hasInfo&&!d.hasLock&&await s(150)}let o=y(t.paths),l=be(t.paths.logPath);throw new e(`COMMAND_FAILED`,`Failed to start daemon`,{kind:`daemon_startup_failed`,stateDir:t.paths.baseDir,infoPath:t.paths.infoPath,lockPath:t.paths.lockPath,logPath:t.paths.logPath,startupTimeoutMs:L,startupAttempts:2,lockRecoveryCount:n,cleanupResults:r,startError:i,daemonProcess:a,...l?{daemonLogTail:l}:{},metadataState:o,hint:m(o,t.paths)})}async function me(e,t,n,i){if(!X(e.command)||!t.startedByClient&&!n.ownedStateDir||p(t.info)||Y(i)||Z(e,i))return i;let a={pid:t.info.pid,removedInfo:!1,removedLock:!1,removedStateDir:!1,error:void 0},o=i;try{await f(t.info)}catch(e){a.error=e instanceof Error?e.message:String(e)}finally{let e=O.existsSync(n.paths.infoPath);d(n.paths.infoPath),a.removedInfo=e&&!O.existsSync(n.paths.infoPath);let t=O.existsSync(n.paths.lockPath);if(_(n.paths.lockPath),a.removedLock=t&&!O.existsSync(n.paths.lockPath),n.ownedStateDir){let e=w(n.paths.sessionsDir);e?o=he(i,e):(O.rmSync(n.paths.baseDir,{recursive:!0,force:!0}),a.removedStateDir=!O.existsSync(n.paths.baseDir))}}return r({level:a.error?`warn`:`info`,phase:`daemon_replay_cleanup`,data:a}),o}function he(n,r){if(n&&!n.ok)return n;let{sessionName:i,tombstone:a}=r,o=a.sourcePath?`re-run: replay ${a.sourcePath} --save-script`:`re-run your replay <script> --save-script from the start`,s=`The repair transaction for session "${i}" completed, but committing its healed script failed at teardown: ${a.commitFailure.message}. ${o}.`;return{ok:!1,error:t(new e(`REPAIR_COMMIT_FAILED`,s))}}function Y(e){return!e||e.ok||e.error.code!==`REPLAY_DIVERGENCE`?!1:S(e.error.details?.divergence)?.repairSessionHeld===!0}function ge(e,t){let n=`This repair session's daemon was kept alive to continue the repair; pass --state-dir ${t} on your next command (press, replay --from, or close --save-script) to reach it.`,r=e.error.hint;return{...e,error:{...e.error,hint:r?`${r} ${n}`:n}}}function X(e){return e===n.replay||e===n.test}function Z(e,t){return e.command!==n.replay||!t||!t.ok?!1:t.data?.sessionActive===!0}function _e(e,t){let n=e.data??{},r=typeof n.session==`string`?n.session:void 0,i=[...t?[`--state-dir ${C(t)}`]:[],...r?[`--session ${C(r)}`]:[]];if(i.length===0)return e;let a=`This session's daemon was kept alive because its script left the session active; pass ${i.join(` `)} on your next command to reach it.`,o=typeof n.message==`string`?n.message:void 0;return{...e,data:{...n,hint:a,message:o?`${o} ${a}`:a}}}async function Q(e,t,n){let r=Date.now(),i;for(n.exited.then(e=>{i=e});Date.now()-r<e;){let e=x(t.paths.infoPath);if(e&&await h(e,t.transportPreference)){if(ve(e,n))return{kind:`ready`,daemon:{info:e,startedByClient:!0}};let r=await K(t);if(r)return{kind:`ready`,daemon:{info:r,startedByClient:!1}}}if(i&&!l(t.paths,i.pid))return{kind:`early_exit`,exit:i};await s(100)}return{kind:`timeout`}}function ve(e,t){return e.pid===t.pid&&t.startTime!==void 0&&e.processStartTime===t.startTime}function ye(e){let t=M(),n=t.useSrc?[`--experimental-strip-types`,t.srcPath]:[t.distPath],r={...process.env,AGENT_DEVICE_STATE_DIR:e.paths.baseDir,AGENT_DEVICE_DAEMON_SERVER_MODE:e.serverMode};O.mkdirSync(e.paths.baseDir,{recursive:!0});let a=O.openSync(e.paths.logPath,`a`),s=O.openSync(e.paths.logPath,`a`);try{let e=o(process.execPath,n,{env:r,stdio:[`ignore`,a,s]});return{...e,startTime:i(e.pid)??void 0}}finally{O.closeSync(a),O.closeSync(s)}}function $(e){return e.error?`daemon process ${e.pid} failed to start: ${e.error}`:e.signal?`daemon process ${e.pid} exited before readiness with signal ${e.signal}`:`daemon process ${e.pid} exited before readiness with code ${e.exitCode??0}`}function be(e){try{if(!O.existsSync(e))return;let t=O.statSync(e);if(t.size<=0)return;let n=Math.min(t.size,64e3),r=O.openSync(e,`r`);try{let e=Buffer.alloc(n);O.readSync(r,e,0,n,t.size-n);let i=e.toString(`utf8`).trim();return i.length>0?i:void 0}finally{O.closeSync(r)}}catch{return}}function xe(t){if(!t)return;let n;try{n=new URL(t)}catch(n){throw new e(`INVALID_ARGS`,`Invalid daemon base URL`,{daemonBaseUrl:t},n instanceof Error?n:void 0)}if(n.protocol!==`http:`&&n.protocol!==`https:`)throw new e(`INVALID_ARGS`,`Daemon base URL must use http or https`,{daemonBaseUrl:t});return n.toString().replace(/\/+$/,``)}function Se(t,n){if(!t)return;let r=new URL(t).hostname;if(!Ce(r)&&!(typeof n==`string`&&n.trim().length>0))throw new e(`INVALID_ARGS`,`Remote daemon base URL for non-loopback hosts requires daemon authentication`,{daemonBaseUrl:t,hint:`Provide --daemon-auth-token or AGENT_DEVICE_DAEMON_AUTH_TOKEN when using a non-loopback remote daemon URL.`})}function Ce(e){let t=e.trim().toLowerCase().replace(/^\[(.*)\]$/,`$1`);return t===`localhost`?!0:A.isIPv4(t)?R.check(t,`ipv4`):A.isIPv6(t)?R.check(t,`ipv6`):!1}export{Z as a,G as i,ge as n,Y as o,me as r,z as s,_e as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{N as e,Q as t,W as n,X as r}from"./sdk-contracts.js";import{d as i,m as a,o}from"./lease-scope.js";import{w as s}from"./sdk-batch.js";import{n as c}from"./catalog.js";import{n as l,r as u}from"./diagnostics.js";import{c as d,p as f}from"./exec.js";import"./diagnostics2.js";import{r as p,t as m}from"./output-path.js";import{_ as h,f as ee,g as te,i as ne,m as g,n as _,s as re,t as v}from"./transport.js";import"./command.js";import{o as ie}from"./device-shell.js";import{a as ae}from"./version.js";import{t as oe}from"./daemon-resolution.js";import{n as se,t as y}from"./daemon-process.js";import{n as ce,o as le,t as ue}from"./request-progress-protocol.js";import{t as de}from"./session-artifact-paths.js";import b from"node:path";import x from"node:fs";import{createHash as fe,randomUUID as pe}from"node:crypto";import me from"node:os";import{Transform as he,Writable as ge}from"node:stream";import{pipeline as _e}from"node:stream/promises";import ve from"node:net";async function ye(e,t){let n=x.statSync(e),r=b.basename(e),i=n.isDirectory(),a=Se(t)??xe(e,n),o=[];try{let t=i?await be(e,o):e,n=x.statSync(t);return{payloadPath:t,fileName:r,artifactType:i?`app-bundle`:`file`,platform:a,contentType:i?`application/gzip`:`application/octet-stream`,sha256:await Ce(t),sizeBytes:n.size,cleanup:()=>S(o)}}catch(e){throw S(o),e}}async function be(e,t){let n=x.mkdtempSync(b.join(me.tmpdir(),`agent-device-upload-${pe()}-`));t.push(n);let r=b.join(n,`${b.basename(e)}.tar.gz`);return await d(`tar`,[`czf`,r,`-C`,b.dirname(e),b.basename(e)],{env:{...process.env,COPYFILE_DISABLE:`1`}}),r}function xe(e,t){let n=e.toLowerCase();if(t.isDirectory()&&n.endsWith(`.app`)||n.endsWith(`.ipa`))return`ios`;if(n.endsWith(`.apk`)||n.endsWith(`.aab`))return`android`}function Se(e){return e===`ios`||e===`android`?e:void 0}function S(e){for(let t of e)x.rmSync(t,{recursive:!0,force:!0})}async function Ce(t){let n=fe(`sha256`),r=new ge({write(e,t,r){n.update(e),r()}});return await _e(x.createReadStream(t),r).catch(t=>{throw new e(`COMMAND_FAILED`,`Failed to read local artifact`,{},t instanceof Error?t:void 0)}),n.digest(`hex`)}function we(e){let{stage:t,fileName:n,startOffset:r,totalBytes:i,onProgress:a}=e,o=r,s=De(i),c=Math.min(i,r+s);return new he({transform(e,r,l){o=Math.min(i,o+e.byteLength),o>=c&&(a?.({type:`progress`,stage:t,fileName:n,transferredBytes:o,totalBytes:i}),c=Math.min(i,o+s)),l(null,e)}})}function Te(){if(!(process.stderr.isTTY!==!0||process.env.CI))return e=>{process.stderr.write(`${Ee(e)}\n`)}}function Ee(e){switch(e.type){case`start`:return`Uploading ${e.fileName} (${w(e.totalBytes)}) via ${C(e.stage)} upload`;case`resume`:return`Resuming ${e.fileName} at ${w(e.transferredBytes)} of ${w(e.totalBytes)}`;case`progress`:return`Uploaded ${w(e.transferredBytes)} of ${w(e.totalBytes)} (${Oe(e.transferredBytes,e.totalBytes)})`;case`fallback`:return`Direct upload did not complete; retrying ${e.fileName} with ${C(e.to)} upload`}}function De(e){return Math.max(8388608,Math.ceil(e*.05))}function C(e){return e===`direct`?`direct`:`legacy`}function Oe(e,t){return t<=0?`100%`:`${Math.min(100,Math.floor(e/t*100))}%`}function w(e){if(e<1024)return`${e} B`;let t=e/1024;if(t<1024)return`${t.toFixed(1)} KiB`;let n=t/1024;return n<1024?`${n.toFixed(1)} MiB`:`${(n/1024).toFixed(1)} GiB`}const T=3e5,E=`uploadStreamRetryable`;async function D(e){return await O({...e,url:e.url,redirectCount:0,startOffset:0})}function ke(t){return t instanceof e&&t.details?.[E]===!0}async function O(t){let n=await _(t.url.protocol),r=x.statSync(t.payloadPath).size,i=je(t.headers,t.startOffset,r);return Ae(t.progress,t.startOffset,r),await new Promise((a,o)=>{let s=!1,c=n.request({protocol:t.url.protocol,host:t.url.hostname,port:t.url.port,method:t.method,path:t.url.pathname+t.url.search,headers:i,...t.signal?{signal:t.signal}:{}},n=>{s=!0,ne(n).then(i=>{clearTimeout(l);let s=n.statusCode??500,c=n.headers.location;if(c&&Me(s)){if(t.redirectCount>=5){o(new e(`COMMAND_FAILED`,`Artifact upload exceeded redirect limit`,{maxRedirects:5,url:t.url.toString()}));return}let n=new URL(c,t.url);O({...t,url:n,redirectCount:t.redirectCount+1}).then(a,o);return}let u=Ne(s)?Pe(n.headers,r):void 0;if(u!==void 0){if(u>=r){a({statusCode:200,statusMessage:`Upload already complete`,body:``});return}if(u<=t.startOffset){o(new e(`COMMAND_FAILED`,`Artifact upload resume did not advance`,{offset:u,previousOffset:t.startOffset,url:t.url.toString()}));return}O({...t,startOffset:u}).then(a,o);return}a({statusCode:s,statusMessage:n.statusMessage,body:i})}).catch(o)}),l=setTimeout(()=>{c.destroy(),o(new e(`COMMAND_FAILED`,t.timeoutMessage,{timeoutMs:T,...t.timeoutHint?{hint:t.timeoutHint}:{},...k(t)}))},T);c.on(`error`,n=>{if(!s){if(clearTimeout(l),t.signal?.aborted){o(t.signal.reason);return}o(new e(`COMMAND_FAILED`,t.errorMessage,{...t.errorHint?{hint:t.errorHint}:{},...k(t)},n))}}),c.on(`close`,()=>clearTimeout(l)),_e(x.createReadStream(t.payloadPath,{start:t.startOffset}),we({stage:t.progress?.stage??`legacy`,fileName:t.progress?.fileName??b.basename(t.payloadPath),startOffset:t.startOffset,totalBytes:r,onProgress:t.progress?.onProgress}),c).catch(t=>{if(s)return;c.destroy();let n=t instanceof Error?t:Error(String(t));o(new e(`COMMAND_FAILED`,`Failed to read local artifact`,{},n))})})}function k(e){return e.retryable===!0?{[E]:!0}:{}}function Ae(e,t,n){e?.onProgress?.({type:t>0?`resume`:`start`,stage:e.stage,fileName:e.fileName,transferredBytes:t,totalBytes:n})}function je(e,t,n){return t<=0?e:{...e,"content-length":Math.max(n-t,0),"content-range":`bytes ${t}-${n-1}/${n}`}}function Me(e){return[301,302,303,307,308].includes(e)}function Ne(e){return e===308}function Pe(e,t){let n=Fe(e[`x-upload-offset`]??e[`upload-offset`]);if(n!==void 0)return Math.min(n,t);let r=A(e.range)?.match(/^bytes=0-(\d+)$/);if(!r)return;let i=Number(r[1]);if(!(!Number.isSafeInteger(i)||i<0))return Math.min(i+1,t)}function Fe(e){let t=A(e);if(t===void 0)return;let n=Number(t);return Number.isSafeInteger(n)&&n>=0?n:void 0}function A(e){return Array.isArray(e)?e[0]:e}const j=3e4;async function M(e){let t=await ye(e.localPath,e.platform),n=e.baseUrl.endsWith(`/`)?e.baseUrl:`${e.baseUrl}/`,r=pe();try{let i=await ze({normalizedBase:n,token:e.token,artifact:t,uploadAttemptId:r,signal:e.signal});return i?.kind===`cache-hit`?i.uploadId:i?.kind===`direct-upload`?await Ie({normalizedBase:n,token:e.token,artifact:t,preflight:i,uploadAttemptId:r,onProgress:e.onProgress,signal:e.signal})||(e.onProgress?.({type:`fallback`,from:`direct`,to:`legacy`,fileName:t.fileName}),await N({normalizedBase:n,token:e.token,artifact:t,onProgress:e.onProgress,signal:e.signal})):await N({normalizedBase:n,token:e.token,artifact:t,onProgress:e.onProgress,signal:e.signal})}finally{t.cleanup()}}async function Ie(e){let t=async t=>(await Ue(e.artifact,t,e.onProgress,e.signal),await We({normalizedBase:e.normalizedBase,token:e.token,uploadId:t.uploadId,signal:e.signal}));try{return await t(e.preflight)}catch(n){if(e.signal?.aborted)throw n;return Re(n)?await Le(e,t):void 0}}async function Le(e,t){let n=await ze({normalizedBase:e.normalizedBase,token:e.token,artifact:e.artifact,uploadAttemptId:e.uploadAttemptId,signal:e.signal});if(n?.kind===`cache-hit`)return n.uploadId;if(n?.kind===`direct-upload`)try{return await t(n)}catch{return}}function Re(t){return t instanceof e?ke(t):!0}async function N(t){let{normalizedBase:n,token:r,artifact:i}=t,a=new URL(`upload`,n),o={"content-type":i.contentType,"x-artifact-type":i.artifactType,"x-artifact-filename":i.fileName,"x-artifact-hash":i.sha256,"x-artifact-hash-algorithm":`sha256`,"transfer-encoding":`chunked`};Object.assign(o,g(r));let s=await D({url:a,method:`POST`,headers:o,payloadPath:i.payloadPath,timeoutMessage:`Artifact upload timed out`,timeoutHint:`The upload to the remote daemon exceeded the 5-minute timeout.`,errorMessage:`Failed to upload artifact to remote daemon`,errorHint:`Verify the remote daemon is reachable and supports artifact uploads.`,signal:t.signal,progress:{stage:`legacy`,fileName:i.fileName,onProgress:t.onProgress}});try{let t=JSON.parse(s.body);if(!t.ok||!t.uploadId)throw new e(`COMMAND_FAILED`,`Upload failed: ${s.body}`);return t.uploadId}catch(t){throw t instanceof e?t:new e(`COMMAND_FAILED`,`Invalid upload response: ${s.body}`)}}async function ze(e){let t=new URL(`upload/preflight`,e.normalizedBase),n={"content-type":`application/json`};Object.assign(n,g(e.token));let r=await fetch(t,{method:`POST`,headers:n,signal:Be(e.signal,j),body:JSON.stringify({uploadAttemptId:e.uploadAttemptId,sha256:e.artifact.sha256,fileName:e.artifact.fileName,sizeBytes:e.artifact.sizeBytes,artifactType:e.artifact.artifactType,...e.artifact.platform?{platform:e.artifact.platform}:{},contentType:e.artifact.contentType})}).catch(t=>{if(e.signal?.aborted)throw t});if(r?.ok)return Ve(await r.json().catch(()=>void 0))}function Be(e,t){let n=AbortSignal.timeout(t);return e?AbortSignal.any([e,n]):n}function Ve(e){if(!e||typeof e!=`object`)return;let t=e;if(t.ok!==!0||typeof t.uploadId!=`string`)return;if(t.cacheHit===!0)return{kind:`cache-hit`,uploadId:t.uploadId};let n=t.upload;if(!n||typeof n.url!=`string`)return;let r=n.headers??{};if(He(r))return{kind:`direct-upload`,uploadId:t.uploadId,url:n.url,headers:r}}function He(e){return!e||typeof e!=`object`||Array.isArray(e)?!1:Object.values(e).every(e=>typeof e==`string`)}async function Ue(t,n,r,i){let a=await D({url:new URL(n.url),method:`PUT`,headers:n.headers,payloadPath:t.payloadPath,timeoutMessage:`Direct artifact upload timed out`,timeoutHint:`The direct upload ticket did not accept the artifact within the timeout.`,errorMessage:`Failed to upload artifact with direct upload ticket`,retryable:!0,signal:i,progress:{stage:`direct`,fileName:t.fileName,onProgress:r}});if(a.statusCode<200||a.statusCode>=300)throw new e(`COMMAND_FAILED`,`Direct artifact upload failed`,{statusCode:a.statusCode,statusMessage:a.statusMessage})}async function We(t){let n=new URL(`upload/finalize`,t.normalizedBase),r={"content-type":`application/json`};Object.assign(r,g(t.token));let i=await fetch(n,{method:`POST`,headers:r,signal:Be(t.signal,j),body:JSON.stringify({uploadId:t.uploadId})}).catch(n=>{throw t.signal?.aborted?n:new e(`COMMAND_FAILED`,`Failed to finalize direct artifact upload`,{},n)});if(!i.ok)throw new e(`COMMAND_FAILED`,`Direct artifact upload finalize failed`,{status:i.status,statusText:i.statusText});let a=await i.json().catch(()=>void 0);if(!a?.ok||!a.uploadId)throw new e(`COMMAND_FAILED`,`Invalid upload finalize response`);return a.uploadId}async function Ge(e,t,n){let r=[...e.positionals??[]],i=e.flags?{...e.flags}:void 0,a=e.meta?.installSource,o={},s,c=Te();if(!dt(t))return Ze({positionals:r,flags:i,installSource:a,uploadedArtifactId:s,clientArtifactPaths:o});Ke(e),i=Je(e,r,i,o);let l=await Qe(e,t,c,n);return l&&(a=l.installSource,s=l.uploadedArtifactId??s),e.command!==`install`&&e.command!==`reinstall`||(s=await qe(e,t,r,c,n)??s),Ze({positionals:r,flags:i,installSource:a,uploadedArtifactId:s,clientArtifactPaths:o})}function Ke(t){if(t.flags?.saveScript!==void 0)throw new e(`INVALID_ARGS`,`--save-script is not supported against a remote daemon: the healed script would be written on the daemon host, not on this machine.`,{hint:`Run the script against a local daemon to capture a healed .ad, or re-run without --save-script.`,command:t.command})}async function qe(e,t,n,r,i){let a=n.length===1?0:1,o=n[a];if(o===void 0)return;if(o.startsWith(`remote:`)){n[a]=o.slice(7);return}let s=Xe(o,e.meta?.cwd);if(s)return await M({localPath:s,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform,onProgress:r,signal:i})}function Je(e,t,n,r){let i=$e(e,t);if(!i)return n;i.positionalIndex!==void 0&&i.positionalPath!==void 0&&(t[i.positionalIndex]=i.positionalPath);let a=Ye(n,i.flagKey??`out`,i.flagPath);return r[i.field]=i.localPath,a}function Ye(e,t,n){return n===void 0?e:{...e??{},[t]:n}}function Xe(e,t){let n=b.isAbsolute(e)?e:b.resolve(t??process.cwd(),e);return x.existsSync(n)?n:void 0}function Ze(e){return{positionals:e.positionals,flags:e.flags,installSource:e.installSource,uploadedArtifactId:e.uploadedArtifactId,...Object.keys(e.clientArtifactPaths).length>0?{clientArtifactPaths:e.clientArtifactPaths}:{}}}async function Qe(e,t,n,r){let i=e.meta?.installSource;if(e.command!==`install_source`||!i||i.kind!==`path`)return null;let a=i.path.trim();if(!a)return{installSource:i};if(a.startsWith(`remote:`))return{installSource:{...i,path:a.slice(7)}};let o=b.isAbsolute(a)?a:b.resolve(e.meta?.cwd??process.cwd(),a);if(!x.existsSync(o))return{installSource:{...i,path:o}};let s=await M({localPath:o,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform,onProgress:n,signal:r});return{installSource:{...i,path:o},uploadedArtifactId:s}}function $e(e,t){if(e.command===`screenshot`){let n=it(e,`path`,`.png`);return t[0]?{field:`path`,localPath:n,positionalIndex:0,positionalPath:F(`screenshot`,`.png`)}:{field:`path`,localPath:n,positionalIndex:0,flagPath:F(`screenshot`,`.png`)}}if(e.command===`record`&&(t[0]??``).toLowerCase()===`start`){if(!nt(e)&&e.flags?.platform===void 0)return null;let t=tt(e),n=rt(it(e,`outPath`,t,1),e);return{field:`outPath`,localPath:n,positionalIndex:1,positionalPath:F(`recording`,b.extname(n)||t)}}return e.command===`test`?{field:`artifactsDir`,localPath:et(e),flagKey:`artifactsDir`,flagPath:ot(`test-artifacts`)}:null}function et(e){let t=e.flags?.artifactsDir;return at(P(t)?t:`.agent-device/test-artifacts`,e.meta?.cwd)}function tt(e){return p(e.flags?.platform)}function nt(e){return P(e.positionals?.[1])||P(e.flags?.out)}function rt(e,t){return t.flags?.platform===`web`?m(e,tt(t)):e}function it(e,t,n,r=0){let i=e.positionals?.[r]??e.flags?.out,a=`${t===`path`?`screenshot`:`recording`}-${Date.now()}${n}`;return at(P(i)?i:a,e.meta?.cwd)}function at(e,t){return b.isAbsolute(e)?e:b.resolve(t??process.cwd(),e)}function P(e){return typeof e==`string`&&e.trim().length>0}function F(e,t){let n=t.startsWith(`.`)?t:`.${t}`;return b.posix.join(`/tmp`,`agent-device-${e}-${Date.now()}-${Math.random().toString(36).slice(2,8)}${n}`)}function ot(e){return b.posix.join(`/tmp`,`agent-device-${e}-${Date.now()}-${Math.random().toString(36).slice(2,8)}`)}async function st(e,t,n){let r=Array.isArray(n.data?.artifacts)?n.data.artifacts:[];if(r.length===0||!e.baseUrl)return n;let i=n.data?{...n.data}:{},a=[];for(let n of r){if(!n||typeof n!=`object`||typeof n.artifactId!=`string`){a.push(n);continue}let r=ct(n,t),o=await lt({baseUrl:e.baseUrl,token:e.token,artifactId:n.artifactId,destinationPath:r,requestScope:t.meta,isDirectory:n.artifactType===`test-artifacts`});i[n.field]=o,a.push({...n,localPath:o})}return i.artifacts=a,{ok:!0,data:i}}function ct(e,t){if(e.localPath&&e.localPath.trim().length>0)return e.localPath;let n=t.meta?.clientArtifactPaths?.[e.field];if(n&&n.trim().length>0)return n;let r=e.fileName?.trim()||`${e.field}-${Date.now()}`;return b.resolve(t.meta?.cwd??process.cwd(),r)}async function lt(e){let{downloadRemoteArtifactFromUrl:t}=await import(`./artifact-download.js`);return await t({artifactUrl:new URL(ut(e.baseUrl,e.artifactId)),token:e.token,artifactId:e.artifactId,destinationPath:e.destinationPath,requestScope:e.requestScope,...e.timeoutMs===void 0?{}:{timeoutMs:e.timeoutMs},...e.isDirectory===void 0?{}:{isDirectory:e.isDirectory}})}function ut(e,t){let n=e.endsWith(`/`)?e:`${e}/`;return new URL(`artifacts/${encodeURIComponent(t)}`,n).toString()}function dt(e){return typeof e.baseUrl==`string`&&e.baseUrl.length>0}const ft=3e3,pt=1e3;function mt(e){let t=Et(e);if(!t||typeof t!=`object`)return null;let n=t,r=ht(n);if(!r)return null;let i=gt(n);return i?{token:r,...i,transport:vt(n.transport),pid:L(n.pid)??0,version:I(n.version),codeOrigin:_t(n.codeOrigin),codeSignature:I(n.codeSignature),processStartTime:I(n.processStartTime),policyDigest:I(n.policyDigest)}:null}function ht(e){return typeof e.token==`string`&&e.token.length>0?e.token:null}function gt(e){let t=L(e.port),n=L(e.httpPort);return t===void 0&&n===void 0?null:{port:t,httpPort:n}}function _t(e){return e===`installed`||e===`checkout`?e:void 0}function vt(e){return e===`socket`||e===`http`||e===`dual`?e:void 0}function I(e){return typeof e==`string`?e:void 0}function L(e){return Number.isInteger(e)&&Number(e)>0?Number(e):void 0}function R(e){let t=Et(e);if(!t||typeof t!=`object`)return null;let n=t;return Number.isInteger(n.pid)&&Number(n.pid)>0?{pid:Number(n.pid),processStartTime:typeof n.processStartTime==`string`?n.processStartTime:void 0,startedAt:typeof n.startedAt==`number`?n.startedAt:void 0}:null}function yt(e,t){let n=R(e.lockPath);return n!==null&&n.pid!==t&&y(n.pid,n.processStartTime)}function z(e){Dt(e)}function B(e){Dt(e)}function bt(e){let t=V(e);if(!t.hasLock||t.hasInfo)return;let n=R(e.lockPath);if(!n){B(e.lockPath);return}y(n.pid,n.processStartTime)||B(e.lockPath)}async function xt(e,t,n={}){let r=n.stopLiveProcesses??!0,i={reason:t,removedInfo:!1,removedLock:!1,stoppedInfoProcess:!1,stoppedLockProcess:!1};try{let t=x.existsSync(e.infoPath),n=mt(e.infoPath);if(n){let t=y(n.pid,n.processStartTime);t&&!r?i.retainedInfoProcess=!0:(t&&(await H(n),i.stoppedInfoProcess=!0),z(e.infoPath),i.removedInfo=!0)}else t&&(z(e.infoPath),i.removedInfo=!0);let a=x.existsSync(e.lockPath),o=R(e.lockPath);if(o){let t=y(o.pid,o.processStartTime);t&&!r?i.retainedLockProcess=!0:(t&&(await se(o.pid,{termTimeoutMs:ft,killTimeoutMs:pt,expectedStartTime:o.processStartTime}),i.stoppedLockProcess=!0),B(e.lockPath),i.removedLock=!0)}else a&&(B(e.lockPath),i.removedLock=!0)}catch(e){i.error=e instanceof Error?e.message:String(e)}return u({level:i.error?`warn`:`info`,phase:`daemon_startup_metadata_cleanup`,data:i}),i}function V(e){return{hasInfo:x.existsSync(e.infoPath),hasLock:x.existsSync(e.lockPath)}}async function St(e){let t=V(e);if(!t.hasLock||t.hasInfo)return!1;let n=R(e.lockPath);return!n||!y(n.pid,n.processStartTime)?(B(e.lockPath),!0):!1}async function H(e){await se(e.pid,{termTimeoutMs:ft,killTimeoutMs:pt,expectedStartTime:e.processStartTime})}function Ct(e){return typeof e.baseUrl==`string`&&e.baseUrl.length>0}function wt(e,t=oe(process.env.AGENT_DEVICE_STATE_DIR)){let n=Tt(t);return e.hasLock&&!e.hasInfo?`agent-device attempted to clean stale daemon metadata automatically, but ${t.lockPath} still exists without ${t.infoPath}. Retry with --debug; if this persists after confirming no agent-device daemon process is running, run: ${n}`:e.hasLock&&e.hasInfo?`agent-device attempted to clean stale daemon metadata automatically, but ${t.infoPath} and ${t.lockPath} still remain. Retry with --debug; if this persists after confirming no agent-device daemon process is running, run: ${n}`:e.hasInfo?`agent-device did not observe reachable daemon metadata after retrying, and ${t.infoPath} still remains. Stale metadata was cleaned automatically when safe; retry with --debug. If this persists after confirming no agent-device daemon process is running, run: ${n}`:`agent-device did not observe reachable daemon metadata after retrying. Stale metadata was cleaned automatically when safe; retry with --debug and check daemon diagnostics logs. If stale metadata returns after confirming no agent-device daemon process is running, run: ${n}`}function Tt(e){return`rm -f ${ie(e.infoPath)} ${ie(e.lockPath)}`}function Et(e){if(!x.existsSync(e))return null;try{return JSON.parse(x.readFileSync(e,`utf8`))}catch{return null}}function Dt(e){try{x.existsSync(e)&&x.unlinkSync(e)}catch{}}function U(t,n,r){return new e(`COMMAND_FAILED`,`Invalid daemon response`,{requestId:t.meta?.requestId,line:n},r instanceof Error?r:void 0)}function Ot(e){let t=t=>(e.onError(t),!0);return{handleLine(n){let r;try{r=JSON.parse(n)}catch(r){return t(U(e.req,n,r))}if(ue(r))try{return e.onProgress?.(r.event),!1}catch(e){return t(e)}return ce(r)?(e.onResponse(r.response),!0):e.responseFormat===`socket-legacy`?(e.onResponse(r),!0):t(U(e.req,n,Error(`Missing daemon progress response envelope`)))}}}function kt(e,t){return le(e)&&String(Array.isArray(t)?t.join(`,`):t??``).includes(`application/x-ndjson`)}function At(e,t){let{req:n,isSettled:r,resolve:i,reject:a,clearTimeout:o}=t,s=``,c=Ot({req:n,onProgress:t.onProgress,responseFormat:`socket-legacy`,onResponse(t){o(),i(t),e.end()},onError(e){o(),a(e)}});e.setEncoding(`utf8`),e.on(`data`,e=>{if(r())return;let t=v(s,e);s=t.buffer;for(let e of t.lines)if(c.handleLine(e))return}),e.on(`end`,()=>{if(r())return;let e=s.trim();e&&c.handleLine(e)||(o(),a(U(n,e)))})}function jt(t,n){let{req:r,handleResponseBody:i,reject:a,clearTimeout:o}=n,s=``,c=!1,l=Ot({req:r,onProgress:n.onProgress,responseFormat:`ndjson-envelope`,onResponse(e){c=!0,o(),i(JSON.stringify(e))},onError(e){c=!0,o(),a(e)}});t.setEncoding(`utf8`),t.on(`data`,e=>{if(c)return;let t=v(s,e);s=t.buffer;for(let e of t.lines)if(e&&l.handleLine(e))return}),t.on(`end`,()=>{if(c)return;let e=s.trim();e&&l.handleLine(e)||(c=!0,o(),a(U(r,e)))}),t.on(`error`,t=>{c||(c=!0,o(),a(new e(`COMMAND_FAILED`,`Failed to read daemon response`,{requestId:r.meta?.requestId},t instanceof Error?t:void 0)))})}const Mt=1e4,Nt=8388608;function Pt(e,t){return h(e,`sessions/${encodeURIComponent(t.session)}/requests/${encodeURIComponent(t.requestId)}/diagnostics`)}function Ft(e){let{logPath:t,...n}=e;return n}async function It(e,t){let n=Ft(e),r=e.diagnosticsRecord,i=r?.requestId??t.requestId;if(!r)return W(n,t.endpoint,i,`the daemon named no diagnostics record`);try{let e=de(t.stateDir,r),a=await Lt({endpoint:t.endpoint,ref:r,destinationPath:e});return a?W(n,t.endpoint,i,a):{...n,logPath:e}}catch(e){return W(n,t.endpoint,i,e instanceof Error?e.message:String(e))}}function W(e,t,n,r){return{...e,logPathUnavailable:`remote daemon ${t.baseUrl}, request ${n??`unknown`}: ${r}`}}async function Lt(e){let{endpoint:t,ref:n,destinationPath:r}=e,i;try{i=new URL(Pt(t.baseUrl,n))}catch{return`daemon base URL is not a valid URL`}try{let e=await _(i.protocol);return await x.promises.mkdir(b.dirname(r),{recursive:!0}),await new Promise(n=>{let a=!1,o=e=>{if(!a){if(a=!0,clearTimeout(c),e===void 0){n(void 0);return}x.promises.rm(r,{force:!0}).finally(()=>{n(e)})}},s=e.request({protocol:i.protocol,host:i.hostname,port:i.port,method:`GET`,path:i.pathname+i.search,headers:{...g(t.token),...te(t.tenantId)}},e=>{let t=e.statusCode??500;if(t!==200){e.resume(),o(`HTTP ${t}`);return}let n=x.createWriteStream(r),i=0;e.on(`data`,e=>{i+=e.length,i>Nt&&(s.destroy(),n.destroy(),o(`record exceeds ${Nt} bytes`))}),e.on(`error`,e=>{n.destroy(),o(e.message)}),n.on(`error`,e=>{o(e.message)}),n.on(`finish`,()=>{o(void 0)}),e.pipe(n)}),c=setTimeout(()=>{o(`fetch timed out after ${Mt}ms`),s.destroy()},Mt);s.on(`error`,e=>{o(e.message)}),s.end()})}catch(e){return e instanceof Error?e.message:String(e)}}function Rt(t,n){let{info:r,req:i,stateDir:a,resolve:o,reject:s}=n;try{let n=zt(t);if(n.error){Bt(n.error,{info:r,req:i,stateDir:a,reject:s});return}if(!n.result||typeof n.result!=`object`){s(new e(`COMMAND_FAILED`,`Invalid daemon RPC response`,{requestId:i.meta?.requestId}));return}Wt(r,i,n.result,o,s)}catch(n){s(new e(`COMMAND_FAILED`,`Invalid daemon response`,{requestId:i.meta?.requestId,line:t},n instanceof Error?n:void 0))}}function zt(e){return JSON.parse(e)}async function Bt(e,t){let{info:n,req:r,stateDir:i,reject:a}=t,o=r.meta?.requestId,s=Vt(e);if(!n.baseUrl){a(Ut(s,o));return}a(Ut(await It(s,{endpoint:{baseUrl:n.baseUrl,token:n.token,tenantId:r.meta?.tenantId},stateDir:i,requestId:o}),o))}function Vt(e){let t=e.data??{},i=Ht(t.cause);return{code:r(t.code==null?void 0:String(t.code),`COMMAND_FAILED`),message:String(t.message??e.message??`Daemon RPC request failed`),cause:i,details:typeof t.details==`object`&&t.details?t.details:void 0,hint:typeof t.hint==`string`?t.hint:void 0,diagnosticId:typeof t.diagnosticId==`string`?t.diagnosticId:void 0,logPath:typeof t.logPath==`string`?t.logPath:void 0,diagnosticsRecord:n(t.diagnosticsRecord),retriable:typeof t.retriable==`boolean`?t.retriable:void 0,supportedOn:typeof t.supportedOn==`string`?t.supportedOn:void 0}}function Ht(e){return t(e)}function Ut(t,n){return new e(r(t.code,`COMMAND_FAILED`),t.message,{...t.details??{},hint:t.hint,diagnosticId:t.diagnosticId,logPath:t.logPath,logPathUnavailable:t.logPathUnavailable,diagnosticsRecord:t.diagnosticsRecord,retriable:t.retriable,supportedOn:t.supportedOn,requestId:n},t.cause)}async function Wt(e,t,n,r,i){try{r(e.baseUrl&&n.ok?await st(e,t,n):n)}catch(e){i(e)}}function Gt(e,t){let n=e.meta?.requestId??l();return Kt(e.command)?{jsonrpc:`2.0`,id:n,method:qt(e.command),params:{...Jt(e,e.command,t),...e.command===`lease_allocate`?a(e.flags):{}}}:{jsonrpc:`2.0`,id:n,method:`agent_device.command`,params:e}}function Kt(e){return e===`lease_allocate`||e===`lease_heartbeat`||e===`lease_release`}function qt(e){switch(e){case`lease_allocate`:return`agent_device.lease.allocate`;case`lease_heartbeat`:return`agent_device.lease.heartbeat`;case`lease_release`:return`agent_device.lease.release`}}function Jt(e,t,n){return i(o(e),t,{includeTokenParam:n.includeTokenParam,token:e.token,session:e.session})}const Yt=[`xcodebuild .*AgentDeviceRunnerUITests/RunnerTests/testCommand`,String.raw`xcodebuild .*AgentDeviceRunner\.env\.session-`,String.raw`xcodebuild build-for-testing .*apple/runner/AgentDeviceRunner/AgentDeviceRunner\.xcodeproj`],Xt=new Set([`apple`,`ios`,`macos`]);function Zt(e){return e!==void 0&&Xt.has(e)}function G(t){let{info:n,statePaths:r,remote:i,timeoutMs:a,requestId:o,command:s,platform:c,session:l,action:d}=t,f=i?{terminated:0}:en(),p=!i&&Qt(s),m=p?tn(n,r):{forcedKill:!1},h=Zt(c)||f.terminated>0;return u({level:`error`,phase:`daemon_request_timeout`,data:{timeoutMs:a,requestId:o,command:s,timedOutRunnerPidsTerminated:f.terminated,timedOutRunnerCleanupError:f.error,daemonPidReset:p?n.pid:void 0,daemonPidForceKilled:p?m.forcedKill:void 0,daemonPreservedAfterTimeout:!i&&!p,daemonBaseUrl:n.baseUrl}}),new e(`COMMAND_FAILED`,`Daemon request timed out`,{timeoutMs:a,requestId:o,reason:`daemon_transport_timeout`,hint:$t({remote:i,resetDaemon:p,command:s,appleCleanupEvidence:h,session:l,action:d})})}function Qt(e){return s(e).onTimeout===`reset-daemon`}function $t(e){let{remote:t,resetDaemon:n,command:r,appleCleanupEvidence:i,session:a,action:o}=e;if(t)return r===c.record&&o===`stop`?`The remote daemon is still exporting the recording. Run agent-device record stop${a?` --session ${a}`:``} again to wait for that export and receive the completed recording.`:`Retry with --debug and verify the remote daemon URL, auth token, and remote host logs.`;if(!n){let e=i&&r===c.snapshot?` If this was the first Apple-platform snapshot on the device, run agent-device prepare ios-runner with the same --platform before snapshot/test so runner startup is handled explicitly.`:``;return`Retry with --debug and check daemon diagnostics logs. The timed-out ${r??`request`} request was canceled${i?` and Apple runner work was aborted when detected`:``}; the daemon was kept alive so the session can still be closed or inspected.${e}`}return i?`Retry with --debug and check daemon diagnostics logs. Timed-out Apple runner xcodebuild processes were terminated when detected.`:`Retry with --debug and check daemon diagnostics logs. The daemon was reset after the timeout.`}function en(){let e=0;try{for(let t of Yt)f(`pkill`,[`-f`,t],{allowFailure:!0}).exitCode===0&&(e+=1);return{terminated:e}}catch(t){return{terminated:e,error:t instanceof Error?t.message:String(t)}}}function tn(e,t){let n=!1;try{y(e.pid,e.processStartTime)&&(process.kill(e.pid,`SIGKILL`),n=!0)}catch{H(e)}finally{z(t.infoPath),B(t.lockPath)}return{forcedKill:n}}const nn=3e3,K=`Daemon HTTP endpoint is unavailable`,q=`Daemon socket endpoint is unavailable`;async function rn(e,t){let n=gn(e,t);if(await an(e,n))return!0;let r=_n(e,t,n);return r?await an(e,r):!1}async function an(e,t){return t===`http`?await sn(e):await on(e.port)}function on(e){return e?new Promise(t=>{let n=!1,r=ve.createConnection({host:`127.0.0.1`,port:e},()=>{i(!0)}),i=e=>{n||(n=!0,r.destroy(),t(e))};r.setTimeout(500),r.on(`timeout`,()=>{i(!1)}),r.on(`error`,()=>{i(!1)})}):Promise.resolve(!1)}function sn(e){return ln(e).then(e=>e.reachable)}async function cn(t,n){let r=await ln(t,n);if(!t.baseUrl||!r.reachable)return r;let i=[r,r.upstream].find(e=>typeof e?.rpcProtocolVersion==`number`&&e.rpcProtocolVersion!==2);if(i)throw new e(`COMMAND_FAILED`,`Remote daemon RPC protocol is incompatible`,{daemonBaseUrl:t.baseUrl,clientVersion:ae(),remoteVersion:i.version,remoteService:i.service,supportedRpcProtocolVersion:2,remoteRpcProtocolVersion:i.rpcProtocolVersion,hint:`Upgrade agent-device on the client or remote host so both support the same daemon RPC protocol.`});return r}async function ln(e,t){let n=e.baseUrl?h(e.baseUrl,`health`):e.httpPort?`http://127.0.0.1:${e.httpPort}/health`:null;if(!n)return{reachable:!1};let r=new URL(n),i=await _(r.protocol),a=Math.min(e.baseUrl?nn:500,t??1/0);if(a<=0)return{reachable:!1,timedOut:!0};let o=AbortSignal.timeout(Math.ceil(a));return await new Promise(t=>{let n=e.baseUrl?g(e.token):{},s=()=>o.aborted?{reachable:!1,timedOut:!0}:{reachable:!1},c=i.request({protocol:r.protocol,host:r.hostname,port:r.port,path:r.pathname+r.search,method:`GET`,timeout:a,signal:o,headers:n},e=>{let n=``;e.setEncoding(`utf8`),e.on(`data`,e=>{n+=e}),e.on(`end`,()=>{let r=e.statusCode??500;t({reachable:r<500,statusCode:r,...un(n)})}),e.on(`error`,()=>t(s())),e.on(`aborted`,()=>t(s()))});c.on(`timeout`,()=>{c.destroy(),t({reachable:!1,timedOut:!0})}),c.on(`error`,()=>{t(s())}),c.end()})}function un(e){try{let t=JSON.parse(e),n=t.upstream&&typeof t.upstream==`object`?dn(t.upstream):void 0;return{...dn(t),...n?{upstream:n}:{}}}catch{return{}}}function dn(e){return{service:typeof e.service==`string`?e.service:void 0,version:typeof e.version==`string`?e.version:void 0,rpcProtocolVersion:typeof e.rpcProtocolVersion==`number`?e.rpcProtocolVersion:void 0,...typeof e.instanceId==`string`?{instanceId:e.instanceId}:{},...typeof e.hostArch==`string`?{hostArch:e.hostArch}:{}}}async function fn(e,t,n,r,i,a={}){let o=gn(e,n),s=typeof i==`number`?performance.now()+i:void 0;try{return await Y(e,t,r,i,o,a)}catch(c){if(e.baseUrl&&mn(c))return await pn(e,t,r,i,s,o,a);hn(c)&&$(e);let l=_n(e,n,o);if(!l||!vn(c,o))throw c;return await Y(e,t,r,i,l,a)}}async function pn(t,n,r,i,a,o,s){$(t);let c=J(t,n,r,i,a),l=await cn(t,c);if(l.timedOut&&i!==void 0&&c!==void 0&&c<=nn)throw G({info:t,statePaths:r,...Z(n,!0,i)});let u=J(t,n,r,i,a);if(!l.reachable)throw new e(`COMMAND_FAILED`,`Remote daemon is unavailable`,{daemonBaseUrl:t.baseUrl});t.remoteInstanceId=l.instanceId,t.remoteUpstreamInstanceId=l.upstream?.instanceId,En(t,l);try{return await Y(t,n,r,u,o,s)}catch(e){throw hn(e)&&$(t),e}}function J(e,t,n,r,i){if(i===void 0||r===void 0)return;let a=i-performance.now();if(a>0)return a;throw G({info:e,statePaths:n,...Z(t,!0,r)})}function mn(t){return t instanceof e&&t.details?.reason===`remote_instance_mismatch`}function hn(t){return t instanceof e&&(t.details?.reason===`daemon_transport_failure`||t.details?.reason===`daemon_transport_timeout`||t.details?.reason===`daemon_response_read_failure`)}async function Y(e,t,n,r,i,a){return i===`http`?await wn(e,t,n,r,a):await xn(e,t,n,r,a)}function gn(t,n){if(t.baseUrl){if(n===`socket`)throw new e(`COMMAND_FAILED`,`Remote daemon endpoint only supports HTTP transport`,{daemonBaseUrl:t.baseUrl});return`http`}if(n===`http`||n===`socket`)return yn(t,n);let r=(t.transport===`socket`||t.transport===`dual`?[`socket`,`http`]:[`http`,`socket`]).find(e=>X(t,e));if(r)return r;throw new e(`COMMAND_FAILED`,`Daemon metadata has no reachable transport`)}function X(e,t){return t===`http`?!!e.httpPort:!!e.port}function _n(e,t,n){if(t!==`auto`||e.baseUrl)return null;let r=n===`socket`?`http`:`socket`;return X(e,r)?r:null}function vn(t,n){return n===`socket`&&t instanceof e&&t.code===`COMMAND_FAILED`&&t.message===`Failed to communicate with daemon`&&t.details?.daemonSocketRequestWritten===!1}function yn(t,n){if(X(t,n))return n;throw new e(`COMMAND_FAILED`,n===`http`?K:q)}function bn(t,n,r,i={}){return u({level:`error`,phase:`daemon_request_socket_error`,data:{requestId:n,message:t instanceof Error?t.message:String(t)}}),new e(`COMMAND_FAILED`,`Failed to communicate with daemon`,{...i,reason:`daemon_transport_failure`,requestId:n,hint:r?`Retry command. If this persists, verify the remote daemon URL, auth token, and remote host reachability.`:`Retry command. If this persists, clean stale daemon metadata and start a fresh session.`},t instanceof Error?t:void 0)}async function xn(t,n,r,i,a){let o=t.port;if(!o)throw new e(`COMMAND_FAILED`,q);return new Promise((e,s)=>{let c=!1,l=ve.createConnection({host:`127.0.0.1`,port:o},()=>{c=!0,l.write(`${JSON.stringify(n)}\n`)}),u=!1,d=typeof i==`number`?setTimeout(()=>{u=!0,l.destroy(),s(G({info:t,statePaths:r,...Z(n,!1,i)}))},i):void 0;At(l,{req:n,onProgress:a.onProgress,isSettled:()=>u,clearTimeout:()=>{d&&clearTimeout(d)},resolve:t=>{u=!0,e(t)},reject:e=>{u=!0,s(e)}}),l.on(`error`,e=>{u||(u=!0,d&&clearTimeout(d),s(bn(e,n.meta?.requestId,!1,{daemonSocketRequestWritten:c})))})})}function Z(e,t,n){return{remote:t,timeoutMs:n,requestId:e.meta?.requestId,command:e.command,platform:e.flags?.platform,session:e.session,action:e.positionals?.[0]}}function Sn(e){return{...e.remoteInstanceId?{[re]:e.remoteInstanceId}:{},...e.remoteUpstreamInstanceId?{[ee]:e.remoteUpstreamInstanceId}:{}}}function Cn(e,t){return e===409&&t[`x-agent-device-instance-mismatch`]===`true`}async function wn(t,n,r,i,a){let o=t.baseUrl?new URL(h(t.baseUrl,`rpc`)):t.httpPort?new URL(`http://127.0.0.1:${t.httpPort}/rpc`):null;if(!o)throw new e(`COMMAND_FAILED`,K);let s=JSON.stringify(Gt(n,{includeTokenParam:!t.baseUrl})),c={"content-type":`application/json`,"content-length":Buffer.byteLength(s)};t.baseUrl&&(Object.assign(c,g(t.token)),Object.assign(c,Sn(t)));let l=await _(o.protocol);return await new Promise((u,d)=>{let f=l.request({protocol:o.protocol,host:o.hostname,port:o.port,method:`POST`,path:o.pathname+o.search,headers:c},i=>{if(Cn(i.statusCode,i.headers??{})){i.resume(),m&&clearTimeout(m),d(new e(`COMMAND_FAILED`,`Remote daemon instance changed`,{reason:`remote_instance_mismatch`,daemonBaseUrl:t.baseUrl}));return}if(kt(n,i.headers?.[`content-type`])){jt(i,{req:n,onProgress:a.onProgress,reject:d,clearTimeout:()=>{m&&clearTimeout(m)},handleResponseBody:e=>{Rt(e,{info:t,req:n,stateDir:r.baseDir,resolve:u,reject:d})}});return}ne(i).catch(t=>{throw new e(`COMMAND_FAILED`,`Failed to read daemon response`,{requestId:n.meta?.requestId,reason:`daemon_response_read_failure`},t instanceof Error?t:void 0)}).then(e=>{m&&clearTimeout(m),Rt(e,{info:t,req:n,stateDir:r.baseDir,resolve:u,reject:d})}).catch(e=>{m&&clearTimeout(m),d(e)})}),p=Ct(t),m=typeof i==`number`?setTimeout(()=>{f.destroy(),d(G({info:t,statePaths:r,...Z(n,p,i)}))},i):void 0;f.on(`error`,e=>{m&&clearTimeout(m),d(bn(e,n.meta?.requestId,p))}),f.write(s),f.end()})}let Q;function Tn(e,t){return e.baseUrl===t.baseUrl&&e.token===t.token&&e.pid===t.pid}function En(e,t){!t.instanceId||t.upstream&&!t.upstream.instanceId||(Q={baseUrl:e.baseUrl??``,token:e.token,pid:e.pid,health:Promise.resolve(t)})}function $(e){Q&&Tn(Q,e)&&(Q=void 0)}async function Dn(e){if(Q&&Tn(Q,e))return await Q.health;let t={baseUrl:e.baseUrl??``,token:e.token,pid:e.pid,health:cn(e)};Q=t;try{let e=await t.health;return(!e.reachable||!e.instanceId||e.upstream&&!e.upstream.instanceId)&&Q===t&&(Q=void 0),e}catch(e){throw Q===t&&(Q=void 0),e}}export{Ge as _,fn as a,V as c,mt as d,St as f,H as g,wt as h,rn as i,yt as l,B as m,q as n,xt as o,z as p,Dn as r,bt as s,K as t,Ct as u};
|
|
1
|
+
import{N as e,Q as t,W as n,X as r}from"./sdk-contracts.js";import{d as i,m as a,o}from"./lease-scope.js";import{w as s}from"./sdk-batch.js";import{n as c}from"./catalog.js";import{n as l,r as u}from"./diagnostics.js";import{c as d,p as f}from"./exec.js";import"./diagnostics2.js";import{r as p,t as m}from"./output-path.js";import{_ as h,f as ee,g as te,i as ne,m as g,n as _,s as re,t as v}from"./transport.js";import"./command.js";import{o as ie}from"./device-shell.js";import{a as ae}from"./version.js";import{t as oe}from"./daemon-resolution.js";import{n as se,t as y}from"./daemon-process.js";import{n as ce,o as le,t as ue}from"./request-progress-protocol.js";import{t as de}from"./session-artifact-paths.js";import b from"node:path";import x from"node:fs";import{createHash as fe,randomUUID as pe}from"node:crypto";import me from"node:os";import{Transform as he,Writable as ge}from"node:stream";import{pipeline as _e}from"node:stream/promises";import ve from"node:net";async function ye(e,t){let n=x.statSync(e),r=b.basename(e),i=n.isDirectory(),a=Se(t)??xe(e,n),o=[];try{let t=i?await be(e,o):e,n=x.statSync(t);return{payloadPath:t,fileName:r,artifactType:i?`app-bundle`:`file`,platform:a,contentType:i?`application/gzip`:`application/octet-stream`,sha256:await Ce(t),sizeBytes:n.size,cleanup:()=>S(o)}}catch(e){throw S(o),e}}async function be(e,t){let n=x.mkdtempSync(b.join(me.tmpdir(),`agent-device-upload-${pe()}-`));t.push(n);let r=b.join(n,`${b.basename(e)}.tar.gz`);return await d(`tar`,[`czf`,r,`-C`,b.dirname(e),b.basename(e)],{env:{...process.env,COPYFILE_DISABLE:`1`}}),r}function xe(e,t){let n=e.toLowerCase();if(t.isDirectory()&&n.endsWith(`.app`)||n.endsWith(`.ipa`))return`ios`;if(n.endsWith(`.apk`)||n.endsWith(`.aab`))return`android`}function Se(e){return e===`ios`||e===`android`?e:void 0}function S(e){for(let t of e)x.rmSync(t,{recursive:!0,force:!0})}async function Ce(t){let n=fe(`sha256`),r=new ge({write(e,t,r){n.update(e),r()}});return await _e(x.createReadStream(t),r).catch(t=>{throw new e(`COMMAND_FAILED`,`Failed to read local artifact`,{},t instanceof Error?t:void 0)}),n.digest(`hex`)}function we(e){let{stage:t,fileName:n,startOffset:r,totalBytes:i,onProgress:a}=e,o=r,s=De(i),c=Math.min(i,r+s);return new he({transform(e,r,l){o=Math.min(i,o+e.byteLength),o>=c&&(a?.({type:`progress`,stage:t,fileName:n,transferredBytes:o,totalBytes:i}),c=Math.min(i,o+s)),l(null,e)}})}function Te(){if(!(process.stderr.isTTY!==!0||process.env.CI))return e=>{process.stderr.write(`${Ee(e)}\n`)}}function Ee(e){switch(e.type){case`start`:return`Uploading ${e.fileName} (${w(e.totalBytes)}) via ${C(e.stage)} upload`;case`resume`:return`Resuming ${e.fileName} at ${w(e.transferredBytes)} of ${w(e.totalBytes)}`;case`progress`:return`Uploaded ${w(e.transferredBytes)} of ${w(e.totalBytes)} (${Oe(e.transferredBytes,e.totalBytes)})`;case`fallback`:return`Direct upload did not complete; retrying ${e.fileName} with ${C(e.to)} upload`}}function De(e){return Math.max(8388608,Math.ceil(e*.05))}function C(e){return e===`direct`?`direct`:`legacy`}function Oe(e,t){return t<=0?`100%`:`${Math.min(100,Math.floor(e/t*100))}%`}function w(e){if(e<1024)return`${e} B`;let t=e/1024;if(t<1024)return`${t.toFixed(1)} KiB`;let n=t/1024;return n<1024?`${n.toFixed(1)} MiB`:`${(n/1024).toFixed(1)} GiB`}const T=3e5,E=`uploadStreamRetryable`;async function D(e){return await O({...e,url:e.url,redirectCount:0,startOffset:0})}function ke(t){return t instanceof e&&t.details?.[E]===!0}async function O(t){let n=await _(t.url.protocol),r=x.statSync(t.payloadPath).size,i=je(t.headers,t.startOffset,r);return Ae(t.progress,t.startOffset,r),await new Promise((a,o)=>{let s=!1,c=n.request({protocol:t.url.protocol,host:t.url.hostname,port:t.url.port,method:t.method,path:t.url.pathname+t.url.search,headers:i,...t.signal?{signal:t.signal}:{}},n=>{s=!0,ne(n).then(i=>{clearTimeout(l);let s=n.statusCode??500,c=n.headers.location;if(c&&Me(s)){if(t.redirectCount>=5){o(new e(`COMMAND_FAILED`,`Artifact upload exceeded redirect limit`,{maxRedirects:5,url:t.url.toString()}));return}let n=new URL(c,t.url);O({...t,url:n,redirectCount:t.redirectCount+1}).then(a,o);return}let u=Ne(s)?Pe(n.headers,r):void 0;if(u!==void 0){if(u>=r){a({statusCode:200,statusMessage:`Upload already complete`,body:``});return}if(u<=t.startOffset){o(new e(`COMMAND_FAILED`,`Artifact upload resume did not advance`,{offset:u,previousOffset:t.startOffset,url:t.url.toString()}));return}O({...t,startOffset:u}).then(a,o);return}a({statusCode:s,statusMessage:n.statusMessage,body:i})}).catch(o)}),l=setTimeout(()=>{c.destroy(),o(new e(`COMMAND_FAILED`,t.timeoutMessage,{timeoutMs:T,...t.timeoutHint?{hint:t.timeoutHint}:{},...k(t)}))},T);c.on(`error`,n=>{if(!s){if(clearTimeout(l),t.signal?.aborted){o(t.signal.reason);return}o(new e(`COMMAND_FAILED`,t.errorMessage,{...t.errorHint?{hint:t.errorHint}:{},...k(t)},n))}}),c.on(`close`,()=>clearTimeout(l)),_e(x.createReadStream(t.payloadPath,{start:t.startOffset}),we({stage:t.progress?.stage??`legacy`,fileName:t.progress?.fileName??b.basename(t.payloadPath),startOffset:t.startOffset,totalBytes:r,onProgress:t.progress?.onProgress}),c).catch(t=>{if(s)return;c.destroy();let n=t instanceof Error?t:Error(String(t));o(new e(`COMMAND_FAILED`,`Failed to read local artifact`,{},n))})})}function k(e){return e.retryable===!0?{[E]:!0}:{}}function Ae(e,t,n){e?.onProgress?.({type:t>0?`resume`:`start`,stage:e.stage,fileName:e.fileName,transferredBytes:t,totalBytes:n})}function je(e,t,n){return t<=0?e:{...e,"content-length":Math.max(n-t,0),"content-range":`bytes ${t}-${n-1}/${n}`}}function Me(e){return[301,302,303,307,308].includes(e)}function Ne(e){return e===308}function Pe(e,t){let n=Fe(e[`x-upload-offset`]??e[`upload-offset`]);if(n!==void 0)return Math.min(n,t);let r=A(e.range)?.match(/^bytes=0-(\d+)$/);if(!r)return;let i=Number(r[1]);if(!(!Number.isSafeInteger(i)||i<0))return Math.min(i+1,t)}function Fe(e){let t=A(e);if(t===void 0)return;let n=Number(t);return Number.isSafeInteger(n)&&n>=0?n:void 0}function A(e){return Array.isArray(e)?e[0]:e}const j=3e4;async function M(e){let t=await ye(e.localPath,e.platform),n=e.baseUrl.endsWith(`/`)?e.baseUrl:`${e.baseUrl}/`,r=pe();try{let i=await P({normalizedBase:n,token:e.token,artifact:t,uploadAttemptId:r,signal:e.signal});return i?.kind===`cache-hit`?i.uploadId:i?.kind===`direct-upload`?await Ie({normalizedBase:n,token:e.token,artifact:t,preflight:i,uploadAttemptId:r,onProgress:e.onProgress,signal:e.signal})||(e.onProgress?.({type:`fallback`,from:`direct`,to:`legacy`,fileName:t.fileName}),await N({normalizedBase:n,token:e.token,artifact:t,onProgress:e.onProgress,signal:e.signal})):await N({normalizedBase:n,token:e.token,artifact:t,onProgress:e.onProgress,signal:e.signal})}finally{t.cleanup()}}async function Ie(e){let t=async t=>(await He(e.artifact,t,e.onProgress,e.signal),await Ue({normalizedBase:e.normalizedBase,token:e.token,uploadId:t.uploadId,signal:e.signal}));try{return await t(e.preflight)}catch(n){if(e.signal?.aborted)throw n;return Re(n)?await Le(e,t):void 0}}async function Le(e,t){let n=await P({normalizedBase:e.normalizedBase,token:e.token,artifact:e.artifact,uploadAttemptId:e.uploadAttemptId,signal:e.signal});if(n?.kind===`cache-hit`)return n.uploadId;if(n?.kind===`direct-upload`)try{return await t(n)}catch{return}}function Re(t){return t instanceof e?ke(t):!0}async function N(t){let{normalizedBase:n,token:r,artifact:i}=t,a=new URL(`upload`,n),o={"content-type":i.contentType,"x-artifact-type":i.artifactType,"x-artifact-filename":i.fileName,"x-artifact-hash":i.sha256,"x-artifact-hash-algorithm":`sha256`,"transfer-encoding":`chunked`};Object.assign(o,g(r));let s=await D({url:a,method:`POST`,headers:o,payloadPath:i.payloadPath,timeoutMessage:`Artifact upload timed out`,timeoutHint:`The upload to the remote daemon exceeded the 5-minute timeout.`,errorMessage:`Failed to upload artifact to remote daemon`,errorHint:`Verify the remote daemon is reachable and supports artifact uploads.`,signal:t.signal,progress:{stage:`legacy`,fileName:i.fileName,onProgress:t.onProgress}});try{let t=JSON.parse(s.body);if(!t.ok||!t.uploadId)throw new e(`COMMAND_FAILED`,`Upload failed: ${s.body}`);return t.uploadId}catch(t){throw t instanceof e?t:new e(`COMMAND_FAILED`,`Invalid upload response: ${s.body}`)}}async function P(e){let t=new URL(`upload/preflight`,e.normalizedBase),n={"content-type":`application/json`};Object.assign(n,g(e.token));let r=await fetch(t,{method:`POST`,headers:n,signal:ze(e.signal,j),body:JSON.stringify({uploadAttemptId:e.uploadAttemptId,sha256:e.artifact.sha256,fileName:e.artifact.fileName,sizeBytes:e.artifact.sizeBytes,artifactType:e.artifact.artifactType,...e.artifact.platform?{platform:e.artifact.platform}:{},contentType:e.artifact.contentType})}).catch(t=>{if(e.signal?.aborted)throw t});if(r?.ok)return Be(await r.json().catch(()=>void 0))}function ze(e,t){let n=AbortSignal.timeout(t);return e?AbortSignal.any([e,n]):n}function Be(e){if(!e||typeof e!=`object`)return;let t=e;if(t.ok!==!0||typeof t.uploadId!=`string`)return;if(t.cacheHit===!0)return{kind:`cache-hit`,uploadId:t.uploadId};let n=t.upload;if(!n||typeof n.url!=`string`)return;let r=n.headers??{};if(Ve(r))return{kind:`direct-upload`,uploadId:t.uploadId,url:n.url,headers:r}}function Ve(e){return!e||typeof e!=`object`||Array.isArray(e)?!1:Object.values(e).every(e=>typeof e==`string`)}async function He(t,n,r,i){let a=await D({url:new URL(n.url),method:`PUT`,headers:n.headers,payloadPath:t.payloadPath,timeoutMessage:`Direct artifact upload timed out`,timeoutHint:`The direct upload ticket did not accept the artifact within the timeout.`,errorMessage:`Failed to upload artifact with direct upload ticket`,retryable:!0,signal:i,progress:{stage:`direct`,fileName:t.fileName,onProgress:r}});if(a.statusCode<200||a.statusCode>=300)throw new e(`COMMAND_FAILED`,`Direct artifact upload failed`,{statusCode:a.statusCode,statusMessage:a.statusMessage})}async function Ue(t){let n=new URL(`upload/finalize`,t.normalizedBase),r={"content-type":`application/json`};Object.assign(r,g(t.token));let i=await fetch(n,{method:`POST`,headers:r,signal:ze(t.signal,j),body:JSON.stringify({uploadId:t.uploadId})}).catch(n=>{throw t.signal?.aborted?n:new e(`COMMAND_FAILED`,`Failed to finalize direct artifact upload`,{},n)});if(!i.ok)throw new e(`COMMAND_FAILED`,`Direct artifact upload finalize failed`,{status:i.status,statusText:i.statusText});let a=await i.json().catch(()=>void 0);if(!a?.ok||!a.uploadId)throw new e(`COMMAND_FAILED`,`Invalid upload finalize response`);return a.uploadId}async function We(e,t,n){let r=[...e.positionals??[]],i=e.flags?{...e.flags}:void 0,a=e.meta?.installSource,o={},s,c=Te();if(!ut(t))return Xe({positionals:r,flags:i,installSource:a,uploadedArtifactId:s,clientArtifactPaths:o});Ge(e),i=qe(e,r,i,o);let l=await Ze(e,t,c,n);return l&&(a=l.installSource,s=l.uploadedArtifactId??s),e.command!==`install`&&e.command!==`reinstall`||(s=await Ke(e,t,r,c,n)??s),Xe({positionals:r,flags:i,installSource:a,uploadedArtifactId:s,clientArtifactPaths:o})}function Ge(t){if(t.flags?.saveScript!==void 0)throw new e(`INVALID_ARGS`,`--save-script is not supported against a remote daemon: the healed script would be written on the daemon host, not on this machine.`,{hint:`Run the script against a local daemon to capture a healed .ad, or re-run without --save-script.`,command:t.command})}async function Ke(e,t,n,r,i){let a=n.length===1?0:1,o=n[a];if(o===void 0)return;if(o.startsWith(`remote:`)){n[a]=o.slice(7);return}let s=Ye(o,e.meta?.cwd);if(s)return await M({localPath:s,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform,onProgress:r,signal:i})}function qe(e,t,n,r){let i=Qe(e,t);if(!i)return n;i.positionalIndex!==void 0&&i.positionalPath!==void 0&&(t[i.positionalIndex]=i.positionalPath);let a=Je(n,i.flagKey??`out`,i.flagPath);return r[i.field]=i.localPath,a}function Je(e,t,n){return n===void 0?e:{...e??{},[t]:n}}function Ye(e,t){let n=b.isAbsolute(e)?e:b.resolve(t??process.cwd(),e);return x.existsSync(n)?n:void 0}function Xe(e){return{positionals:e.positionals,flags:e.flags,installSource:e.installSource,uploadedArtifactId:e.uploadedArtifactId,...Object.keys(e.clientArtifactPaths).length>0?{clientArtifactPaths:e.clientArtifactPaths}:{}}}async function Ze(e,t,n,r){let i=e.meta?.installSource;if(e.command!==`install_source`||!i||i.kind!==`path`)return null;let a=i.path.trim();if(!a)return{installSource:i};if(a.startsWith(`remote:`))return{installSource:{...i,path:a.slice(7)}};let o=b.isAbsolute(a)?a:b.resolve(e.meta?.cwd??process.cwd(),a);if(!x.existsSync(o))return{installSource:{...i,path:o}};let s=await M({localPath:o,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform,onProgress:n,signal:r});return{installSource:{...i,path:o},uploadedArtifactId:s}}function Qe(e,t){if(e.command===`screenshot`){let n=rt(e,`path`,`.png`);return t[0]?{field:`path`,localPath:n,positionalIndex:0,positionalPath:I(`screenshot`,`.png`)}:{field:`path`,localPath:n,positionalIndex:0,flagPath:I(`screenshot`,`.png`)}}if(e.command===`record`&&(t[0]??``).toLowerCase()===`start`){if(!tt(e)&&e.flags?.platform===void 0)return null;let t=et(e),n=nt(rt(e,`outPath`,t,1),e);return{field:`outPath`,localPath:n,positionalIndex:1,positionalPath:I(`recording`,b.extname(n)||t)}}return e.command===`test`?{field:`artifactsDir`,localPath:$e(e),flagKey:`artifactsDir`,flagPath:at(`test-artifacts`)}:null}function $e(e){let t=e.flags?.artifactsDir;return it(F(t)?t:`.agent-device/test-artifacts`,e.meta?.cwd)}function et(e){return p(e.flags?.platform)}function tt(e){return F(e.positionals?.[1])||F(e.flags?.out)}function nt(e,t){return t.flags?.platform===`web`?m(e,et(t)):e}function rt(e,t,n,r=0){let i=e.positionals?.[r]??e.flags?.out,a=`${t===`path`?`screenshot`:`recording`}-${Date.now()}${n}`;return it(F(i)?i:a,e.meta?.cwd)}function it(e,t){return b.isAbsolute(e)?e:b.resolve(t??process.cwd(),e)}function F(e){return typeof e==`string`&&e.trim().length>0}function I(e,t){let n=t.startsWith(`.`)?t:`.${t}`;return b.posix.join(`/tmp`,`agent-device-${e}-${Date.now()}-${Math.random().toString(36).slice(2,8)}${n}`)}function at(e){return b.posix.join(`/tmp`,`agent-device-${e}-${Date.now()}-${Math.random().toString(36).slice(2,8)}`)}async function ot(e,t,n){let r=Array.isArray(n.data?.artifacts)?n.data.artifacts:[];if(r.length===0||!e.baseUrl)return n;let i=n.data?{...n.data}:{},a=[];for(let n of r){if(!n||typeof n!=`object`||typeof n.artifactId!=`string`){a.push(n);continue}let r=st(n,t),o=await ct({baseUrl:e.baseUrl,token:e.token,artifactId:n.artifactId,destinationPath:r,requestScope:t.meta,isDirectory:n.artifactType===`test-artifacts`});i[n.field]=o,a.push({...n,localPath:o})}return i.artifacts=a,{ok:!0,data:i}}function st(e,t){if(e.localPath&&e.localPath.trim().length>0)return e.localPath;let n=t.meta?.clientArtifactPaths?.[e.field];if(n&&n.trim().length>0)return n;let r=e.fileName?.trim()||`${e.field}-${Date.now()}`;return b.resolve(t.meta?.cwd??process.cwd(),r)}async function ct(e){let{downloadRemoteArtifactFromUrl:t}=await import(`./artifact-download.js`);return await t({artifactUrl:new URL(lt(e.baseUrl,e.artifactId)),token:e.token,artifactId:e.artifactId,destinationPath:e.destinationPath,requestScope:e.requestScope,...e.timeoutMs===void 0?{}:{timeoutMs:e.timeoutMs},...e.isDirectory===void 0?{}:{isDirectory:e.isDirectory}})}function lt(e,t){let n=e.endsWith(`/`)?e:`${e}/`;return new URL(`artifacts/${encodeURIComponent(t)}`,n).toString()}function ut(e){return typeof e.baseUrl==`string`&&e.baseUrl.length>0}const dt=3e3,ft=1e3;function pt(e){let t=Tt(e);if(!t||typeof t!=`object`)return null;let n=t,r=mt(n);if(!r)return null;let i=ht(n);return i?{token:r,...i,transport:_t(n.transport),pid:R(n.pid)??0,version:L(n.version),codeOrigin:gt(n.codeOrigin),codeSignature:L(n.codeSignature),processStartTime:L(n.processStartTime),policyDigest:L(n.policyDigest)}:null}function mt(e){return typeof e.token==`string`&&e.token.length>0?e.token:null}function ht(e){let t=R(e.port),n=R(e.httpPort);return t===void 0&&n===void 0?null:{port:t,httpPort:n}}function gt(e){return e===`installed`||e===`checkout`?e:void 0}function _t(e){return e===`socket`||e===`http`||e===`dual`?e:void 0}function L(e){return typeof e==`string`?e:void 0}function R(e){return Number.isInteger(e)&&Number(e)>0?Number(e):void 0}function z(e){let t=Tt(e);if(!t||typeof t!=`object`)return null;let n=t;return Number.isInteger(n.pid)&&Number(n.pid)>0?{pid:Number(n.pid),processStartTime:typeof n.processStartTime==`string`?n.processStartTime:void 0,startedAt:typeof n.startedAt==`number`?n.startedAt:void 0}:null}function vt(e,t){let n=z(e.lockPath);return n!==null&&n.pid!==t&&y(n.pid,n.processStartTime)}function B(e){Et(e)}function V(e){Et(e)}function yt(e){let t=H(e);if(!t.hasLock||t.hasInfo)return;let n=z(e.lockPath);if(!n){V(e.lockPath);return}y(n.pid,n.processStartTime)||V(e.lockPath)}async function bt(e,t,n={}){let r=n.stopLiveProcesses??!0,i={reason:t,removedInfo:!1,removedLock:!1,stoppedInfoProcess:!1,stoppedLockProcess:!1};try{let t=x.existsSync(e.infoPath),n=pt(e.infoPath);if(n){let t=y(n.pid,n.processStartTime);t&&!r?i.retainedInfoProcess=!0:(t&&(await U(n),i.stoppedInfoProcess=!0),B(e.infoPath),i.removedInfo=!0)}else t&&(B(e.infoPath),i.removedInfo=!0);let a=x.existsSync(e.lockPath),o=z(e.lockPath);if(o){let t=y(o.pid,o.processStartTime);t&&!r?i.retainedLockProcess=!0:(t&&(await se(o.pid,{termTimeoutMs:dt,killTimeoutMs:ft,expectedStartTime:o.processStartTime}),i.stoppedLockProcess=!0),V(e.lockPath),i.removedLock=!0)}else a&&(V(e.lockPath),i.removedLock=!0)}catch(e){i.error=e instanceof Error?e.message:String(e)}return u({level:i.error?`warn`:`info`,phase:`daemon_startup_metadata_cleanup`,data:i}),i}function H(e){return{hasInfo:x.existsSync(e.infoPath),hasLock:x.existsSync(e.lockPath)}}async function xt(e){let t=H(e);if(!t.hasLock||t.hasInfo)return!1;let n=z(e.lockPath);return!n||!y(n.pid,n.processStartTime)?(V(e.lockPath),!0):!1}async function U(e){await se(e.pid,{termTimeoutMs:dt,killTimeoutMs:ft,expectedStartTime:e.processStartTime})}function St(e){return typeof e.baseUrl==`string`&&e.baseUrl.length>0}function Ct(e,t=oe(process.env.AGENT_DEVICE_STATE_DIR)){let n=wt(t);return e.hasLock&&!e.hasInfo?`agent-device attempted to clean stale daemon metadata automatically, but ${t.lockPath} still exists without ${t.infoPath}. Retry with --debug; if this persists after confirming no agent-device daemon process is running, run: ${n}`:e.hasLock&&e.hasInfo?`agent-device attempted to clean stale daemon metadata automatically, but ${t.infoPath} and ${t.lockPath} still remain. Retry with --debug; if this persists after confirming no agent-device daemon process is running, run: ${n}`:e.hasInfo?`agent-device did not observe reachable daemon metadata after retrying, and ${t.infoPath} still remains. Stale metadata was cleaned automatically when safe; retry with --debug. If this persists after confirming no agent-device daemon process is running, run: ${n}`:`agent-device did not observe reachable daemon metadata after retrying. Stale metadata was cleaned automatically when safe; retry with --debug and check daemon diagnostics logs. If stale metadata returns after confirming no agent-device daemon process is running, run: ${n}`}function wt(e){return`rm -f ${ie(e.infoPath)} ${ie(e.lockPath)}`}function Tt(e){if(!x.existsSync(e))return null;try{return JSON.parse(x.readFileSync(e,`utf8`))}catch{return null}}function Et(e){try{x.existsSync(e)&&x.unlinkSync(e)}catch{}}function W(t,n,r){return new e(`COMMAND_FAILED`,`Invalid daemon response`,{requestId:t.meta?.requestId,line:n},r instanceof Error?r:void 0)}function Dt(e){let t=t=>(e.onError(t),!0);return{handleLine(n){let r;try{r=JSON.parse(n)}catch(r){return t(W(e.req,n,r))}if(ue(r))try{return e.onProgress?.(r.event),!1}catch(e){return t(e)}return ce(r)?(e.onResponse(r.response),!0):e.responseFormat===`socket-legacy`?(e.onResponse(r),!0):t(W(e.req,n,Error(`Missing daemon progress response envelope`)))}}}function Ot(e,t){return le(e)&&String(Array.isArray(t)?t.join(`,`):t??``).includes(`application/x-ndjson`)}function kt(e,t){let{req:n,isSettled:r,resolve:i,reject:a,clearTimeout:o}=t,s=``,c=Dt({req:n,onProgress:t.onProgress,responseFormat:`socket-legacy`,onResponse(t){o(),i(t),e.end()},onError(e){o(),a(e)}});e.setEncoding(`utf8`),e.on(`data`,e=>{if(r())return;let t=v(s,e);s=t.buffer;for(let e of t.lines)if(c.handleLine(e))return}),e.on(`end`,()=>{if(r())return;let e=s.trim();e&&c.handleLine(e)||(o(),a(W(n,e)))})}function At(t,n){let{req:r,handleResponseBody:i,reject:a,clearTimeout:o}=n,s=``,c=!1,l=Dt({req:r,onProgress:n.onProgress,responseFormat:`ndjson-envelope`,onResponse(e){c=!0,o(),i(JSON.stringify(e))},onError(e){c=!0,o(),a(e)}});t.setEncoding(`utf8`),t.on(`data`,e=>{if(c)return;let t=v(s,e);s=t.buffer;for(let e of t.lines)if(e&&l.handleLine(e))return}),t.on(`end`,()=>{if(c)return;let e=s.trim();e&&l.handleLine(e)||(c=!0,o(),a(W(r,e)))}),t.on(`error`,t=>{c||(c=!0,o(),a(new e(`COMMAND_FAILED`,`Failed to read daemon response`,{requestId:r.meta?.requestId},t instanceof Error?t:void 0)))})}const jt=1e4,Mt=8388608;function Nt(e,t){return h(e,`sessions/${encodeURIComponent(t.session)}/requests/${encodeURIComponent(t.requestId)}/diagnostics`)}function Pt(e){let{logPath:t,...n}=e;return n}async function Ft(e,t){let n=Pt(e),r=e.diagnosticsRecord,i=r?.requestId??t.requestId;if(!r)return G(n,t.endpoint,i,`the daemon named no diagnostics record`);try{let e=de(t.stateDir,r),a=await It({endpoint:t.endpoint,ref:r,destinationPath:e});return a?G(n,t.endpoint,i,a):{...n,logPath:e}}catch(e){return G(n,t.endpoint,i,e instanceof Error?e.message:String(e))}}function G(e,t,n,r){return{...e,logPathUnavailable:`remote daemon ${t.baseUrl}, request ${n??`unknown`}: ${r}`}}async function It(e){let{endpoint:t,ref:n,destinationPath:r}=e,i;try{i=new URL(Nt(t.baseUrl,n))}catch{return`daemon base URL is not a valid URL`}try{let e=await _(i.protocol);return await x.promises.mkdir(b.dirname(r),{recursive:!0}),await new Promise(n=>{let a=!1,o=e=>{if(!a){if(a=!0,clearTimeout(c),e===void 0){n(void 0);return}x.promises.rm(r,{force:!0}).finally(()=>{n(e)})}},s=e.request({protocol:i.protocol,host:i.hostname,port:i.port,method:`GET`,path:i.pathname+i.search,headers:{...g(t.token),...te(t.tenantId)}},e=>{let t=e.statusCode??500;if(t!==200){e.resume(),o(`HTTP ${t}`);return}let n=x.createWriteStream(r),i=0;e.on(`data`,e=>{i+=e.length,i>Mt&&(s.destroy(),n.destroy(),o(`record exceeds ${Mt} bytes`))}),e.on(`error`,e=>{n.destroy(),o(e.message)}),n.on(`error`,e=>{o(e.message)}),n.on(`finish`,()=>{o(void 0)}),e.pipe(n)}),c=setTimeout(()=>{o(`fetch timed out after ${jt}ms`),s.destroy()},jt);s.on(`error`,e=>{o(e.message)}),s.end()})}catch(e){return e instanceof Error?e.message:String(e)}}function Lt(t,n){let{info:r,req:i,stateDir:a,resolve:o,reject:s}=n;try{let n=Rt(t);if(n.error){zt(n.error,{info:r,req:i,stateDir:a,reject:s});return}if(!n.result||typeof n.result!=`object`){s(new e(`COMMAND_FAILED`,`Invalid daemon RPC response`,{requestId:i.meta?.requestId}));return}Ut(r,i,n.result,o,s)}catch(n){s(new e(`COMMAND_FAILED`,`Invalid daemon response`,{requestId:i.meta?.requestId,line:t},n instanceof Error?n:void 0))}}function Rt(e){return JSON.parse(e)}async function zt(e,t){let{info:n,req:r,stateDir:i,reject:a}=t,o=r.meta?.requestId,s=Bt(e);if(!n.baseUrl){a(Ht(s,o));return}a(Ht(await Ft(s,{endpoint:{baseUrl:n.baseUrl,token:n.token,tenantId:r.meta?.tenantId},stateDir:i,requestId:o}),o))}function Bt(e){let t=e.data??{},i=Vt(t.cause);return{code:r(t.code==null?void 0:String(t.code),`COMMAND_FAILED`),message:String(t.message??e.message??`Daemon RPC request failed`),cause:i,details:typeof t.details==`object`&&t.details?t.details:void 0,hint:typeof t.hint==`string`?t.hint:void 0,diagnosticId:typeof t.diagnosticId==`string`?t.diagnosticId:void 0,logPath:typeof t.logPath==`string`?t.logPath:void 0,diagnosticsRecord:n(t.diagnosticsRecord),retriable:typeof t.retriable==`boolean`?t.retriable:void 0,supportedOn:typeof t.supportedOn==`string`?t.supportedOn:void 0}}function Vt(e){return t(e)}function Ht(t,n){return new e(r(t.code,`COMMAND_FAILED`),t.message,{...t.details??{},hint:t.hint,diagnosticId:t.diagnosticId,logPath:t.logPath,logPathUnavailable:t.logPathUnavailable,diagnosticsRecord:t.diagnosticsRecord,retriable:t.retriable,supportedOn:t.supportedOn,requestId:n},t.cause)}async function Ut(e,t,n,r,i){try{r(e.baseUrl&&n.ok?await ot(e,t,n):n)}catch(e){i(e)}}function Wt(e,t){let n=e.meta?.requestId??l();return Gt(e.command)?{jsonrpc:`2.0`,id:n,method:Kt(e.command),params:{...qt(e,e.command,t),...e.command===`lease_allocate`?a(e.flags):{}}}:{jsonrpc:`2.0`,id:n,method:`agent_device.command`,params:e}}function Gt(e){return e===`lease_allocate`||e===`lease_heartbeat`||e===`lease_release`}function Kt(e){switch(e){case`lease_allocate`:return`agent_device.lease.allocate`;case`lease_heartbeat`:return`agent_device.lease.heartbeat`;case`lease_release`:return`agent_device.lease.release`}}function qt(e,t,n){return i(o(e),t,{includeTokenParam:n.includeTokenParam,token:e.token,session:e.session})}const Jt=[`xcodebuild .*AgentDeviceRunnerUITests/RunnerTests/testCommand`,String.raw`xcodebuild .*AgentDeviceRunner\.env\.session-`,String.raw`xcodebuild build-for-testing .*apple/runner/AgentDeviceRunner/AgentDeviceRunner\.xcodeproj`],Yt=new Set([`apple`,`ios`,`macos`]);function Xt(e){return e!==void 0&&Yt.has(e)}function K(t){let{info:n,statePaths:r,remote:i,timeoutMs:a,requestId:o,command:s,platform:c,session:l,action:d}=t,f=i?{terminated:0}:$t(),p=!i&&Zt(s),m=p?en(n,r):{forcedKill:!1},h=Xt(c)||f.terminated>0;return u({level:`error`,phase:`daemon_request_timeout`,data:{timeoutMs:a,requestId:o,command:s,timedOutRunnerPidsTerminated:f.terminated,timedOutRunnerCleanupError:f.error,daemonPidReset:p?n.pid:void 0,daemonPidForceKilled:p?m.forcedKill:void 0,daemonPreservedAfterTimeout:!i&&!p,daemonBaseUrl:n.baseUrl}}),new e(`COMMAND_FAILED`,`Daemon request timed out`,{timeoutMs:a,requestId:o,reason:`daemon_transport_timeout`,hint:Qt({remote:i,resetDaemon:p,command:s,appleCleanupEvidence:h,session:l,action:d})})}function Zt(e){return s(e).onTimeout===`reset-daemon`}function Qt(e){let{remote:t,resetDaemon:n,command:r,appleCleanupEvidence:i,session:a,action:o}=e;if(t)return r===c.record&&o===`stop`?`The remote daemon is still exporting the recording. Run agent-device record stop${a?` --session ${a}`:``} again to wait for that export and receive the completed recording.`:`Retry with --debug and verify the remote daemon URL, auth token, and remote host logs.`;if(!n){let e=i&&r===c.snapshot?` If this was the first Apple-platform snapshot on the device, run agent-device prepare ios-runner with the same --platform before snapshot/test so runner startup is handled explicitly.`:``;return`Retry with --debug and check daemon diagnostics logs. The timed-out ${r??`request`} request was canceled${i?` and Apple runner work was aborted when detected`:``}; the daemon was kept alive so the session can still be closed or inspected.${e}`}return i?`Retry with --debug and check daemon diagnostics logs. Timed-out Apple runner xcodebuild processes were terminated when detected.`:`Retry with --debug and check daemon diagnostics logs. The daemon was reset after the timeout.`}function $t(){let e=0;try{for(let t of Jt)f(`pkill`,[`-f`,t],{allowFailure:!0}).exitCode===0&&(e+=1);return{terminated:e}}catch(t){return{terminated:e,error:t instanceof Error?t.message:String(t)}}}function en(e,t){let n=!1;try{y(e.pid,e.processStartTime)&&(process.kill(e.pid,`SIGKILL`),n=!0)}catch{U(e)}finally{B(t.infoPath),V(t.lockPath)}return{forcedKill:n}}const tn=3e3,nn=`daemon_endpoint_unavailable`;function rn(t){return t instanceof e&&t.code===`COMMAND_FAILED`&&t.details?.reason===nn}function q(t){return new e(`COMMAND_FAILED`,t===`http`?`Daemon HTTP endpoint is unavailable`:`Daemon socket endpoint is unavailable`,{reason:nn,transport:t})}async function an(e,t){let n=_n(e,t);if(await J(e,n))return!0;let r=vn(e,t,n);return r?await J(e,r):!1}async function J(e,t){return t===`http`?await sn(e):await on(e.port)}function on(e){return e?new Promise(t=>{let n=!1,r=ve.createConnection({host:`127.0.0.1`,port:e},()=>{i(!0)}),i=e=>{n||(n=!0,r.destroy(),t(e))};r.setTimeout(500),r.on(`timeout`,()=>{i(!1)}),r.on(`error`,()=>{i(!1)})}):Promise.resolve(!1)}function sn(e){return ln(e).then(e=>e.reachable)}async function cn(t,n){let r=await ln(t,n);if(!t.baseUrl||!r.reachable)return r;let i=[r,r.upstream].find(e=>typeof e?.rpcProtocolVersion==`number`&&e.rpcProtocolVersion!==2);if(i)throw new e(`COMMAND_FAILED`,`Remote daemon RPC protocol is incompatible`,{daemonBaseUrl:t.baseUrl,clientVersion:ae(),remoteVersion:i.version,remoteService:i.service,supportedRpcProtocolVersion:2,remoteRpcProtocolVersion:i.rpcProtocolVersion,hint:`Upgrade agent-device on the client or remote host so both support the same daemon RPC protocol.`});return r}async function ln(e,t){let n=e.baseUrl?h(e.baseUrl,`health`):e.httpPort?`http://127.0.0.1:${e.httpPort}/health`:null;if(!n)return{reachable:!1};let r=new URL(n),i=await _(r.protocol),a=Math.min(e.baseUrl?tn:500,t??1/0);if(a<=0)return{reachable:!1,timedOut:!0};let o=AbortSignal.timeout(Math.ceil(a));return await new Promise(t=>{let n=e.baseUrl?g(e.token):{},s=()=>o.aborted?{reachable:!1,timedOut:!0}:{reachable:!1},c=i.request({protocol:r.protocol,host:r.hostname,port:r.port,path:r.pathname+r.search,method:`GET`,timeout:a,signal:o,headers:n},e=>{let n=``;e.setEncoding(`utf8`),e.on(`data`,e=>{n+=e}),e.on(`end`,()=>{let r=e.statusCode??500;t({reachable:r<500,statusCode:r,...un(n)})}),e.on(`error`,()=>t(s())),e.on(`aborted`,()=>t(s()))});c.on(`timeout`,()=>{c.destroy(),t({reachable:!1,timedOut:!0})}),c.on(`error`,()=>{t(s())}),c.end()})}function un(e){try{let t=JSON.parse(e),n=t.upstream&&typeof t.upstream==`object`?dn(t.upstream):void 0;return{...dn(t),...n?{upstream:n}:{}}}catch{return{}}}function dn(e){return{service:typeof e.service==`string`?e.service:void 0,version:typeof e.version==`string`?e.version:void 0,rpcProtocolVersion:typeof e.rpcProtocolVersion==`number`?e.rpcProtocolVersion:void 0,...typeof e.instanceId==`string`?{instanceId:e.instanceId}:{},...typeof e.hostArch==`string`?{hostArch:e.hostArch}:{}}}async function fn(e,t,n,r,i,a={}){let o=_n(e,n),s=typeof i==`number`?performance.now()+i:void 0;try{return await Y(e,t,r,i,o,a)}catch(c){if(e.baseUrl&&hn(c))return await pn(e,t,r,i,s,o,a);gn(c)&&$(e);let l=vn(e,n,o);if(!l||!yn(c,o))throw c;return await Y(e,t,r,i,l,a)}}async function pn(t,n,r,i,a,o,s){$(t);let c=mn(t,n,r,i,a),l=await cn(t,c);if(l.timedOut&&i!==void 0&&c!==void 0&&c<=tn)throw K({info:t,statePaths:r,...Z(n,!0,i)});let u=mn(t,n,r,i,a);if(!l.reachable)throw new e(`COMMAND_FAILED`,`Remote daemon is unavailable`,{daemonBaseUrl:t.baseUrl});t.remoteInstanceId=l.instanceId,t.remoteUpstreamInstanceId=l.upstream?.instanceId,Dn(t,l);try{return await Y(t,n,r,u,o,s)}catch(e){throw gn(e)&&$(t),e}}function mn(e,t,n,r,i){if(i===void 0||r===void 0)return;let a=i-performance.now();if(a>0)return a;throw K({info:e,statePaths:n,...Z(t,!0,r)})}function hn(t){return t instanceof e&&t.details?.reason===`remote_instance_mismatch`}function gn(t){return t instanceof e&&(t.details?.reason===`daemon_transport_failure`||t.details?.reason===`daemon_transport_timeout`||t.details?.reason===`daemon_response_read_failure`)}async function Y(e,t,n,r,i,a){return i===`http`?await Tn(e,t,n,r,a):await Sn(e,t,n,r,a)}function _n(t,n){if(t.baseUrl){if(n===`socket`)throw new e(`COMMAND_FAILED`,`Remote daemon endpoint only supports HTTP transport`,{daemonBaseUrl:t.baseUrl});return`http`}if(n===`http`||n===`socket`)return bn(t,n);let r=(t.transport===`socket`||t.transport===`dual`?[`socket`,`http`]:[`http`,`socket`]).find(e=>X(t,e));if(r)return r;throw new e(`COMMAND_FAILED`,`Daemon metadata has no reachable transport`)}function X(e,t){return t===`http`?!!e.httpPort:!!e.port}function vn(e,t,n){if(t!==`auto`||e.baseUrl)return null;let r=n===`socket`?`http`:`socket`;return X(e,r)?r:null}function yn(t,n){return n===`socket`&&t instanceof e&&t.code===`COMMAND_FAILED`&&t.message===`Failed to communicate with daemon`&&t.details?.daemonSocketRequestWritten===!1}function bn(e,t){if(X(e,t))return t;throw q(t)}function xn(t,n,r,i={}){return u({level:`error`,phase:`daemon_request_socket_error`,data:{requestId:n,message:t instanceof Error?t.message:String(t)}}),new e(`COMMAND_FAILED`,`Failed to communicate with daemon`,{...i,reason:`daemon_transport_failure`,requestId:n,hint:r?`Retry command. If this persists, verify the remote daemon URL, auth token, and remote host reachability.`:`Retry command. If this persists, clean stale daemon metadata and start a fresh session.`},t instanceof Error?t:void 0)}async function Sn(e,t,n,r,i){let a=e.port;if(!a)throw q(`socket`);return new Promise((o,s)=>{let c=!1,l=ve.createConnection({host:`127.0.0.1`,port:a},()=>{c=!0,l.write(`${JSON.stringify(t)}\n`)}),u=!1,d=typeof r==`number`?setTimeout(()=>{u=!0,l.destroy(),s(K({info:e,statePaths:n,...Z(t,!1,r)}))},r):void 0;kt(l,{req:t,onProgress:i.onProgress,isSettled:()=>u,clearTimeout:()=>{d&&clearTimeout(d)},resolve:e=>{u=!0,o(e)},reject:e=>{u=!0,s(e)}}),l.on(`error`,e=>{u||(u=!0,d&&clearTimeout(d),s(xn(e,t.meta?.requestId,!1,{daemonSocketRequestWritten:c})))})})}function Z(e,t,n){return{remote:t,timeoutMs:n,requestId:e.meta?.requestId,command:e.command,platform:e.flags?.platform,session:e.session,action:e.positionals?.[0]}}function Cn(e){return{...e.remoteInstanceId?{[re]:e.remoteInstanceId}:{},...e.remoteUpstreamInstanceId?{[ee]:e.remoteUpstreamInstanceId}:{}}}function wn(e,t){return e===409&&t[`x-agent-device-instance-mismatch`]===`true`}async function Tn(t,n,r,i,a){let o=t.baseUrl?new URL(h(t.baseUrl,`rpc`)):t.httpPort?new URL(`http://127.0.0.1:${t.httpPort}/rpc`):null;if(!o)throw q(`http`);let s=JSON.stringify(Wt(n,{includeTokenParam:!t.baseUrl})),c={"content-type":`application/json`,"content-length":Buffer.byteLength(s)};t.baseUrl&&(Object.assign(c,g(t.token)),Object.assign(c,Cn(t)));let l=await _(o.protocol);return await new Promise((u,d)=>{let f=l.request({protocol:o.protocol,host:o.hostname,port:o.port,method:`POST`,path:o.pathname+o.search,headers:c},i=>{if(wn(i.statusCode,i.headers??{})){i.resume(),m&&clearTimeout(m),d(new e(`COMMAND_FAILED`,`Remote daemon instance changed`,{reason:`remote_instance_mismatch`,daemonBaseUrl:t.baseUrl}));return}if(Ot(n,i.headers?.[`content-type`])){At(i,{req:n,onProgress:a.onProgress,reject:d,clearTimeout:()=>{m&&clearTimeout(m)},handleResponseBody:e=>{Lt(e,{info:t,req:n,stateDir:r.baseDir,resolve:u,reject:d})}});return}ne(i).catch(t=>{throw new e(`COMMAND_FAILED`,`Failed to read daemon response`,{requestId:n.meta?.requestId,reason:`daemon_response_read_failure`},t instanceof Error?t:void 0)}).then(e=>{m&&clearTimeout(m),Lt(e,{info:t,req:n,stateDir:r.baseDir,resolve:u,reject:d})}).catch(e=>{m&&clearTimeout(m),d(e)})}),p=St(t),m=typeof i==`number`?setTimeout(()=>{f.destroy(),d(K({info:t,statePaths:r,...Z(n,p,i)}))},i):void 0;f.on(`error`,e=>{m&&clearTimeout(m),d(xn(e,n.meta?.requestId,p))}),f.write(s),f.end()})}let Q;function En(e,t){return e.baseUrl===t.baseUrl&&e.token===t.token&&e.pid===t.pid}function Dn(e,t){!t.instanceId||t.upstream&&!t.upstream.instanceId||(Q={baseUrl:e.baseUrl??``,token:e.token,pid:e.pid,health:Promise.resolve(t)})}function $(e){Q&&En(Q,e)&&(Q=void 0)}async function On(e){if(Q&&En(Q,e))return await Q.health;let t={baseUrl:e.baseUrl??``,token:e.token,pid:e.pid,health:cn(e)};Q=t;try{let e=await t.health;return(!e.reachable||!e.instanceId||e.upstream&&!e.upstream.instanceId)&&Q===t&&(Q=void 0),e}catch(e){throw Q===t&&(Q=void 0),e}}export{bt as a,vt as c,xt as d,B as f,We as g,U as h,fn as i,St as l,Ct as m,an as n,yt as o,V as p,rn as r,H as s,On as t,pt as u};
|
package/dist/src/internal/bin.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
async function e(e,n,r){try{await t(e,n,r)}catch(e){r.stderr(`${e instanceof Error?e.message:String(e)}\n`),await(await n.processExit()).exitAfterFlush(1)}}async function t(e,t,l){if(e.length===0)return await n(t,l);if(o(e))return await r(t,l);let u=c(e);if(u!==void 0)return await i(u,e,t,l);if(s(e))return await(await t.mcp()).runAgentDeviceMcpServer();await a(e,t)}async function n(e,t){t.stdout(`${(await e.help()).buildUsageText()}\n`),await(await e.processExit()).exitAfterFlush(1)}async function r(e,t){t.stdout(`${t.bundledVersion??(await e.version()).readVersion()}\n`)}async function i(e,t,n,r){let i=await n.help(),o=e===null?`${i.buildUsageText()}\n`:i.resolveHelpTargetUsageText(e);if(o===null)return await a(t,n);r.stdout(o)}async function a(e,t){await(await t.cli()).runCliProcess(e)}function o(e){return e.length===1&&(e[0]===`--version`||e[0]===`-V`)}function s(e){return e[0]===`mcp`&&!e.some(l)}function c(e){let[t,n]=e;if(e.length===1)return t===`help`||l(t)?null:void 0;if(e.length===2)return t===`help`?n:l(n)?t:void 0}function l(e){return e===`--help`||e===`-h`}e(process.argv.slice(2),{help:()=>import(`../cli-help.js`).then(e=>e.n),cli:()=>import(`../process-entry.js`),mcp:()=>import(`../server.js`),version:()=>import(`../version.js`).then(e=>e.t),processExit:()=>import(`../process-exit.js`)},{bundledVersion:`0.21.
|
|
1
|
+
async function e(e,n,r){try{await t(e,n,r)}catch(e){r.stderr(`${e instanceof Error?e.message:String(e)}\n`),await(await n.processExit()).exitAfterFlush(1)}}async function t(e,t,l){if(e.length===0)return await n(t,l);if(o(e))return await r(t,l);let u=c(e);if(u!==void 0)return await i(u,e,t,l);if(s(e))return await(await t.mcp()).runAgentDeviceMcpServer();await a(e,t)}async function n(e,t){t.stdout(`${(await e.help()).buildUsageText()}\n`),await(await e.processExit()).exitAfterFlush(1)}async function r(e,t){t.stdout(`${t.bundledVersion??(await e.version()).readVersion()}\n`)}async function i(e,t,n,r){let i=await n.help(),o=e===null?`${i.buildUsageText()}\n`:i.resolveHelpTargetUsageText(e);if(o===null)return await a(t,n);r.stdout(o)}async function a(e,t){await(await t.cli()).runCliProcess(e)}function o(e){return e.length===1&&(e[0]===`--version`||e[0]===`-V`)}function s(e){return e[0]===`mcp`&&!e.some(l)}function c(e){let[t,n]=e;if(e.length===1)return t===`help`||l(t)?null:void 0;if(e.length===2)return t===`help`?n:l(n)?t:void 0}function l(e){return e===`--help`||e===`-h`}e(process.argv.slice(2),{help:()=>import(`../cli-help.js`).then(e=>e.n),cli:()=>import(`../process-entry.js`),mcp:()=>import(`../server.js`),version:()=>import(`../version.js`).then(e=>e.t),processExit:()=>import(`../process-exit.js`)},{bundledVersion:`0.21.18`,stdout:e=>{process.stdout.write(e)},stderr:e=>{process.stderr.write(e)}}).catch(()=>process.exit(1));export{};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-device",
|
|
3
|
-
"version": "0.21.
|
|
3
|
+
"version": "0.21.18",
|
|
4
4
|
"description": "Mobile app automation and verification for AI coding agents. CLI, MCP server, and typed Node.js API for iOS, Android, HarmonyOS, TV, web, macOS, and Linux.",
|
|
5
5
|
"mcpName": "io.github.callstack/agent-device",
|
|
6
6
|
"license": "MIT",
|
package/server.json
CHANGED
|
@@ -7,12 +7,12 @@
|
|
|
7
7
|
"url": "https://github.com/callstack/agent-device",
|
|
8
8
|
"source": "github"
|
|
9
9
|
},
|
|
10
|
-
"version": "0.21.
|
|
10
|
+
"version": "0.21.18",
|
|
11
11
|
"packages": [
|
|
12
12
|
{
|
|
13
13
|
"registryType": "npm",
|
|
14
14
|
"identifier": "agent-device",
|
|
15
|
-
"version": "0.21.
|
|
15
|
+
"version": "0.21.18",
|
|
16
16
|
"transport": {
|
|
17
17
|
"type": "stdio"
|
|
18
18
|
},
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
8217a388cb181b785090b23258a1c412319d03869d9627f9ee5a81f6746fbe48 agent-device-android-ime-helper-0.21.17.apk
|
package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.17.apk.sha256
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
b8801f4de4f76f9ed646694b0b0785c511a7a3cfef2744bdd746055176e1bf06 agent-device-android-snapshot-helper-0.21.17.apk
|