agent-device 0.21.17 → 0.21.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.17.apk → agent-device-android-ime-helper-0.21.19.apk} +0 -0
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.19.apk.sha256 +1 -0
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.17.manifest.json → agent-device-android-ime-helper-0.21.19.manifest.json} +4 -4
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.17.apk → agent-device-android-snapshot-helper-0.21.19.apk} +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.19.apk.sha256 +1 -0
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.17.manifest.json → agent-device-android-snapshot-helper-0.21.19.manifest.json} +6 -6
- package/dist/src/adapter.js +1 -1
- package/dist/src/adb-executor.js +2 -2
- package/dist/src/adb-failure.js +2 -1
- package/dist/src/agent-browser-lifecycle.js +1 -1
- package/dist/src/agent-browser-process-record.js +1 -1
- package/dist/src/agent-browser-provider.js +1 -1
- package/dist/src/agent-device-client.js +2 -2
- package/dist/src/ai-sdk.js +1 -1
- package/dist/src/alert-runtime.js +1 -1
- package/dist/src/android-input-ownership.js +1 -1
- package/dist/src/android.js +1 -1
- package/dist/src/app-log-runtime2.js +1 -1
- package/dist/src/cache.js +1 -1
- package/dist/src/catalog.js +1 -1
- package/dist/src/cli-help.js +1 -1
- package/dist/src/cli.js +4 -4
- package/dist/src/client-types.d.ts +11 -4
- package/dist/src/command-metadata.js +1 -1
- package/dist/src/command-tools.js +2 -2
- package/dist/src/contracts.js +1 -1
- package/dist/src/daemon-client-lease-beat.js +1 -1
- package/dist/src/daemon-client-lifecycle.js +1 -1
- package/dist/src/daemon-client-transport.js +1 -1
- package/dist/src/daemon-policy-file.js +1 -1
- package/dist/src/device-claim-inspection.js +1 -1
- package/dist/src/device-claim-rule.js +1 -1
- package/dist/src/device-inventory-context.js +1 -1
- package/dist/src/device-session.js +1 -1
- package/dist/src/diagnostics.js +1 -1
- package/dist/src/diagnostics2.js +1 -1
- package/dist/src/durable-resource.js +1 -1
- package/dist/src/engine-eval-script.js +1 -1
- package/dist/src/error.js +1 -1
- package/dist/src/find.js +1 -1
- package/dist/src/finders.js +1 -1
- package/dist/src/generic-settle.js +1 -1
- package/dist/src/gesture-runtime.js +1 -1
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.js +1 -1
- package/dist/src/input-actions2.js +2 -2
- package/dist/src/install-source-network-transport.js +1 -1
- package/dist/src/interaction-positionals.js +1 -1
- package/dist/src/interaction-ref-policy.js +1 -1
- package/dist/src/interaction.js +1 -1
- package/dist/src/interaction2.js +1 -1
- package/dist/src/interactor.js +5 -5
- package/dist/src/internal/bin.js +1 -1
- package/dist/src/internal/daemon.js +2 -2
- package/dist/src/internal/png-worker.js +1 -1
- package/dist/src/ios-snapshot-acquisition.js +1 -1
- package/dist/src/ios-snapshot-engine.js +1 -1
- package/dist/src/lease.js +1 -1
- package/dist/src/local-interactor-operation-set.js +1 -1
- package/dist/src/mechanics.js +16 -17
- package/dist/src/mobile-snapshot-semantics.js +1 -1
- package/dist/src/observe-until.js +1 -0
- package/dist/src/overlay.js +2 -2
- package/dist/src/parameterized-recorded-fill.js +1 -1
- package/dist/src/perf-facade.js +1 -1
- package/dist/src/perf-runtime-operation-builder.js +1 -1
- package/dist/src/perf-runtime-plan.js +1 -1
- package/dist/src/physical-device-control.js +1 -1
- package/dist/src/platform-request-scope.js +1 -1
- package/dist/src/platform-runtime-managed-owner.js +1 -1
- package/dist/src/platform-runtime-operation-host.js +1 -1
- package/dist/src/platform-runtime-screen-recording-process-host.js +1 -1
- package/dist/src/platform-runtime.js +1 -1
- package/dist/src/platform-runtime2.js +1 -1
- package/dist/src/png-worker-client.js +1 -1
- package/dist/src/provider-device-admission.js +1 -0
- package/dist/src/provider-webdriver.js +1 -1
- package/dist/src/proxy.js +1 -1
- package/dist/src/react-native.js +1 -1
- package/dist/src/record-runtime.js +1 -1
- package/dist/src/registry.js +36 -36
- package/dist/src/replay-divergence.js +1 -1
- package/dist/src/replay.js +1 -1
- package/dist/src/request-admission.js +1 -1
- package/dist/src/request-runtime-binding.js +1 -1
- package/dist/src/runner-cache-metadata.js +2 -2
- package/dist/src/runner-client.js +1 -1
- package/dist/src/runner-dev-tools-security.js +1 -1
- package/dist/src/runner-disposal.js +1 -1
- package/dist/src/runner-error-classification.js +3 -3
- package/dist/src/runner-exchange.js +1 -1
- package/dist/src/runner-start-budget.js +1 -1
- package/dist/src/runner-startup-transport.js +1 -1
- package/dist/src/runner-xctestrun.js +1 -1
- package/dist/src/runner.js +1 -1
- package/dist/src/runtime-admission.js +1 -0
- package/dist/src/runtime.js +1 -1
- package/dist/src/runtime10.js +2 -2
- package/dist/src/runtime2.js +1 -1
- package/dist/src/runtime3.js +1 -1
- package/dist/src/runtime4.js +4 -4
- package/dist/src/runtime5.js +1 -1
- package/dist/src/runtime6.js +1 -1
- package/dist/src/runtime7.js +1 -1
- package/dist/src/runtime8.js +1 -1
- package/dist/src/runtime9.js +1 -1
- package/dist/src/screen-recording-resource-recovery.js +1 -1
- package/dist/src/screenshot-runtime.js +1 -1
- package/dist/src/script.js +1 -1
- package/dist/src/scroll-gesture.js +1 -1
- package/dist/src/sdk-batch-runner.js +2 -2
- package/dist/src/sdk-batch.js +1 -1
- package/dist/src/sdk-contracts.d.ts +16 -2
- package/dist/src/sdk-contracts.js +2 -2
- package/dist/src/sdk-finders.js +1 -1
- package/dist/src/sdk-selectors.d.ts +9 -0
- package/dist/src/sdk-selectors.js +1 -1
- package/dist/src/selection.js +0 -0
- package/dist/src/selector-pipeline-policy.js +1 -0
- package/dist/src/selector-runtime.js +1 -1
- package/dist/src/selectors.js +1 -1
- package/dist/src/server.js +1 -1
- package/dist/src/session-runtime-admission.js +1 -1
- package/dist/src/session-snapshot.js +1 -1
- package/dist/src/session-store.js +3 -3
- package/dist/src/session2.js +5 -5
- package/dist/src/snapshot-desktop-projection.js +1 -1
- package/dist/src/snapshot-runtime-binding.js +1 -1
- package/dist/src/snapshot-runtime.js +1 -1
- package/dist/src/snapshot-state.js +1 -1
- package/dist/src/snapshot4.js +1 -1
- package/dist/src/src.js +1 -1
- package/dist/src/src7.js +1 -1
- package/dist/src/target-evidence.js +1 -1
- package/dist/src/text-entry-focus.js +1 -1
- package/dist/src/touch-runtime.js +1 -1
- package/dist/src/touch-runtime2.js +1 -0
- package/dist/src/tree.js +1 -1
- package/dist/src/type-text-runtime.js +1 -1
- package/dist/src/video.js +1 -1
- package/package.json +1 -1
- package/server.json +2 -2
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.17.apk.sha256 +0 -1
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.17.apk.sha256 +0 -1
- package/dist/src/runner-command-traits.js +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{N as e}from"./sdk-contracts.js";import{p as t}from"./sdk-device.js";import{
|
|
1
|
+
import{N as e}from"./sdk-contracts.js";import{p as t}from"./sdk-device.js";import{$t as n,tn as r}from"./sdk-batch.js";import{n as i,o as a,r as o,s}from"./request-cancellation.js";import{n as c,t as l}from"./application-lifecycle-runtime.js";import{A as u,B as d,C as f,D as ee,F as te,G as p,I as m,J as h,M as ne,N as re,R as ie,U as ae,V as g,d as _,h as v,k as oe,n as se,o as ce,q as le,s as ue,v as de,w as y,x as b,z as fe}from"./alert-runtime.js";import{n as pe}from"./audio-probe-runtime.js";import{n as me}from"./perf-runtime.js";import{i as he,n as ge}from"./touch-runtime.js";import{r as _e}from"./platform-runtime-unavailable.js";import{a as ve,n as ye}from"./durable-resource.js";import{t as be}from"./async-lifecycle.js";import{a as x,d as xe,f as Se,n as Ce,o as we,u as Te}from"./src7.js";import{i as Ee,t as De}from"./gesture-admission.js";import{n as Oe}from"./interactor-operation-catalog.js";import{t as S}from"./app-log-runtime.js";import{r as ke,t as Ae}from"./application-lifecycle-interaction.js";import{n as je,r as Me,t as Ne}from"./screen-recording-transport.js";import{setTimeout as Pe}from"node:timers/promises";const C=Object.freeze({available:!0}),Fe=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Limrun iOS direct sessions do not expose portable gesture execution yet.`}),Ie=Object.freeze({available:!1,reason:`unsupported-provider-mode`}),Le=Object.freeze({available:!1,reason:`unsupported-provider-mode`}),Re=Object.freeze({available:!1,reason:`unsupported-platform-leaf`,hint:De}),ze=Object.freeze({available:!1,reason:`unsupported-platform-leaf`,hint:Ee});function w(e,t){if(!t.available)return m({unsupported:t});if(e.platform!==`android`)return m({unsupported:Fe});let n=e.target===`tv`;return m({unsupported:Ie,plan:C,directionalFling:C,multiTouch:n?Re:C,targetAuthoredDrag:n?ze:C,viewport:C})}const Be=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Limrun iOS direct sessions do not expose home yet.`}),Ve=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Limrun iOS direct sessions do not expose tv remote control.`}),He=Object.freeze({available:!1,reason:`unsupported-device-kind`,hint:`tv-remote is supported only on Android TV targets.`}),Ue=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Limrun iOS direct sessions do not expose keyboard actions.`}),We=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Limrun iOS direct sessions do not expose clipboard access yet.`}),Ge=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Limrun iOS direct sessions do not expose settings changes yet.`}),Ke=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Limrun iOS direct sessions do not expose app switcher yet.`}),T=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`No Limrun session exposes this system button.`});function E(e,n){let r=n??C,i=Object.freeze({available:!1,reason:`unsupported-provider-mode`});return Object.freeze({...fe({focus:r}),...u({type:r}),...he({unsupported:i,tap:r,longPress:r,hover:n??i,fill:r,tapElementSelector:n??(t(e)?r:i)}),...w(e,r),...re({scroll:r})})}function qe(e){let{device:t,signal:n}=e,r=n=>e.getInteractor(t,n);return Object.freeze({...ae({device:t,signal:n,resolveInteractor:r,presentIosAcquisition:e.presentIosAcquisition}),...ie({device:t,signal:n,resolveInteractor:r}),...oe({device:t,signal:n,resolveInteractor:r}),...ge({device:t,signal:n,resolveInteractor:r,facts:E(t),pause:async e=>await Pe(e,void 0,{signal:n})}),...le({device:t,signal:n,resolveInteractor:r}),...te({device:t,signal:n,facts:w(t,C),resolveInteractor:r}),...ne({device:t,signal:n,resolveInteractor:r})})}function D(e,t){return t?Object.freeze({...y({back:t}),...f({orientation:t}),...b({tvRemote:t})}):e.platform===`android`?Object.freeze({...y({back:C}),...f({orientation:C}),...b({tvRemote:e.target===`tv`?C:He})}):Object.freeze({...y({back:C}),...f({orientation:C}),...b({tvRemote:Ve})})}function O(e,t){return t?Object.freeze({...v({unsupported:t})}):e.platform===`android`?Object.freeze({...v({unsupported:Le,read:C,write:C})}):Object.freeze({...v({unsupported:We})})}const Je=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Limrun iOS direct sessions do not expose alert inspection yet.`});function k(e,t){let n=t??(e.platform===`android`?C:Je);return Object.freeze({...se({read:n,wait:n,accept:n,dismiss:n})})}function A(e,t){return t?_({unsupported:t}):e.platform===`android`?_({unsupported:T,home:C,appSwitcher:C}):_({unsupported:T,home:Be,appSwitcher:Ke})}const j=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`fold runs a HID helper through simctl spawn inside a foldable iPhone simulator on the daemon host; a Limrun session has no such simulator.`});function M(){return Object.freeze({setFoldPose:j})}function N(e,t){return Object.freeze({...ue({triggerAppEvent:t??C})})}function P(e,t){let n=t??(e.platform===`android`?C:Ge);return Object.freeze({...ce({setSetting:n,readSetting:n})})}function F(e,t){let n=t??Ue,r=t===void 0&&e.platform===`android`;return Object.freeze({...de(r?{unsupported:n,status:C,dismiss:C,enter:C}:{unsupported:n})})}const I=Object.freeze({resourceKind:S,version:1,encode:e=>({...e}),decode:e=>e.transport!==`limrun-log-poller`||e.platform!==`ios`&&e.platform!==`android`||!L(e.leaseId)||!L(e.instanceId)||!L(e.appBundleId)||!L(e.outputPath)?{status:`invalid`,message:`Invalid Limrun app-log descriptor`}:{status:`decoded`,descriptor:Object.freeze({transport:`limrun-log-poller`,platform:e.platform,leaseId:e.leaseId,instanceId:e.instanceId,appBundleId:e.appBundleId,outputPath:e.outputPath})}});function Ye(e){if(e.device.platform===`apple`&&!e.device.appleOs)throw TypeError(`Limrun Apple app-log persistence requires an explicit appleOs identity`);return ye({resourceKind:S,sessionId:e.sessionId,device:{id:e.device.id,family:e.device.platform,...e.device.appleOs===void 0?{}:{appleOs:e.device.appleOs},kind:e.device.kind,...e.device.target===void 0?{}:{target:e.device.target},...e.device.iosPhysicalDeviceBackend===void 0?{}:{iosPhysicalDeviceBackend:e.device.iosPhysicalDeviceBackend}},owner:e.owner,fence:e.fence,lifecycle:`open`,descriptor:ve(I,e.descriptor)})}function L(e){return typeof e==`string`&&e.trim().length>0}async function R(e){let t=new be,n=!1;t.defer(async()=>{n||await e.reader[Symbol.asyncDispose]()});try{let r=await e.host.outputs.readTail(e.outputPath,262144),i=await e.host.outputs.openAppend(e.outputPath);t.defer(async()=>{n||await i[Symbol.asyncDispose]()});let a=Xe(e,i,tt(r));return n=!0,a}finally{await t[Symbol.asyncDispose]()}}function Xe(e,t,n){let r=rt(e.reader),i=e.host.clock.now(),a=`active`,o=!1,s=n,c=(async()=>{for(;!o;){try{let n=await Ze(e);if(n.status===`timeout`){a=`failed`;return}if(o)return;let r=Qe(s,n.text);s=n.text,r&&await t.write(r.endsWith(`
|
|
2
2
|
`)?r:`${r}\n`),a=`active`}catch{if(o)return;a=`recovering`}await e.host.clock.sleep(1e3)}})(),l;return Te({inspect:()=>({backend:r,state:a,startedAt:i}),finish:async()=>l??=(async()=>(o=!0,await c,(await nt([e.reader,t])).length>0?(a=`failed`,{status:`cleanup-pending`,reason:`transport-failed`,message:`Limrun app-log cleanup did not settle every owned resource`}):(a=`ended`,{status:`completed`,result:{backend:r,outputPath:e.outputPath,completedAt:e.host.clock.now()}})))()})}async function Ze(e){let t=new AbortController,n=i(e.reader.readLogs(e.appBundleId,1e3),t.signal,`App-log provider read aborted`).then(e=>({status:`read`,text:e}));try{let r=await Promise.race([n,e.host.clock.sleep(5e3,t.signal).then(()=>({status:`timeout`}))]);return r.status===`timeout`&&(t.abort(),await n.catch(()=>void 0)),r}finally{t.abort()}}function Qe(e,t){if(!e||!t)return t;let n=$e(t),r=Math.min(e.length,t.length),i=e.slice(e.length-r);return t.slice(et(i,t,n))}function $e(e){let t=new Uint32Array(e.length),n=0;for(let r=1;r<e.length;r+=1){for(;n>0&&e[r]!==e[n];)n=t[n-1];e[r]===e[n]&&(n+=1),t[r]=n}return t}function et(e,t,n){let r=0;for(let i=0;i<e.length;i+=1){for(;r>0&&e[i]!==t[r];)r=n[r-1];e[i]===t[r]&&(r+=1),r===t.length&&i<e.length-1&&(r=n[r-1])}return r}function tt(e){return e.split(`
|
|
3
3
|
`).filter(e=>!e.startsWith(`[agent-device][mark]`)).join(`
|
|
4
4
|
`)}async function nt(e){return(await Promise.allSettled(e.map(async e=>await e[Symbol.asyncDispose]()))).flatMap(e=>e.status===`rejected`?[e.reason]:[])}function rt(e){return e.platform===`ios`?`ios-simulator`:`android`}function it(e){let t=Ae({owner:`Limrun`,openTargetIdentity:`bundle-id`,closeBeforeRelaunch:!0,configureProviderPortReverse:async t=>await e.configurePortReverse(t),binding:ke({device:e.device,signal:e.signal,resolveInteractor:t=>e.getInteractor(e.device,t)})}),n=e.resolveAppReference;return n?Object.freeze({...t,resolveOpenTarget:async e=>await t.resolveOpenTarget(at(e,n)),openApplication:async e=>await t.openApplication(ot(e,n)),closeApplication:async e=>await t.closeApplication(st(e,n))}):t}function at(e,t){return e.target===void 0?e:{...e,target:t(e.target)}}function ot(e,t){return{...e,target:B(e.target,t),positionals:z(e.positionals,t),appBundleId:B(e.appBundleId,t)}}function st(e,t){return{...e,positionals:z(e.positionals,t),appBundleId:B(e.appBundleId,t)}}function z(e,t){let n=e[0];return n===void 0?e:[t(n),...e.slice(1)]}function B(e,t){return e===void 0?void 0:t(e)}function ct(e){let t=s(e.id);return!t||e.target!==`mobile`?!1:t.platform===`ios`?e.platform===`apple`&&e.appleOs===`ios`&&e.kind===`simulator`&&e.iosPhysicalDeviceBackend===void 0:e.platform===`android`&&e.appleOs===void 0&&e.kind===`emulator`&&e.iosPhysicalDeviceBackend===void 0}const lt=Object.freeze({available:!0}),V=Object.freeze({available:!1,reason:`owner-capability-missing`,hint:`The Limrun provider session is no longer active for this device.`}),ut=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Push notifications are unavailable for Limrun provider-owned devices.`});function H(e,t){let n=ft(e,t);return Object.freeze({deployApp:n,materializeAppSource:n,deployMaterializedApp:n,sendPushNotification:U(e,t)?ut:V})}function dt(e,t,n,r){let i=e.deployApp,a=e.deployMaterializedApp;return!H(e,t).deployApp.available||!i||!a?Object.freeze({}):Object.freeze({deployApp:async e=>W(await i(t,e,n,r)),materializeAppSource:async r=>await pt(e.host,t,r,n),deployMaterializedApp:async e=>W(await a(t,e,n,r))})}function ft(e,t){return ct(t)&&U(e,t)&&e.deployApp&&e.deployMaterializedApp?lt:V}function U(e,t){return e.isSessionActive?.(t)??e.ownsDevice(t)}async function pt(e,t,n,r){return await(t.platform===`apple`?e.appleDeployment:e.androidDeployment).prepareArtifact(n,{signal:r})}function W(t){if(!t)throw new e(`UNSUPPORTED_OPERATION`,`The Limrun provider session is no longer active.`);return t}const mt=Object.freeze({medium:5,high:8});function ht(e){return Object.freeze({screenRecordingStart:async t=>await gt(e,t),screenRecordingReattach:async()=>Me(`Limrun recordings cannot be reattached after daemon restart.`),screenRecordingCleanup:async()=>je(`Limrun recordings cannot be cleaned after daemon restart; the instance disposes them when it terminates.`)})}async function gt(t,n){let r=t.getDeviceSession(t.device);if(!r)throw new e(`UNSUPPORTED_OPERATION`,`Limrun recording requires a live provider session for this device.`,{deviceId:t.device.id});return await Ne({host:t.host,device:t.device,owner:t.owner,input:n,signal:t.signal,transport:{backend:`limrun-recorder`,targetLabel:`Limrun recording`,start:async()=>{await r.startRecording({quality:mt[n.exportQuality??`medium`]})},stop:async()=>(await r.stopRecording()).downloadUrl,collect:async(e,t)=>{await r.downloadRecording({downloadUrl:e,outPath:t})}},support:{scopes:[`app`,`device`,`system`],fps:!1,exportQuality:!0,hideTouches:!1},unsupported:e=>`Limrun recordings do not support ${e.join(`, `)}`})}const G=Object.freeze({available:!0}),K=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Custom snapshot actions are available only for Limrun iOS simulator sessions.`}),_t=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Limrun does not expose viewport resizing.`}),q=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Limrun-owned devices read element text from the captured tree only.`}),vt=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Headless boot is unavailable for provider-owned devices.`}),J=Object.freeze({available:!1,reason:`owner-capability-missing`,hint:`Limrun requires a matching live provider session for this device.`}),yt=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Apple runner preparation is unavailable for Limrun-owned devices.`}),bt=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Limrun iOS appstate is session-owned; no sessionless provider foreground probe is exposed.`}),xt=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Limrun open requires a Limrun-owned iOS simulator or Android emulator.`}),St=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Limrun close requires a Limrun-owned iOS simulator or Android emulator.`}),Y=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Runtime hints are not applied to provider-owned devices.`}),Ct=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Limrun port reverse requires an active Android Limrun session.`}),wt=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Limrun does not expose the audio probe.`});function Tt(e){return{...e,isSessionActive:e.hasLiveSession}}function X(e,t){let n=Et(e,t),r=Dt(e,t),i=Ot(e,t);return l({resolveOpenTarget:n,prepareApplicationOpen:n,openApplication:n,applyRuntimeHints:Y,clearRuntimeHints:Y,closeApplication:r,finalizeApplicationClose:r,prepareAppleRunner:yt,configureProviderPortReverse:i})}function Et(e,t){return a(e)?t?G:J:xt}function Dt(e,t){return a(e)?t?G:J:St}function Ot(e,t){return t?e.platform===`android`?G:Ct:J}function Z(e,n){let r=H(Tt(e),n),i=n.platform===`android`,a=t(n)&&n.kind===`simulator`?G:K;return Object.freeze({device:{family:n.platform,...n.appleOs===void 0?{}:{appleOs:n.appleOs},kind:n.kind,...n.target===void 0?{}:{target:n.target},...n.iosPhysicalDeviceBackend===void 0?{}:{iosPhysicalDeviceBackend:n.iosPhysicalDeviceBackend},providerMode:`provider-runtime`},operations:{appLogInspect:G,appLogDoctor:G,appLogStart:G,appLogReattach:G,appLogCleanup:G,...r,appState:i?G:bt,networkDump:G,screenRecordingStart:G,screenRecordingReattach:G,screenRecordingCleanup:G,...p({capture:G,customActions:a,withoutActiveApp:G}),...h({capture:G}),...g({findText:K}),...d({setViewport:_t}),...E(n),...ee({readTextAtPoint:q}),...D(n),...F(n),...O(n),...A(n),...M(),...N(n),...P(n),...k(n),...pe({capture:wt,query:wt}),...me({frames:q,memorySample:q,memorySnapshot:q,nativeCapture:q,profileReport:q}),ensureReady:G,bootTarget:G,bootTargetHeadless:vt,listApps:G,shutdownTarget:{available:!1,reason:`unsupported-provider-mode`,hint:`Limrun owns the target lifecycle for provider-owned devices.`},...X(n,!0)}})}function kt(e,t){let n=Z(e,t);return Object.freeze({device:n.device,operations:{...n.operations,appLogInspect:J,appLogDoctor:J,appLogStart:J,appLogReattach:G,appLogCleanup:G,appState:J,networkDump:J,screenRecordingStart:J,screenRecordingReattach:J,screenRecordingCleanup:J,...p({capture:J,customActions:J,withoutActiveApp:J}),...h({capture:J}),...g({findText:J}),...d({setViewport:J}),...E(t,J),...D(t,J),...F(t,J),...O(t,J),...A(t,J),...M(),...N(t,J),...P(t,J),...k(t,J),ensureReady:J,bootTarget:J,bootTargetHeadless:J,listApps:J,deployApp:J,materializeAppSource:J,deployMaterializedApp:J,sendPushNotification:J,shutdownTarget:J,...X(t,!1)}})}function At(t){let i=n(`limrun`,t.runtimeInstance),o=e=>a(e)&&t.ownsDevice(e),s=e=>o(e)&&t.hasLiveSession(e);return Object.freeze({owner:i,ownsDevice:o,inspectFacts:async e=>s(e)?Z(t,e):_e(e,i,{appLog:J,appState:J,appDeployment:J,network:J,screenshot:J,viewport:J,focus:J,gesture:J,scroll:J,typeText:J,touch:J,elementText:J,back:J,orientation:J,tvRemote:J,keyboard:J,clipboard:J,systemButton:J,fold:j,triggerAppEvent:J,settings:J,readAlert:J,awaitAlert:J,acceptAlert:J,dismissAlert:J,audioProbeCapture:J,audioProbeQuery:J,perf:J,readiness:J,shutdown:J,lifecycle:X(e,!1)}),bind:async n=>{if(n.intent.kind===`exact-owner`&&!r(n.intent.owner,i))throw new e(`UNSUPPORTED_OPERATION`,`Limrun app-log owner identity does not match`);if(!a(n.device))throw new e(`UNSUPPORTED_PLATFORM`,`Limrun app logs require an iOS simulator or Android emulator device identity`);let o=s(n.device);if(n.intent.kind!==`exact-owner`&&!o)throw new e(`UNSUPPORTED_OPERATION`,`Limrun provider session is no longer live for the selected device`,{reason:`provider-session-unavailable`});return jt(t,i,n.device,n.scope.signal,!o)},shutdown:async()=>void 0})}function jt(t,n,r,i,a){let s=a?kt(t,r):Z(t,r),l=o(),u=xe({codec:I,reattach:async(e,n)=>{if(!$(e,r)||!x(t.host,n.sessionId,e))return{status:`unreattachable`,reason:`descriptor-invalid`,message:`Limrun app-log descriptor does not match the bound device or owning session`};let a=await t.reconnect(e,i);return a.status===`missing`?{status:`missing`}:a.status===`ownership-lost`?{status:`unreattachable`,reason:`ownership-fence-lost`}:{status:`active`,handle:await R({host:t.host,reader:a.reader,appBundleId:e.appBundleId,outputPath:e.outputPath})}},cleanup:async(e,n)=>$(e,r)&&x(t.host,n.sessionId,e)?{status:`cleaned`}:{status:`cleanup-pending`,reason:`ownership-fence-lost`,message:`Limrun app-log descriptor does not match the bound device or owning session`}}),d={appLogInspect:async()=>({backend:Q(r)}),appLogDoctor:async()=>({backend:Q(r),checks:{limrunSessionAvailable:await Mt(t,r,i)},notes:[]}),appLogStart:async a=>{we(t.host,a),i.throwIfAborted();let o=await t.openCurrent(r);if(!o)throw new e(`UNSUPPORTED_OPERATION`,`Limrun app logs require an active instance`);let s={transport:`limrun-log-poller`,platform:o.platform,leaseId:o.leaseId,instanceId:o.instanceId,appBundleId:a.appBundleId,outputPath:a.outputPath},c=!1;try{i.throwIfAborted();let e=Ye({sessionId:a.sessionId,device:r,owner:n,fence:a.fence,descriptor:s});c=!0;let l=await R({host:t.host,reader:o,appBundleId:a.appBundleId,outputPath:a.outputPath});return Se(l,e)}catch(e){throw c||await o[Symbol.asyncDispose](),e}},...u,networkDump:async e=>{let n=await t.host.appLogs.readRecent(e.sessionId,e.maxScanLines),i=Q(r),{dump:a}=Ce(n.text,{...e,path:n.path,exists:n.exists,lineNumberOffset:n.skippedLines,backend:i}),o=a.entries.length===0?[`No HTTP(s) entries were found in recent session app logs.`]:[];return Object.freeze({source:`app-log`,backend:i,dump:a,notes:o})},ensureReady:async()=>({...r,booted:!0}),bootTarget:async()=>({...r,booted:!0}),listApps:async e=>await t.listApps(e.device,e.filter,i),...r.platform===`android`?{appState:async()=>await t.getAppState(r,i)}:{},...c(it({device:r,signal:i,getInteractor:t.getInteractor,resolveAppReference:e=>t.resolveAppReference?.(r,e)??e,configurePortReverse:t.configurePortReverse}),s.operations),...qe({device:r,signal:i,getInteractor:t.getInteractor,presentIosAcquisition:t.host.snapshot.presentIosAcquisition}),...Oe({device:r,signal:i,resolveInteractor:e=>t.getInteractor(r,e),facts:s.operations}),...dt(Tt(t),r,i,l),...ht({host:t.host,device:r,owner:n,signal:i,getDeviceSession:t.getDeviceSession})};return Object.freeze({device:r,owner:n,facts:s,operations:Object.freeze(a?{appLogReattach:u.appLogReattach,appLogCleanup:u.appLogCleanup}:d),[Symbol.asyncDispose]:async()=>await l[Symbol.asyncDispose]()})}async function Mt(e,t,n){n.throwIfAborted();let r=await e.openCurrent(t);if(!r)return!1;try{n.throwIfAborted()}finally{await r[Symbol.asyncDispose]()}return!0}function Q(e){return e.platform===`apple`?`ios-simulator`:`android`}function $(e,t){if(!a(t))return!1;let n=s(t.id);return n!==void 0&&n.leaseId===e.leaseId&&n.platform===e.platform&&(t.platform===`apple`?e.platform===`ios`:e.platform===`android`)}export{At as createLimrunPlatformRuntimeOwner};
|
package/dist/src/cache.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{G as e,N as t}from"./sdk-contracts.js";import{C as n,_ as r,f as i}from"./owner-identity.js";import{r as a}from"./exec.js";import{n as o,t as s}from"./file.js";import"./command.js";import"./process.js";import{n as c}from"./retry.js";import{C as l,D as u,c as d,h as f,n as p,o as m,w as h,y as g}from"./host-file.js";import{a as _}from"./tool-provider.js";import{t as v}from"./apple-runner-platform.js";import y from"node:path";import{createHash as b}from"node:crypto";function x(e){let{waitMs:t,signal:n,stop:r,cancelled:i}=e;return new Promise((e,a)=>{let o=()=>l(()=>a(i())),s=()=>l(e),c=setTimeout(()=>l(e),t);function l(e){clearTimeout(c),n?.removeEventListener(`abort`,o),r?.removeEventListener(`abort`,s),e()}n?.addEventListener(`abort`,o,{once:!0}),r?.addEventListener(`abort`,s,{once:!0}),n?.aborted?o():r?.aborted&&s()})}function S(e){let t=e.now??Date.now,n=e.waitGrant??`every-caller`,r=new Map,i=(n,i)=>{let a={status:`pending`,value:void 0,error:void 0,settledAtMs:t(),waitSpent:!1,controller:new AbortController,settled:void 0},o=()=>{};a.settled=new Promise(e=>{o=e}),r.set(n,a);let s=(i,s)=>{a.status=i,i===`ready`?a.value=s:a.error=s,a.settledAtMs=t(),(i===`ready`||e.retryAfterMs===void 0)&&r.get(n)===a&&r.delete(n),o()};try{i(a.controller.signal).then(e=>s(`ready`,e),e=>s(`failed`,e))}catch(e){s(`failed`,e)}return a},a=(n,a)=>{let o=r.get(n);if(!o)return i(n,a);if(o.status!==`failed`)return o;let s=t()-o.settledAtMs;return e.retryAfterMs===void 0||s>=e.retryAfterMs?i(n,a):o};return{value:async(t,r)=>{let i=a(t,r.start);if(i.status===`pending`&&(n===`every-caller`||!i.waitSpent)){i.waitSpent=!0;let t=new AbortController,n=r.wait(e.waitMs,t.signal);n.catch(()=>{});try{await Promise.race([i.settled,n])}finally{t.abort()}}if(i.status===`ready`)return i.value;throw i.status===`failed`?i.error:r.pending()},close:()=>{let e=[...r.values()];r.clear();for(let t of e)t.controller.abort()}}}async function C(e,t){let n=await _(`ps`,[`-p`,String(e),`-o`,`lstart=`],{allowFailure:!0,signal:t.signal,timeoutMs:t.timeoutMs});return n.exitCode===0&&n.stdout.trim()||null}var w=class extends t{buildFailureKind;buildFailureCode;buildDetails;constructor(e,t,n=`native build ${e}: ${t}`,r={},i){super(`COMMAND_FAILED`,n,{...r,nativeBuildFailure:e,nativeBuildFailureCode:t,...e===`cancelled`?{reason:`request_canceled`}:{}},i),this.name=`NativeBuildError`,this.buildFailureKind=e,this.buildFailureCode=t,this.buildDetails=r}};function T(e,t,n={},r){return new w(e,t,void 0,n,r)}function E(e,t,n=Date.now){if(t?.aborted)throw T(`cancelled`,`abort-signal`);return{clock:c.fromTimeoutMs(e,n()),now:n,signal:t}}function D(e,t){if(e.signal?.aborted)throw T(`cancelled`,`abort-signal`);let n=e.clock.remainingMs(e.now());if(n<=0)throw T(`timeout`,t);return Math.max(1,Math.floor(n))}function O(e){return{run:e,readText:g,readBinary:f,writeText:u,ensureDirectory:m,chmod:p,exists:d,rename:h,remove:l,acquireLock:k,processId:i,cpuArch:r}}async function k(e,t){let r=i(),a=t.deadline,o=s({lockDirPath:e,owner:{pid:r,startTime:n(r),acquiredAtMs:Date.now()},timeoutMs:D(a,`cache-lock-deadline`),pollMs:100,ownerGraceMs:5e3,description:t.description}),c=a.signal;if(!c)try{return await o}catch(e){throw A(e,a)}let l=!1,u,d=new Promise((e,t)=>{u=()=>{l=!0,t(T(`cancelled`,`abort-signal`))},c.addEventListener(`abort`,u,{once:!0}),c.aborted&&u()});try{return await Promise.race([o,d])}catch(e){throw l&&o.then(e=>e().catch(()=>void 0),()=>void 0),A(e,a)}finally{c.removeEventListener(`abort`,u)}}function A(e,t){return t.clock.isExpired()&&!(e instanceof w&&e.buildFailureKind===`cancelled`)?T(`timeout`,`cache-lock-deadline`):e}async function j(e,t){let n=await N(e,`xcodebuild`,[`-version`],t),r=await N(e,`sw_vers`,[`-productVersion`],t),i=await N(e,`sw_vers`,[`-buildVersion`],t),a=await M(e,t);if(a!==`arm64`&&a!==`x86_64`)throw T(`unsupported`,`simulator-architecture-unsupported`,{architecture:a});return{xcode:n,macosProductVersion:r,macosBuild:i,architecture:a}}async function M(e,t){let n=D(t,`host-arch-deadline`),r=t.signal,i,a,o=new Promise((e,t)=>{i=setTimeout(()=>t(T(`timeout`,`host-arch-deadline`)),n),i.unref?.(),a=()=>t(T(`cancelled`,`abort-signal`)),r?.addEventListener(`abort`,a,{once:!0})});try{return await Promise.race([e.cpuArch(),o])}finally{clearTimeout(i),a&&r?.removeEventListener(`abort`,a)}}async function N(e,t,n,r){let i=await P(e,t,n,r);if(i.exitCode!==0)throw T(`unsupported`,`toolchain-probe-failed`,{command:t,exitCode:i.exitCode,stderr:i.stderr.slice(0,1024)});let a=(i.stdout||i.stderr).trim();if(!a)throw T(`unsupported`,`toolchain-probe-empty`,{command:t});return a}async function P(e,t,n,r){let i=[],a;for(let o=1;;o+=1){let s;try{s=Math.min(v,D(r,`toolchain-probe-deadline`))}catch(e){throw a??e}i.push(s);try{return await L(e,t,n,r,s)}catch(e){if(a=F(e,t,r,i),o>=2)throw a}}}function F(t,n,r,i){if(e(t))throw T(`cancelled`,`abort-signal`,{},t);if(!a(t))throw t;if(r.signal?.aborted)throw T(`cancelled`,`abort-signal`);return I(n,i,t)}function I(e,t,n){let r=t.length;return T(`timeout`,`toolchain-probe-stalled`,{command:e,attemptTimeoutsMs:[...t],hint:`${e} did not answer within ${t[r-1]}ms on ${r} attempt(s). A toolchain probe that cannot answer is a host condition rather than a toolchain defect: run \`${e}\` by hand until it answers, then retry.`},n)}function L(e,t,n,r,i){return e.run(t,n,{allowFailure:!0,signal:r.signal,timeoutMs:i})}const R=`manifest.json`;async function z(e){let{host:t,deadline:n,cacheRoot:r,binaryFilename:i}=e,a=b(`sha256`).update(JSON.stringify(e.keyInputs)).digest(`hex`).slice(0,32),s=y.join(r,a);return await o({acquire:()=>t.acquireLock(y.join(r,`${a}.lock`),{deadline:n,description:e.lockDescription}),task:async()=>{let o=await B(t,s,i,a,n);if(o)return{path:o,cacheKey:a};D(n,`native-build-deadline`),t.exists(s)&&await t.remove(s),D(n,`native-build-deadline`),await t.ensureDirectory(r);let c=y.join(r,`.${a}.${t.processId()}.tmp`);D(n,`native-build-deadline`),await t.remove(c);try{D(n,`native-build-deadline`),await t.ensureDirectory(c);let r=y.join(c,i);await e.build(r),D(n,`native-build-deadline`),await t.chmod(r,493);let o=await H(t,r),l={...e.keyInputs,cacheKey:a,binarySha256:o};return await t.writeText(y.join(c,R),`${JSON.stringify(l,null,2)}\n`),D(n,`native-build-deadline`),await t.rename(c,s),{path:y.join(s,i),cacheKey:a}}catch(e){throw await t.remove(c),e}}})}async function B(e,t,n,r,i){let a=y.join(t,n),o=y.join(t,R);if(!(!e.exists(a)||!e.exists(o)))try{let t=JSON.parse(await e.readText(o));return t.cacheKey!==r||typeof t.binarySha256!=`string`?void 0:(D(i,`native-cache-hash-deadline`),await H(e,a)===t.binarySha256?a:void 0)}catch(e){if(V(e))throw e;return}}function V(e){return e instanceof w&&(e.buildFailureKind===`cancelled`||e.buildFailureKind===`timeout`)}async function H(e,t){return b(`sha256`).update(await e.readBinary(t)).digest(`hex`)}async function U(e,t,n,r){let i=b(`sha256`);for(let a of n){let n=y.join(t,a);if(D(r,`native-source-fingerprint-deadline`),!e.exists(n))throw T(`unsupported`,`native-source-missing`,{filePath:n});i.update(a),i.update(`\0`),i.update(await e.readBinary(n)),i.update(`\0`)}return i.digest(`hex`)}async function W(e){let t=Math.min(e.budgetMs,D(e.deadline,`native-build-deadline`));try{return await e.host.run(`xcrun`,[...e.argv],{signal:e.deadline.signal,timeoutMs:t,allowFailure:!0})}catch(n){throw a(n)?T(`timeout`,`native-build-stalled`,{timeoutMs:t,hint:`The Simulator SDK toolchain did not answer within ${t}ms, which stopped the ${e.label} build before clang reported anything. Run \`xcrun --sdk iphonesimulator clang --version\` by hand until it answers, then retry.`},n):n}}export{O as a,w as c,x as d,j as i,C as l,W as n,E as o,U as r,D as s,z as t,S as u};
|
package/dist/src/catalog.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{_ as e}from"./sdk-batch.js";const t=s(`public`),n=s(`internal`),r=s(`local-cli`),i={help:`help`};function a(){return[...Object.values(t),...Object.values(r)].sort()}function o(e){return Object.values(i).includes(e)||Object.values(n).includes(e)?!0:a().includes(e)}function s(t){let n={};for(let[r,i]of e(t))n[r]=i;return n}export{a as i,t as n,o as r,n as t};
|
package/dist/src/cli-help.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime.js";import{
|
|
1
|
+
import{r as e}from"./rolldown-runtime.js";import{vr as t}from"./sdk-batch.js";import{i as n}from"./catalog.js";import{r}from"./back-mode.js";import{C as i,N as a,S as o}from"./registry.js";import{a as s}from"./version.js";import{n as c,r as l}from"./command-schema.js";import{n as u}from"./cli-command-aliases.js";const d=[`Flows: launchApp (with clearState, permissions, and Apple-only launch arguments; permissions apply after state clearing but before launch, and a launchApp without permissions touches nothing — there is no silent all: allow default); setPermissions (mid-flow permission grants, denials, and resets; all resolves in the backend — one simctl call on iOS, the declared permissions on Android — with specific entries overriding after it); runFlow file/inline with platform, visibility, and limited boolean conditions; onFlowStart/onFlowComplete; repeat.times and retry.`,`Interactions: tapOn, doubleTapOn, longPressOn, inputText on the focused element, eraseText, openLink, hideKeyboard, basic pressKey, and back; selector targets poll until available and support recursive index, childOf, above, below, leftOf, rightOf, containsChild, containsDescendants, points, and optional; outer command labels are metadata, not target selectors.`,'Assertions and navigation: assertVisible, assertNotVisible, assertTrue (literal values and ${VAR} lookups only; "", "false", "0", "null", and "undefined" are falsy, everything else is truthy), extendedWaitUntil, scroll, scrollUntilVisible, absolute/percentage/target swipe, takeScreenshot, waitForAnimationToEnd, clearState, and stopApp.',`Scripts: ordered runScript file/env scripts with http.post, json, and output variables; evalScript inline expressions run flow-scoped JavaScript and write output.* leaves for later steps.`],f=[`Permissions: every entry is one settings permission call, applied in order with all first; the step stops at the first entry the selected platform refuses, earlier entries stay applied, and the error names what landed. Android’s only allow level is while-in-use, so location: inuse and location: never mean allow and deny there, while location: always and photos: limited are Apple-only and fail. On iOS, which service a runtime changes is simctl privacy’s own verdict: current runtimes refuse a targeted notifications change and leave notifications untouched under all.`,`Runtime: iOS and Android only; launchApp.clearState and standalone clearState support Android and iOS simulators, launch arguments are Apple-only, and other standalone device utility/state commands are unsupported.`,"Expressions: evalScript is the only command whose payload is evaluated as JavaScript (flow env and prior output leaves are string-typed); with that exception, fields stay literal or ${VAR} lookup-only — assertTrue supports literals and bare lookups, repeat.while is unsupported, and other expression-shaped payloads fail loud.",`Environment: flow env is the default, AD_VAR_* overrides it, and CLI -e KEY=VALUE wins over both.`,`Failure diagnostics: resolved targets and runFlow paths are rendered, while inputText payloads remain hidden; do not place secrets in diagnostic identifiers.`,`Trust: runScript and evalScript execute flow scripts in-process via node:vm, which is not a security sandbox; runScript may make http.post network requests and its output keys cannot contain a dot. evalScript is refused outright for a flow accepted over the daemon’s remote HTTP surface, since that context can escape to the host.`,`Errors and tracking: unsupported commands and fields fail with source context when available; open a focused issue only when implementation work is planned.`];function p(){return[`Supported subset:`,...d.map(e=>` - ${e}`),``,`Boundaries:`,...f.map(e=>` - ${e}`)].join(`
|
|
2
2
|
`)}function m(e){let t=e.endsWith(`?`),n=t?e.slice(0,-1):e;return t?`[${n}]`:`<${n}>`}function h(e){return r().filter(t=>t.key===e)}function g(e){if(!e.usageHidden)return e.usageLabel??e.names[0]}function _(e){return(e??[]).flatMap(e=>h(e).map(g).filter(e=>e!==void 0).map(e=>`[${e}]`))}function v(e,t){return[t.usageOverride??[e,...(t.positionalArgs??[]).map(m)].join(` `),..._(t.usageFlags??t.allowedFlags)].join(` `)}function y(){return`agent-device <command> [args] [--json]
|
|
3
3
|
|
|
4
4
|
Automates iOS, Android, macOS, TV, and web apps for AI agents.
|
package/dist/src/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{N as e,P as t,U as n,Y as r}from"./sdk-contracts.js";import{t as i}from"./capture.js";import{d as a,f as o,s,u as c}from"./sdk-batch-runner.js";import{n as l,r as u}from"./agent-device-client.js";import{s as d,t as f,u as p}from"./sdk-batch.js";import{i as m,r as h,t as g}from"./catalog.js";import{n as _,r as v}from"./back-mode.js";import{I as ee}from"./registry.js";import{a as y,i as b,l as te,n as ne,o as re,r as x}from"./diagnostics.js";import{f as ie}from"./exec.js";import{n as ae}from"./command-metadata.js";import"./diagnostics2.js";import"./command.js";import{a as oe}from"./version.js";import{t as se}from"./daemon-resolution.js";import{t as ce}from"./session-artifact-paths.js";import{r as S,t as le}from"./command-schema.js";import{n as C,r as w,t as ue}from"./cli-config.js";import{t as de}from"./update-check.js";import{n as fe,r as pe,t as me}from"./cli-command-aliases.js";import{exitAfterFlush as T}from"./process-exit.js";import{A as he,D as ge,M as _e,f as ve,h as ye,j as be,k as xe,r as Se}from"./connection-runtime.js";import{i as Ce}from"./auth-session.js";import E from"node:fs";import{pathToFileURL as we}from"node:url";const D=`open <app> --relaunch`,Te={start:{command:`open`,example:D},restart:{command:`open`,example:D},touch:{command:`press`,example:`press`},input:{command:`fill`,example:`fill`},settext:{command:`fill`,example:`fill`},entertext:{command:`fill`,example:`fill`},screencap:{command:`screenshot`,example:`screenshot`},capture:{command:`screenshot`,example:`screenshot`},dismiss:{command:`keyboard`,example:`keyboard dismiss`},"get-text":{command:`get`,example:`get text`},gettext:{command:`get`,example:`get text`},get_text:{command:`get`,example:`get text`},"open-url":{command:`open`,example:`open <url>`},"close-session":{command:`close`,example:`close`}};function Ee(e){if(e.length<=2)return[];let t=m(),n=t.filter(t=>t.startsWith(e));return n.length>0?n.sort(O).slice(0,3):k(e,t)}function O(e,t){return e.length-t.length||e.localeCompare(t)}function k(e,t){let n=t.map(t=>({name:t,distance:Oe(e,t)})).filter(t=>t.distance<=De(e));if(n.length===0)return[];let r=Math.min(...n.map(e=>e.distance));return n.filter(e=>e.distance===r).sort((e,t)=>e.name.localeCompare(t.name)).slice(0,3).map(e=>e.name)}function De(e){return e.length<4?1:e.length<=6?2:3}function Oe(e,t){return e===t?0:e.startsWith(t)||t.startsWith(e)?Math.abs(e.length-t.length):ke(e,t)}function ke(e,t){let n=e.length+1,r=t.length+1,i=Array.from({length:n},()=>Array(r).fill(0));for(let e=0;e<n;e+=1)i[e][0]=e;for(let e=0;e<r;e+=1)i[0][e]=e;for(let a=1;a<n;a+=1)for(let n=1;n<r;n+=1){let r=e[a-1]===t[n-1]?0:1;i[a][n]=Math.min(i[a-1][n]+1,i[a][n-1]+1,i[a-1][n-1]+r)}return i[n-1][r-1]}function A(e){let t=e.toLowerCase(),n=Te[t]?.example;if(n)return n;let r=Ee(t);if(r.length!==0)return r.length===1?r[0]:`one of: ${r.join(`, `)}`}const Ae=new Set([`--bundle-id`,`--bundleid`,`--bundle`,`--package`,`--package-name`,`--packagename`,`--app-id`,`--appid`,`--pkg`]),je=new Set([`--session-locked`,`--session-lock-conflicts`]),Me={"--output":`--out`,"--path":`--out`};function Ne(e,t){let n=e.toLowerCase(),r=Me[n];if(r&&Pe(r,t))return r;let i=Fe(n,t);if(i.length!==0)return i.length===1?i[0]:`one of: ${i.join(`, `)}`}function Pe(e,t){let n=v().find(t=>t.names.includes(e));return n?w(n.key,t):!1}function Fe(e,t){let n=j(e);if(n.length<=2)return[];let r=Ie(t),i=r.filter(e=>j(e).startsWith(n));return i.length>0?i.sort(O).slice(0,3):k(n,r.map(e=>j(e))).map(e=>`--${e}`)}function Ie(e){let t=new Set;for(let n of v()){if(!w(n.key,e))continue;let r=n.names[0];r&&t.add(r)}return[...t]}function j(e){return e.replace(/^--?/,``)}function Le(e,t){let n=e.toLowerCase();if(Ae.has(n))return`Unknown flag: ${e}. The app or bundle id is a positional argument, e.g. ${D}.`;if(je.has(n))return`Unknown flag: ${e}. Use --session-lock reject|strip instead.`;if(n===i.cliToken)return`Unknown flag: ${e}. ${i.migration.screenshot}. ${i.migration.record}.`;let r=Ne(e,t);return r?`Unknown flag: ${e}. Did you mean ${r}?`:`Unknown flag: ${e}`}function M(t){let n={json:!1,help:!1,version:!1},r=null,i=null,a=[],o=[],s=[],c=!0;for(let o=0;o<t.length;o+=1){let l=t[o];if(c&&l===`--`){c=!1;continue}if(!c){r?a.push(l):(i=l,r=L(l));continue}if(Ve(r)){a.push(l);continue}let u=l.startsWith(`--`),d=l.startsWith(`-`)&&l.length>1;if(!u&&!d){r?a.push(l):(i=l,r=L(l));continue}let[f,p]=u?N(l):[l,void 0];if(ze(r,f))continue;let m=He(f,r);if(Be(r,m)){a.push(l);continue}if(!m){if(qe(r,a,l)){r?a.push(l):r=l;continue}throw new e(`INVALID_ARGS`,Le(f,r))}let h=Ge(m,f,p,t[o+1]);h.consumeNext&&(o+=1);let g=n[m.key];if(m.multiple){let e=Array.isArray(g)?[...g,h.value]:g===void 0?[h.value]:[g,h.value];n[m.key]=e}else n[m.key]=h.value;s.push({key:m.key,token:f})}return Re(i,n),{command:r,positionals:a,flags:n,warnings:o,providedFlags:s}}function Re(e,t){if(e)for(let n of me(e)?.impliedFlags??[])t[n]=!0}function ze(e,t){return t===`-c`&&(e===`snapshot`||e===`diff`)}function Be(e,t){return e===`react-devtools`?!t||!w(t.key,e):!1}function Ve(e){return e===`cdp`}function He(e,t){let n=v().filter(t=>t.names.includes(e));if(n.length<=1)return n[0]??_(e);if(t){let e=n.find(e=>w(e.key,t));if(e)return e}return _(e)}function Ue(t,n){let r=n?.strictFlags??!0,i=[...t.warnings],a=C({json:!1,help:!1,version:!1},n?.defaultFlags??{});if(C(a,t.flags),t.command&&!h(t.command)&&!a.help){let n=A(t.command),r=n?`Unknown command: ${t.command}. Did you mean ${n}?`:`Unknown command: ${t.command}`;throw new e(`INVALID_ARGS`,r)}let o=t.providedFlags.filter(e=>!w(e.key,t.command));if(o.length>0){let n=o.map(e=>e.token),s=Qe(t.command,n);if(r)throw new e(`INVALID_ARGS`,s);i.push(s);for(let e of o)delete a[e.key]}let s=Xe(t);if(s.length>0){let n=Ze(t.command,t.positionals[0],s);if(r)throw new e(`INVALID_ARGS`,n);i.push(n);for(let e of s)delete a[e.key]}for(let e of Object.keys(a))a[e]!==void 0&&(w(e,t.command)||delete a[e]);We(t),p(t.command,a);let c=Ye({command:t.command,positionals:t.positionals,flags:a,warnings:i});if(le(c.command,c.positionals),c.command===`batch`&&+!!a.steps+ +!!a.stepsFile!=1)throw new e(`INVALID_ARGS`,`batch requires exactly one step source: --steps or --steps-file.`);return c}function We(t){if(t.command!==`back`)return;let n=t.providedFlags.filter(e=>e.key===`backMode`);if(!(new Set(n.map(e=>e.token)).size<=1))throw new e(`INVALID_ARGS`,`back accepts only one explicit mode flag: use either --in-app or --system.`)}function N(e){let t=e.indexOf(`=`);return t===-1?[e,void 0]:[e.slice(0,t),e.slice(t+1)]}function Ge(t,n,r,i){if(t.setValue!==void 0){if(r!==void 0)throw new e(`INVALID_ARGS`,`Flag ${n} does not take a value.`);return{value:t.setValue,consumeNext:!1}}if(t.type===`boolean`){if(r!==void 0)throw new e(`INVALID_ARGS`,`Flag ${n} does not take a value.`);return{value:!0,consumeNext:!1}}if(t.type===`booleanOrString`){if(r!==void 0){if(r.trim().length===0)throw new e(`INVALID_ARGS`,`Flag ${n} requires a non-empty value when provided.`);return{value:r,consumeNext:!1}}return i===void 0||F(i)?{value:!0,consumeNext:!1}:Ke(i)?{value:i,consumeNext:!0}:{value:!0,consumeNext:!1}}let a=r??i;if(a===void 0||r===void 0&&F(a))throw new e(`INVALID_ARGS`,`Flag ${n} requires a value.`);if(t.type===`string`)return{value:a,consumeNext:r===void 0};if(t.type===`enum`){if(!t.enumValues?.includes(a))throw new e(`INVALID_ARGS`,`Invalid ${P(n)}: ${a}`);return{value:a,consumeNext:r===void 0}}let o=Number(a);if(!Number.isFinite(o)||typeof t.min==`number`&&o<t.min||typeof t.max==`number`&&o>t.max)throw new e(`INVALID_ARGS`,`Invalid ${P(n)}: ${a}`);return{value:t.type===`int`?Math.floor(o):o,consumeNext:r===void 0}}function P(e){return e.replace(/^-+/,``)}function F(e){if(!e.startsWith(`-`)||e===`-`)return!1;let[t]=e.startsWith(`--`)?N(e):[e,void 0];return _(t)!==void 0}function Ke(e){let t=e.trim();return!t||/^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(t)?!1:!!(t.startsWith(`./`)||t.startsWith(`../`)||t.startsWith(`~/`)||t.startsWith(`/`)||t.includes(`/`)||t.includes(`\\`))}function qe(e,t,n){if(!Je(n)||!e)return!1;let r=S(e);if(!r||r.allowsExtraPositionals)return!0;let i=r.positionalArgs??[];return i.length===0?!1:t.length<i.length||i.some(e=>e.includes(`?`))}function Je(e){return/^-\d+(\.\d+)?$/.test(e)}function Ye(e){if(e.flags.help)return e;if(e.command===`snapshot`&&e.flags.snapshotDiff){let{snapshotDiff:t,...n}=e.flags;return{command:`diff`,positionals:[`snapshot`,...e.positionals],flags:n,warnings:e.warnings}}return e}function Xe(e){let t=S(e.command)?.flagsByAction,n=e.positionals[0];if(t===void 0||n===void 0||!Object.hasOwn(t,n))return[];let r=t[n];if(r===void 0)return[];let i=new Set(Object.values(t).flat());return e.providedFlags.filter(e=>i.has(e.key)&&!r.includes(e.key))}function Ze(e,t,n){return`${e} ${t} does not read ${n.map(e=>e.token).join(`, `)}. Run \`${e} ${t} --help\` for the options it reads.`}function Qe(e,t){return e?t.length===1?`Flag ${t[0]} is not supported for command ${e}.`:`Flags ${t.join(`, `)} are not supported for command ${e}.`:t.length===1?`Flag ${t[0]} requires a command that supports it.`:`Flags ${t.join(`, `)} require a command that supports them.`}async function I(){let{buildUsageText:e}=await import(`./cli-help.js`).then(e=>e.n);return e()}async function $e(e){let{buildCommandUsageText:t}=await import(`./cli-help.js`).then(e=>e.n);return t(L(e))}function L(t){let n=pe(t);if(n)throw new e(`INVALID_ARGS`,n);return fe(t)}function et(){return{renderedToStderr:!1}}function tt(e){return t=>{t.type===`command`&&(e.renderedToStderr=!0,process.stderr.write(`${t.message}\n`))}}function nt(e){return ae(e)}const rt={connect:async()=>(await import(`./connection.js`)).connectCommand,disconnect:async()=>(await import(`./connection.js`)).disconnectCommand,connection:async()=>(await import(`./connection.js`)).connectionCommand,auth:async()=>(await import(`./auth.js`)).authCommand,daemon:async()=>(await import(`./daemon.js`)).daemonCommand,device:async()=>(await import(`./device2.js`)).deviceCommand,proxy:async()=>(await import(`./proxy.js`)).proxyCommand,takeover:async()=>(await import(`./takeover.js`)).takeoverCommand,replay:async()=>(await import(`./replay.js`)).replayCommand,screenshot:async()=>(await import(`./screenshot3.js`)).screenshotCommand,diff:async()=>(await import(`./screenshot3.js`)).diffCommand,record:async()=>(await import(`./recording.js`)).recordingCommand};async function R(e){let t={...e.flags},n=rt[e.command];return n&&await(await n())({...e,flags:t})?!0:nt(e.command)?await it({...e,command:e.command,flags:t}):!1}async function it(e){let{runGenericClientBackedCommand:t}=await import(`./generic.js`);return await t(e)}function at(e){return[`exec`,`--yes`,`--package`,`agent-react-devtools@0.5.0`,`--`,`agent-react-devtools`,...e]}function ot(e){return e===`ios-instance`}function st(e){return e[0]===`wait`&&e.includes(`--connected`)}function ct(e,t,n){n===0||!st(e)||!ot(t?.leaseBackend)||process.stderr.write([`Hint: Remote iOS React DevTools connects during JavaScript startup.`,"If the app was already open before `agent-device react-devtools start`, relaunch it with `agent-device open <bundle-id> --platform ios --relaunch`, then retry `agent-device react-devtools wait --connected`.",``].join(`
|
|
2
|
-
`))}function z(e,t,n){return n||(e.push(t),``)}function lt(
|
|
3
|
-
`)}function q(e){let t=e.effectiveFlags,n=e.connectionMetadata;return{session:t.session,requestId:e.requestId,stateDir:t.stateDir,daemonBaseUrl:t.daemonBaseUrl,daemonAuthToken:t.daemonAuthToken,daemonTransport:t.daemonTransport,daemonServerMode:t.daemonServerMode,tenant:t.tenant,sessionIsolation:t.sessionIsolation,runId:t.runId,leaseId:t.leaseId,leaseBackend:t.leaseBackend,leaseProvider:n?.leaseProvider,clientId:n?.clientId,deviceKey:n?.deviceKey,providerApp:t.providerApp,providerOsVersion:t.providerOsVersion,providerProject:t.providerProject,providerBuild:t.providerBuild,providerSessionName:t.providerSessionName,providerDeviceOrientation:t.providerDeviceOrientation,providerGeoLocation:t.providerGeoLocation,providerTimezone:t.providerTimezone,providerAppiumVersion:t.providerAppiumVersion,providerLanguage:t.providerLanguage,providerLocale:t.providerLocale,providerNetworkProfile:t.providerNetworkProfile,providerCustomNetwork:t.providerCustomNetwork,providerNoResignApp:t.providerNoResignApp,awsProjectArn:t.awsProjectArn,awsDeviceArn:t.awsDeviceArn,awsAppArn:t.awsAppArn,awsRegion:t.awsRegion,awsInteractionMode:t.awsInteractionMode,runtime:e.resolvedRuntime,lockPolicy:e.binding.lockPolicy,lockPlatform:e.binding.defaultPlatform,cwd:process.cwd(),debug:e.debugOutputEnabled,cost:t.cost,responseLevel:t.responseLevel}}function At(e){let t=e.effectiveFlags.daemonBaseUrl;return e.debugOutputEnabled&&!e.effectiveFlags.json&&!t?Jt(e.daemonPaths.logPath):null}async function jt(e){if(e.command!==`test`)return;let{createReplayTestReporterRuntime:t}=await import(`./reporting.js`);return t({debug:e.debugOutputEnabled,verbose:e.effectiveFlags.verbose,json:e.effectiveFlags.json,reporter:e.effectiveFlags.reporter,reportJunit:e.effectiveFlags.reportJunit})}async function Mt(
|
|
1
|
+
import{$ as e,N as t,P as n,q as r}from"./sdk-contracts.js";import{t as i}from"./capture.js";import{d as a,f as o,s,u as c}from"./sdk-batch-runner.js";import{n as l,r as u}from"./agent-device-client.js";import{s as d,t as f,u as p}from"./sdk-batch.js";import{i as m,r as h,t as g}from"./catalog.js";import{n as _,r as v}from"./back-mode.js";import{I as ee}from"./registry.js";import{a as y,i as b,l as te,n as ne,o as re,r as x}from"./diagnostics.js";import{f as ie}from"./exec.js";import{n as ae}from"./command-metadata.js";import"./diagnostics2.js";import"./command.js";import{a as oe}from"./version.js";import{t as se}from"./daemon-resolution.js";import{t as ce}from"./session-artifact-paths.js";import{r as S,t as le}from"./command-schema.js";import{n as C,r as w,t as ue}from"./cli-config.js";import{t as de}from"./update-check.js";import{n as fe,r as pe,t as me}from"./cli-command-aliases.js";import{exitAfterFlush as T}from"./process-exit.js";import{A as he,D as ge,M as _e,f as ve,h as ye,j as be,k as xe,r as Se}from"./connection-runtime.js";import{i as Ce}from"./auth-session.js";import E from"node:fs";import{pathToFileURL as we}from"node:url";const D=`open <app> --relaunch`,Te={start:{command:`open`,example:D},restart:{command:`open`,example:D},touch:{command:`press`,example:`press`},input:{command:`fill`,example:`fill`},settext:{command:`fill`,example:`fill`},entertext:{command:`fill`,example:`fill`},screencap:{command:`screenshot`,example:`screenshot`},capture:{command:`screenshot`,example:`screenshot`},dismiss:{command:`keyboard`,example:`keyboard dismiss`},"get-text":{command:`get`,example:`get text`},gettext:{command:`get`,example:`get text`},get_text:{command:`get`,example:`get text`},"open-url":{command:`open`,example:`open <url>`},"close-session":{command:`close`,example:`close`}};function Ee(e){if(e.length<=2)return[];let t=m(),n=t.filter(t=>t.startsWith(e));return n.length>0?n.sort(O).slice(0,3):k(e,t)}function O(e,t){return e.length-t.length||e.localeCompare(t)}function k(e,t){let n=t.map(t=>({name:t,distance:Oe(e,t)})).filter(t=>t.distance<=De(e));if(n.length===0)return[];let r=Math.min(...n.map(e=>e.distance));return n.filter(e=>e.distance===r).sort((e,t)=>e.name.localeCompare(t.name)).slice(0,3).map(e=>e.name)}function De(e){return e.length<4?1:e.length<=6?2:3}function Oe(e,t){return e===t?0:e.startsWith(t)||t.startsWith(e)?Math.abs(e.length-t.length):ke(e,t)}function ke(e,t){let n=e.length+1,r=t.length+1,i=Array.from({length:n},()=>Array(r).fill(0));for(let e=0;e<n;e+=1)i[e][0]=e;for(let e=0;e<r;e+=1)i[0][e]=e;for(let a=1;a<n;a+=1)for(let n=1;n<r;n+=1){let r=e[a-1]===t[n-1]?0:1;i[a][n]=Math.min(i[a-1][n]+1,i[a][n-1]+1,i[a-1][n-1]+r)}return i[n-1][r-1]}function A(e){let t=e.toLowerCase(),n=Te[t]?.example;if(n)return n;let r=Ee(t);if(r.length!==0)return r.length===1?r[0]:`one of: ${r.join(`, `)}`}const Ae=new Set([`--bundle-id`,`--bundleid`,`--bundle`,`--package`,`--package-name`,`--packagename`,`--app-id`,`--appid`,`--pkg`]),je=new Set([`--session-locked`,`--session-lock-conflicts`]),Me={"--output":`--out`,"--path":`--out`};function Ne(e,t){let n=e.toLowerCase(),r=Me[n];if(r&&Pe(r,t))return r;let i=Fe(n,t);if(i.length!==0)return i.length===1?i[0]:`one of: ${i.join(`, `)}`}function Pe(e,t){let n=v().find(t=>t.names.includes(e));return n?w(n.key,t):!1}function Fe(e,t){let n=j(e);if(n.length<=2)return[];let r=Ie(t),i=r.filter(e=>j(e).startsWith(n));return i.length>0?i.sort(O).slice(0,3):k(n,r.map(e=>j(e))).map(e=>`--${e}`)}function Ie(e){let t=new Set;for(let n of v()){if(!w(n.key,e))continue;let r=n.names[0];r&&t.add(r)}return[...t]}function j(e){return e.replace(/^--?/,``)}function Le(e,t){let n=e.toLowerCase();if(Ae.has(n))return`Unknown flag: ${e}. The app or bundle id is a positional argument, e.g. ${D}.`;if(je.has(n))return`Unknown flag: ${e}. Use --session-lock reject|strip instead.`;if(n===i.cliToken)return`Unknown flag: ${e}. ${i.migration.screenshot}. ${i.migration.record}.`;let r=Ne(e,t);return r?`Unknown flag: ${e}. Did you mean ${r}?`:`Unknown flag: ${e}`}function M(e){let n={json:!1,help:!1,version:!1},r=null,i=null,a=[],o=[],s=[],c=!0;for(let o=0;o<e.length;o+=1){let l=e[o];if(c&&l===`--`){c=!1;continue}if(!c){r?a.push(l):(i=l,r=L(l));continue}if(Ve(r)){a.push(l);continue}let u=l.startsWith(`--`),d=l.startsWith(`-`)&&l.length>1;if(!u&&!d){r?a.push(l):(i=l,r=L(l));continue}let[f,p]=u?N(l):[l,void 0];if(ze(r,f))continue;let m=He(f,r);if(Be(r,m)){a.push(l);continue}if(!m){if(qe(r,a,l)){r?a.push(l):r=l;continue}throw new t(`INVALID_ARGS`,Le(f,r))}let h=Ge(m,f,p,e[o+1]);h.consumeNext&&(o+=1);let g=n[m.key];if(m.multiple){let e=Array.isArray(g)?[...g,h.value]:g===void 0?[h.value]:[g,h.value];n[m.key]=e}else n[m.key]=h.value;s.push({key:m.key,token:f})}return Re(i,n),{command:r,positionals:a,flags:n,warnings:o,providedFlags:s}}function Re(e,t){if(e)for(let n of me(e)?.impliedFlags??[])t[n]=!0}function ze(e,t){return t===`-c`&&(e===`snapshot`||e===`diff`)}function Be(e,t){return e===`react-devtools`?!t||!w(t.key,e):!1}function Ve(e){return e===`cdp`}function He(e,t){let n=v().filter(t=>t.names.includes(e));if(n.length<=1)return n[0]??_(e);if(t){let e=n.find(e=>w(e.key,t));if(e)return e}return _(e)}function Ue(e,n){let r=n?.strictFlags??!0,i=[...e.warnings],a=C({json:!1,help:!1,version:!1},n?.defaultFlags??{});if(C(a,e.flags),e.command&&!h(e.command)&&!a.help){let n=A(e.command),r=n?`Unknown command: ${e.command}. Did you mean ${n}?`:`Unknown command: ${e.command}`;throw new t(`INVALID_ARGS`,r)}let o=e.providedFlags.filter(t=>!w(t.key,e.command));if(o.length>0){let n=o.map(e=>e.token),s=Qe(e.command,n);if(r)throw new t(`INVALID_ARGS`,s);i.push(s);for(let e of o)delete a[e.key]}let s=Xe(e);if(s.length>0){let n=Ze(e.command,e.positionals[0],s);if(r)throw new t(`INVALID_ARGS`,n);i.push(n);for(let e of s)delete a[e.key]}for(let t of Object.keys(a))a[t]!==void 0&&(w(t,e.command)||delete a[t]);We(e),p(e.command,a);let c=Ye({command:e.command,positionals:e.positionals,flags:a,warnings:i});if(le(c.command,c.positionals),c.command===`batch`&&+!!a.steps+ +!!a.stepsFile!=1)throw new t(`INVALID_ARGS`,`batch requires exactly one step source: --steps or --steps-file.`);return c}function We(e){if(e.command!==`back`)return;let n=e.providedFlags.filter(e=>e.key===`backMode`);if(!(new Set(n.map(e=>e.token)).size<=1))throw new t(`INVALID_ARGS`,`back accepts only one explicit mode flag: use either --in-app or --system.`)}function N(e){let t=e.indexOf(`=`);return t===-1?[e,void 0]:[e.slice(0,t),e.slice(t+1)]}function Ge(e,n,r,i){if(e.setValue!==void 0){if(r!==void 0)throw new t(`INVALID_ARGS`,`Flag ${n} does not take a value.`);return{value:e.setValue,consumeNext:!1}}if(e.type===`boolean`){if(r!==void 0)throw new t(`INVALID_ARGS`,`Flag ${n} does not take a value.`);return{value:!0,consumeNext:!1}}if(e.type===`booleanOrString`){if(r!==void 0){if(r.trim().length===0)throw new t(`INVALID_ARGS`,`Flag ${n} requires a non-empty value when provided.`);return{value:r,consumeNext:!1}}return i===void 0||F(i)?{value:!0,consumeNext:!1}:Ke(i)?{value:i,consumeNext:!0}:{value:!0,consumeNext:!1}}let a=r??i;if(a===void 0||r===void 0&&F(a))throw new t(`INVALID_ARGS`,`Flag ${n} requires a value.`);if(e.type===`string`)return{value:a,consumeNext:r===void 0};if(e.type===`enum`){if(!e.enumValues?.includes(a))throw new t(`INVALID_ARGS`,`Invalid ${P(n)}: ${a}`);return{value:a,consumeNext:r===void 0}}let o=Number(a);if(!Number.isFinite(o)||typeof e.min==`number`&&o<e.min||typeof e.max==`number`&&o>e.max)throw new t(`INVALID_ARGS`,`Invalid ${P(n)}: ${a}`);return{value:e.type===`int`?Math.floor(o):o,consumeNext:r===void 0}}function P(e){return e.replace(/^-+/,``)}function F(e){if(!e.startsWith(`-`)||e===`-`)return!1;let[t]=e.startsWith(`--`)?N(e):[e,void 0];return _(t)!==void 0}function Ke(e){let t=e.trim();return!t||/^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(t)?!1:!!(t.startsWith(`./`)||t.startsWith(`../`)||t.startsWith(`~/`)||t.startsWith(`/`)||t.includes(`/`)||t.includes(`\\`))}function qe(e,t,n){if(!Je(n)||!e)return!1;let r=S(e);if(!r||r.allowsExtraPositionals)return!0;let i=r.positionalArgs??[];return i.length===0?!1:t.length<i.length||i.some(e=>e.includes(`?`))}function Je(e){return/^-\d+(\.\d+)?$/.test(e)}function Ye(e){if(e.flags.help)return e;if(e.command===`snapshot`&&e.flags.snapshotDiff){let{snapshotDiff:t,...n}=e.flags;return{command:`diff`,positionals:[`snapshot`,...e.positionals],flags:n,warnings:e.warnings}}return e}function Xe(e){let t=S(e.command)?.flagsByAction,n=e.positionals[0];if(t===void 0||n===void 0||!Object.hasOwn(t,n))return[];let r=t[n];if(r===void 0)return[];let i=new Set(Object.values(t).flat());return e.providedFlags.filter(e=>i.has(e.key)&&!r.includes(e.key))}function Ze(e,t,n){return`${e} ${t} does not read ${n.map(e=>e.token).join(`, `)}. Run \`${e} ${t} --help\` for the options it reads.`}function Qe(e,t){return e?t.length===1?`Flag ${t[0]} is not supported for command ${e}.`:`Flags ${t.join(`, `)} are not supported for command ${e}.`:t.length===1?`Flag ${t[0]} requires a command that supports it.`:`Flags ${t.join(`, `)} require a command that supports them.`}async function I(){let{buildUsageText:e}=await import(`./cli-help.js`).then(e=>e.n);return e()}async function $e(e){let{buildCommandUsageText:t}=await import(`./cli-help.js`).then(e=>e.n);return t(L(e))}function L(e){let n=pe(e);if(n)throw new t(`INVALID_ARGS`,n);return fe(e)}function et(){return{renderedToStderr:!1}}function tt(e){return t=>{t.type===`command`&&(e.renderedToStderr=!0,process.stderr.write(`${t.message}\n`))}}function nt(e){return ae(e)}const rt={connect:async()=>(await import(`./connection.js`)).connectCommand,disconnect:async()=>(await import(`./connection.js`)).disconnectCommand,connection:async()=>(await import(`./connection.js`)).connectionCommand,auth:async()=>(await import(`./auth.js`)).authCommand,daemon:async()=>(await import(`./daemon.js`)).daemonCommand,device:async()=>(await import(`./device2.js`)).deviceCommand,proxy:async()=>(await import(`./proxy.js`)).proxyCommand,takeover:async()=>(await import(`./takeover.js`)).takeoverCommand,replay:async()=>(await import(`./replay.js`)).replayCommand,screenshot:async()=>(await import(`./screenshot3.js`)).screenshotCommand,diff:async()=>(await import(`./screenshot3.js`)).diffCommand,record:async()=>(await import(`./recording.js`)).recordingCommand};async function R(e){let t={...e.flags},n=rt[e.command];return n&&await(await n())({...e,flags:t})?!0:nt(e.command)?await it({...e,command:e.command,flags:t}):!1}async function it(e){let{runGenericClientBackedCommand:t}=await import(`./generic.js`);return await t(e)}function at(e){return[`exec`,`--yes`,`--package`,`agent-react-devtools@0.5.0`,`--`,`agent-react-devtools`,...e]}function ot(e){return e===`ios-instance`}function st(e){return e[0]===`wait`&&e.includes(`--connected`)}function ct(e,t,n){n===0||!st(e)||!ot(t?.leaseBackend)||process.stderr.write([`Hint: Remote iOS React DevTools connects during JavaScript startup.`,"If the app was already open before `agent-device react-devtools start`, relaunch it with `agent-device open <bundle-id> --platform ios --relaunch`, then retry `agent-device react-devtools wait --connected`.",``].join(`
|
|
2
|
+
`))}function z(e,t,n){return n||(e.push(t),``)}function lt(e){if(!e?.metroProxyBaseUrl||!he(e.leaseBackend))return null;let n=[],r={serverBaseUrl:z(n,`metroProxyBaseUrl`,e.metroProxyBaseUrl),bearerToken:z(n,`metroBearerToken`,e.metroBearerToken),tenantId:z(n,`tenant`,e.tenant),runId:z(n,`runId`,e.runId),leaseId:z(n,`leaseId`,e.leaseId)};if(n.length>0)throw new t(`INVALID_ARGS`,`react-devtools remote bridge requires ${n.join(`, `)}.`,{missing:n});return r}async function ut(e,t,n){let{flags:r}=t,i=lt(r);if(!i)return n();let a=t.stateDir??process.cwd(),o=t.session??r?.session??`default`,s=r?.remoteConfig??`${i.tenantId}:${i.runId}:${i.leaseId}`;if(e[0]===`stop`)try{return await n()}finally{await _e({projectRoot:t.cwd??process.cwd(),stateDir:a,profileKey:s,consumerKey:o})}return await be({projectRoot:t.cwd??process.cwd(),stateDir:a,serverBaseUrl:i.serverBaseUrl,bearerToken:i.bearerToken,bridgeScope:{tenantId:i.tenantId,runId:i.runId,leaseId:i.leaseId},session:o,profileKey:s,consumerKey:o,env:t.env??process.env}),await n()}function dt(e,t){if(e[0]!==`start`)return!1;let{flags:n}=t;return n?ve(n.leaseProvider).supportsDirectPortReverse&&n.leaseBackend===`android-instance`&&n.metroProxyBaseUrl===void 0&&t.configureDirectPortReverse!==void 0:!1}async function ft(e,t={}){let n=t.cwd??process.cwd(),r=t.env??process.env,i=await ut(e,t,async()=>(dt(e,t)&&await t.configureDirectPortReverse?.(),(await ie(`npm`,at(e),{cwd:n,env:r,allowFailure:!0,onStdoutChunk:e=>{process.stdout.write(e)},onStderrChunk:e=>{process.stderr.write(e)}})).exitCode));return ct(e,t.flags,i),i}const B=`${s} Run agent-device help batch for the commands batch accepts and for runnable step examples.`,pt=`${f} Run agent-device help batch for the commands batch accepts and for runnable step examples.`;function mt(e){let n;try{n=JSON.parse(e)}catch{throw new t(`INVALID_ARGS`,`Batch steps must be valid JSON.`)}if(!Array.isArray(n)||n.length===0)throw new t(`INVALID_ARGS`,`Batch steps must be a non-empty JSON array.`);return n.map((e,t)=>ht(e,t+1))}function ht(e,n){let r=o(e,n,B),i=[`positionals`,`flags`].filter(e=>e in r);if(i.length>0){let e=i.map(e=>`"${e}"`).join(`, `);throw new t(`INVALID_ARGS`,`Batch step ${n} uses removed field(s): ${e}. Use {"command":"...","input":{...}}. Example: {"command":"open","input":{"app":"settings","platform":"ios"}}.`,{hint:B})}ee(r,[`command`,`input`,`runtime`],`Batch step ${n}`,B);let s=c(r.runtime,n);return{command:d(r.command,n,pt),input:a(r,n,B),...s===void 0?{}:{runtime:s}}}function V(e,t={}){let n=H(t),r={...e};return n.defaultPlatform&&r.platform===void 0&&(r.platform=n.defaultPlatform),r}function H(e){let t=e.env??process.env,n=e.inheritedPlatform??e.configuredPlatform??_t(t.AGENT_DEVICE_PLATFORM),r=yt(e.configuredSession??t.AGENT_DEVICE_SESSION);return{defaultPlatform:n,lockPolicy:gt(e.policyOverrides,t,r)}}function gt(e,t,n){let r=e?.sessionLock??vt(t.AGENT_DEVICE_SESSION_LOCK);if(r)return r;if(n)return`reject`}function _t(e){if(e===void 0)return;let n=e.trim().toLowerCase();if(n){if(n===`ios`||n===`android`||n===`apple`)return n;throw new t(`INVALID_ARGS`,`Invalid AGENT_DEVICE_PLATFORM: ${e}. Use ios, android, or apple.`)}}function vt(e){if(e===void 0)return;let n=e.trim().toLowerCase();if(n){if(n===`reject`||n===`strip`)return n;throw new t(`INVALID_ARGS`,`Invalid session lock mode: ${e}. Use reject or strip.`)}}function yt(e){return typeof e==`string`&&e.trim().length>0}function bt(e,t){let n=M(e),r=t?.env??process.env,i=t?.cwd??process.cwd(),a=xt(n.command)?ye({remoteConfig:n.flags.remoteConfig,cwd:i,env:r}):{},o=C(ue({command:n.command,cwd:i,cliFlags:n.flags,env:r}),a);return{...Ue(n,{strictFlags:t?.strictFlags,defaultFlags:o}),providedFlags:n.providedFlags}}function xt(e){return e!==null}g.runtime;async function St(e){let{command:t,request:n,transport:r,transportOptions:i}=e;return await r({...n,command:t},i)}const U=(e,t={})=>import(`./error.js`).then(e=>e.t).then(({printHumanError:n})=>n(e,t)),W=e=>import(`./json.js`).then(({printJson:t})=>t(e)),Ct={sendToDaemon:u},wt=new Set([`launchUrl`,`kind`,`metroBearerToken`,`metroKind`,`metroListenHost`,`metroNoInstallDeps`,`metroNoReuseExisting`,`metroPreparePort`,`metroProbeTimeoutMs`,`metroProjectRoot`,`metroProxyBaseUrl`,`metroPublicBaseUrl`,`metroRuntimeFile`,`metroStartupTimeoutMs`,`metroStatusHost`]),Tt=new Set([`connect`,`connection`,`close`,`daemon`,`device`,`disconnect`,`metro`,`proxy`,`session`,`takeover`]);async function G(e,t=Ct){let n=ne(),r=oe(),i=Ft(e),a=e.includes(`--json`),o=qt(e)??process.env.AGENT_DEVICE_SESSION??`default`;await te({session:o,requestId:n,command:e[0],debug:i},async()=>{let{parsed:o,command:s,positionals:c}=await Et(e,{version:r,jsonRequested:a,debugEnabled:i}),u=Z(s,o.providedFlags),d=await Dt(o,{command:s,positionals:c,requestId:n,debugOutputEnabled:u});K(d.effectiveFlags);let f=null;try{if(s===`react-devtools`){await T(await Ot(d,t));return}if(s===`web`){let{runWebCommand:e}=await import(`./web.js`);await T(await e(c,{flags:d.effectiveFlags,stateDir:d.daemonPaths.baseDir}));return}if(de({command:s,currentVersion:r,stateDir:d.daemonPaths.baseDir,flags:d.effectiveFlags}),await kt(d,t),K(d.effectiveFlags),s===`cdp`){await T(await xe(c,{flags:d.effectiveFlags,runtime:d.resolvedRuntime,cwd:process.cwd(),env:process.env}));return}f=At(d);let e=await jt(d),n=et();await Mt(d,l(q(d),{transport:Kt({command:s,flags:d.effectiveFlags,replayTestReporterRuntime:e,commandProgress:n,transport:t.sendToDaemon})}),e,n)}catch(e){await Nt(e,d,f)}finally{f&&f()}})}function K(e){e.daemonAuthToken&&re(e.daemonAuthToken)}async function Et(e,n){let i;try{i=bt(e,{cwd:process.cwd(),env:process.env})}catch(e){x({level:`error`,phase:`cli_parse_failed`,data:{error:e instanceof Error?e.message:String(e)}});let t=r(e,{diagnosticId:y().diagnosticId,logPath:b({force:!0})?.path});return n.jsonRequested?await W({success:!1,error:t}):await U(t,{showDetails:n.debugEnabled}),T(1)}for(let e of i.warnings)process.stderr.write(`Warning: ${e}\n`);if(i.flags.version)return process.stdout.write(`${n.version}\n`),T(0);let a=i.command===`help`,o=i.flags.help;if(a||o){if(a&&i.positionals.length>1)return await U(new t(`INVALID_ARGS`,`help accepts at most one command.`)),T(1);let e=a?i.positionals[0]:i.command;if(!e)return process.stdout.write(`${await I()}\n`),T(0);let n=await $e(e);return n?(process.stdout.write(n),T(0)):(await U(new t(`INVALID_ARGS`,It(e))),process.stdout.write(`${await I()}\n`),T(1))}return i.command?{parsed:i,command:i.command,positionals:i.positionals}:(process.stdout.write(`${await I()}\n`),T(1))}async function Dt(e,t){let i=new Set(e.providedFlags.map(e=>e.key));try{let n=H({policyOverrides:e.flags,configuredPlatform:e.flags.platform,configuredSession:e.flags.session}),r=n.lockPolicy?{...e.flags}:V(e.flags,{policyOverrides:e.flags,configuredPlatform:e.flags.platform,configuredSession:e.flags.session}),a=se(r.stateDir),o=r.session??`default`,s=zt({command:t.command,explicitFlagKeys:i,stateDir:a.baseDir,session:o,remoteConfig:r.remoteConfig,hasResolvedSession:r.session!==void 0}),c=s?Wt(r,s.flags,i):r;return{...t,binding:n,flags:r,daemonPaths:a,sessionName:o,connectionDefaults:s,explicitFlagKeys:i,effectiveFlags:c,resolvedRuntime:s?.runtime,connectionMetadata:s?.connection,parsedBatchSteps:void 0}}catch(i){let a=n(i),o=r(a,{diagnosticId:y().diagnosticId,logPath:b({force:!0})?.path});return e.flags.json?await W({success:!1,error:o}):await U(o,{showDetails:t.debugOutputEnabled}),T(1)}}async function Ot(t,n){let{daemonAuthToken:r,...i}=t.effectiveFlags;return await ft(t.positionals,{flags:{...i,leaseProvider:t.connectionDefaults?.connection?.leaseProvider},stateDir:t.daemonPaths.baseDir,session:t.effectiveFlags.session??t.sessionName,cwd:process.cwd(),env:process.env,configureDirectPortReverse:async()=>{let a=await St({route:`react-devtools`,command:g.runtime,request:{positionals:[`port-reverse`],flags:{...i,leaseProvider:t.connectionDefaults?.connection?.leaseProvider,devicePort:8097,hostPort:8097,portReverseName:`react-devtools`},session:t.effectiveFlags.session??t.sessionName},transport:n.sendToDaemon,transportOptions:{authToken:r}});a.ok||e(a.error)}})}async function kt(e,n){if(e.command===`batch`){if(e.positionals.length>0)throw new t(`INVALID_ARGS`,`batch does not accept positional arguments.`);e.parsedBatchSteps=Lt(e.flags)}if(Vt(e.command)&&(e.effectiveFlags=(await Ce({command:e.command,flags:e.effectiveFlags,stateDir:e.daemonPaths.baseDir,env:process.env})).flags),e.effectiveFlags.remoteConfig&&Bt(e.command)){let t=l(q(e),{transport:Q(n.sendToDaemon)}),r=await Se({command:e.command,flags:e.effectiveFlags,client:t,runtime:e.resolvedRuntime,positionals:e.positionals,batchSteps:e.parsedBatchSteps,forceRuntimePrepare:Gt(e.explicitFlagKeys)});e.effectiveFlags=r.flags,e.resolvedRuntime=r.runtime,e.connectionMetadata=r.connection}Ht({command:e.command,flags:e.effectiveFlags,runtime:e.resolvedRuntime,explicitFlagKeys:e.explicitFlagKeys,hadConnectionDefaults:!!e.connectionDefaults})&&process.stderr.write(`Warning: open is using explicit remote daemon or tenant flags without saved Metro runtime hints. React Native apps may launch without bundle/runtime hints; prefer connect --remote-config <path> first or pass --remote-config <path> on this command.
|
|
3
|
+
`)}function q(e){let t=e.effectiveFlags,n=e.connectionMetadata;return{session:t.session,requestId:e.requestId,stateDir:t.stateDir,daemonBaseUrl:t.daemonBaseUrl,daemonAuthToken:t.daemonAuthToken,daemonTransport:t.daemonTransport,daemonServerMode:t.daemonServerMode,tenant:t.tenant,sessionIsolation:t.sessionIsolation,runId:t.runId,leaseId:t.leaseId,leaseBackend:t.leaseBackend,leaseProvider:n?.leaseProvider,clientId:n?.clientId,deviceKey:n?.deviceKey,providerApp:t.providerApp,providerOsVersion:t.providerOsVersion,providerProject:t.providerProject,providerBuild:t.providerBuild,providerSessionName:t.providerSessionName,providerDeviceOrientation:t.providerDeviceOrientation,providerGeoLocation:t.providerGeoLocation,providerTimezone:t.providerTimezone,providerAppiumVersion:t.providerAppiumVersion,providerLanguage:t.providerLanguage,providerLocale:t.providerLocale,providerNetworkProfile:t.providerNetworkProfile,providerCustomNetwork:t.providerCustomNetwork,providerNoResignApp:t.providerNoResignApp,awsProjectArn:t.awsProjectArn,awsDeviceArn:t.awsDeviceArn,awsAppArn:t.awsAppArn,awsRegion:t.awsRegion,awsInteractionMode:t.awsInteractionMode,runtime:e.resolvedRuntime,lockPolicy:e.binding.lockPolicy,lockPlatform:e.binding.defaultPlatform,cwd:process.cwd(),debug:e.debugOutputEnabled,cost:t.cost,responseLevel:t.responseLevel}}function At(e){let t=e.effectiveFlags.daemonBaseUrl;return e.debugOutputEnabled&&!e.effectiveFlags.json&&!t?Jt(e.daemonPaths.logPath):null}async function jt(e){if(e.command!==`test`)return;let{createReplayTestReporterRuntime:t}=await import(`./reporting.js`);return t({debug:e.debugOutputEnabled,verbose:e.effectiveFlags.verbose,json:e.effectiveFlags.json,reporter:e.effectiveFlags.reporter,reportJunit:e.effectiveFlags.reportJunit})}async function Mt(e,n,r,i){let{command:a,positionals:o,effectiveFlags:s}=e;if(a===`batch`){if(!e.parsedBatchSteps)throw new t(`INVALID_ARGS`,`batch requires --steps or --steps-file.`);let c=e.parsedBatchSteps.map((t,n)=>({...t,input:e.binding.lockPolicy&&e.flags.platform===void 0?{...t.input}:V(t.input,{policyOverrides:s,configuredPlatform:s.platform,configuredSession:s.session,inheritedPlatform:s.platform})}));if(await R({command:a,positionals:o,flags:{...s,batchSteps:c},client:n,debug:e.debugOutputEnabled,replayTestReporterRuntime:r,commandProgress:i}))return}else if(a===`runtime`)throw new t(`INVALID_ARGS`,`runtime command was removed. Use connect --remote-config <path> for remote runs, or metro prepare --remote-config <path> for inspection.`);else if(await R({command:a,positionals:o,flags:s,client:n,debug:e.debugOutputEnabled,replayTestReporterRuntime:r,commandProgress:i}))return;throw new t(`INVALID_ARGS`,X(a))}async function Nt(e,t,i){let a=n(e),o=r(a,{diagnosticId:y().diagnosticId,logPath:b({force:!0})?.path});if(t.command===`close`&&Rt(a)){t.effectiveFlags.json&&await W({success:!0,data:{closed:`session`,source:`no-daemon`}});return}t.effectiveFlags.json?await W({success:!1,error:o}):(await U(o,{showDetails:t.debugOutputEnabled}),t.debugOutputEnabled&&Pt(t,o)),i&&i(),await T(1)}const J=64e3;function Pt(e,t){if(!e.effectiveFlags.daemonBaseUrl){Y(`daemon log`,e.daemonPaths.logPath);return}let n=t.diagnosticsRecord;n&&Y(`remote diagnostics`,ce(e.daemonPaths.baseDir,n))}function Y(e,t){try{if(E.existsSync(t)){let n=E.readFileSync(t,`utf8`).split(`
|
|
4
4
|
`),r=n.slice(Math.max(0,n.length-200)).join(`
|
|
5
|
-
`);r.length>J&&(r=r.slice(r.length-J)),r.trim().length>0&&process.stderr.write(`\n[${e}]\n${r}\n`)}}catch{}}function Ft(e){try{let t=M(e);return Z(t.command??``,t.providedFlags)}catch{return e.includes(`--debug`)||e.includes(`-v`)||e.includes(`--verbose`)}}function It(e){let t=A(e);return t?`Unknown command: ${e}. Did you mean ${t}?`:`Unknown command: ${e}`}function X(e){return h(e)?(x({level:`error`,phase:`cli_known_command_unhandled`,data:{command:e}}),`Command is registered but no CLI handler accepted it: ${e}`):`Unknown command: ${e}`}function Z(e,t){return t.some(t=>t.key===`verbose`&&(t.token===`--debug`||t.token===`-v`||e!==`test`))}function Lt(
|
|
5
|
+
`);r.length>J&&(r=r.slice(r.length-J)),r.trim().length>0&&process.stderr.write(`\n[${e}]\n${r}\n`)}}catch{}}function Ft(e){try{let t=M(e);return Z(t.command??``,t.providedFlags)}catch{return e.includes(`--debug`)||e.includes(`-v`)||e.includes(`--verbose`)}}function It(e){let t=A(e);return t?`Unknown command: ${e}. Did you mean ${t}?`:`Unknown command: ${e}`}function X(e){return h(e)?(x({level:`error`,phase:`cli_known_command_unhandled`,data:{command:e}}),`Command is registered but no CLI handler accepted it: ${e}`):`Unknown command: ${e}`}function Z(e,t){return t.some(t=>t.key===`verbose`&&(t.token===`--debug`||t.token===`-v`||e!==`test`))}function Lt(e){let n=``;if(e.steps)n=e.steps;else if(e.stepsFile)try{n=E.readFileSync(e.stepsFile,`utf8`)}catch(n){let r=n instanceof Error?n.message:String(n);throw new t(`INVALID_ARGS`,`Failed to read --steps-file ${e.stepsFile}: ${r}`)}return mt(n)}function Rt(e){return e.code===`COMMAND_FAILED`?e.details?.kind===`daemon_startup_failed`?!0:e.message.toLowerCase().includes(`failed to start daemon`)?typeof e.details?.infoPath==`string`||typeof e.details?.lockPath==`string`:!1:!1}function zt(e){return e.command===`connect`||e.command===`connection`||e.command===`daemon`||e.command===`proxy`?null:ge({stateDir:e.stateDir,session:e.session,remoteConfig:e.remoteConfig,cwd:process.cwd(),env:process.env,allowActiveFallback:!e.explicitFlagKeys.has(`session`)&&(!e.remoteConfig||e.command===`disconnect`||!e.hasResolvedSession),validateRemoteConfigHash:e.command!==`disconnect`})}function Bt(e){return!Tt.has(e)}function Vt(e){return e!==`auth`&&e!==`connection`&&e!==`daemon`&&e!==`device`&&e!==`proxy`}function Ht(e){return e.command!==`open`||e.runtime||e.flags.bundleUrl||e.flags.metroHost||e.flags.metroPort||e.flags.remoteConfig||e.hadConnectionDefaults?!1:Ut(e.explicitFlagKeys)}function Ut(e){return e.has(`daemonBaseUrl`)||e.has(`daemonTransport`)||e.has(`tenant`)||e.has(`sessionIsolation`)||e.has(`runId`)||e.has(`leaseId`)||e.has(`leaseBackend`)}function Wt(e,t,n){let r={...e};for(let[e,i]of Object.entries(t))i!==void 0&&(n.has(e)||(r[e]=i));return r}function Gt(e){for(let t of wt)if(e.has(t))return!0;return!1}function Kt(e){let{command:t,flags:n,replayTestReporterRuntime:r,transport:i}=e;if(n.json)return Q(i);let a=t===`test`&&r?r.onProgress:tt(e.commandProgress);return async(e,n)=>{let r={...n,onProgress:a};return await $(i,{...e,meta:{...e.meta,requestProgress:t===`test`?`replay-test`:`command`}},r)}}function Q(e){return async(t,n)=>await $(e,t,n)}async function $(e,t,n){return await e(t,n)}function qt(e){for(let t=0;t<e.length;t+=1){let n=e[t];if(n.startsWith(`--session=`)){let e=n.slice(10).trim();return e.length>0?e:null}if(n===`--session`){let n=e[t+1]?.trim();return n&&!n.startsWith(`-`)?n:null}}return null}we(process.argv[1]??``).href===import.meta.url&&G(process.argv.slice(2)).catch(async e=>{let t=n(e);await U(r(t),{showDetails:!0}),await T(1)});function Jt(e){try{let t=E.existsSync(e)?E.statSync(e).size:0,n=!1,r=setInterval(()=>{if(!n&&E.existsSync(e))try{let n=E.statSync(e);if(n.size<t&&(t=0),n.size<=t)return;let r=E.openSync(e,`r`);try{let e=Buffer.alloc(n.size-t);E.readSync(r,e,0,e.length,t),t=n.size,e.length>0&&process.stdout.write(e.toString(`utf8`))}finally{E.closeSync(r)}}catch{}},200);return()=>{n=!0,clearInterval(r)}}catch{return null}}export{G as runCli};
|
|
@@ -458,7 +458,14 @@ type SettleCommandOptions = {
|
|
|
458
458
|
settleQuietMs?: number;
|
|
459
459
|
timeoutMs?: number;
|
|
460
460
|
};
|
|
461
|
-
|
|
461
|
+
/**
|
|
462
|
+
* How long a tap-shaped interaction may poll for a target that does not exist yet, capped at the
|
|
463
|
+
* promotedTarget row's maxTimeoutMs. Never model- or CLI-writable; omitted means one attempt.
|
|
464
|
+
*/
|
|
465
|
+
type ReadinessBudgetOptions = {
|
|
466
|
+
readinessTimeoutMs?: number;
|
|
467
|
+
};
|
|
468
|
+
type ClickOptions = DeviceCommandBaseOptions & SelectorSnapshotCommandOptions & InteractionTarget & RepeatedPressOptions & SettleCommandOptions & ReadinessBudgetOptions & {
|
|
462
469
|
button?: ClickButton;
|
|
463
470
|
/**
|
|
464
471
|
* Opt-in (#1047): return cheap post-action evidence (AX digest, node counts,
|
|
@@ -467,10 +474,10 @@ type ClickOptions = DeviceCommandBaseOptions & SelectorSnapshotCommandOptions &
|
|
|
467
474
|
*/
|
|
468
475
|
verify?: boolean;
|
|
469
476
|
};
|
|
470
|
-
type PressOptions = DeviceCommandBaseOptions & SelectorSnapshotCommandOptions & InteractionTarget & RepeatedPressOptions & SettleCommandOptions & {
|
|
477
|
+
type PressOptions = DeviceCommandBaseOptions & SelectorSnapshotCommandOptions & InteractionTarget & RepeatedPressOptions & SettleCommandOptions & ReadinessBudgetOptions & {
|
|
471
478
|
verify?: boolean;
|
|
472
479
|
};
|
|
473
|
-
type LongPressOptions = DeviceCommandBaseOptions & SelectorSnapshotCommandOptions & InteractionTarget & SettleCommandOptions & {
|
|
480
|
+
type LongPressOptions = DeviceCommandBaseOptions & SelectorSnapshotCommandOptions & InteractionTarget & SettleCommandOptions & ReadinessBudgetOptions & {
|
|
474
481
|
durationMs?: number;
|
|
475
482
|
};
|
|
476
483
|
type HoverOptions = DeviceCommandBaseOptions & SelectorSnapshotCommandOptions & InteractionTarget & SettleCommandOptions;
|
|
@@ -1767,4 +1774,4 @@ type AgentDeviceClient = {
|
|
|
1767
1774
|
};
|
|
1768
1775
|
};
|
|
1769
1776
|
//#endregion
|
|
1770
|
-
export { NetworkOptions as $,
|
|
1777
|
+
export { NetworkOptions as $, AppTriggerEventOptions as $t, WaitCommandOptions as A, ElementTarget as At, GetOptions as B, FindSnapshotCommandOptions as Bt, HomeCommandOptions as C, isRecord as Cn, RotateGestureOptions as Ct, ReactNativeCommandOptions as D, SwipeOptions as Dt, PrepareCommandOptions as E, SwipeGestureOptions as Et, SessionCloseResult as F, CaptureDiffOptions as Ft, CommandRequestResult as G, AppDeployResult as Gt, IsStatePredicateOptions as H, AppCloseOptions as Ht, SessionSaveScriptOptions as I, CaptureScreenshotOptions as It, ReplayRunOptions as J, AppInstallOptions as Jt, BatchRunOptions as K, AppInstallFromSourceOptions as Kt, SessionSaveScriptResult as L, CaptureScreenshotResult as Lt, AlertAction as M, PointTarget as Mt, PermissionTarget as N, RefTarget as Nt, TvRemoteCommandOptions as O, TransformGestureOptions as Ot, SettingsUpdateOptions as P, SelectorTarget as Pt, LogsOptions as Q, AppPushOptions as Qt, FindBaseOptions as R, CaptureSnapshotOptions as Rt, FoldCommandOptions as S, JsonValue as Sn, RepeatedPressOptions as St, OrientationCommandOptions as T, SettleCommandOptions as Tt, IsTextPredicateOptions as U, AppCloseResult as Ut, IsOptions as V, SelectorSnapshotCommandOptions as Vt, RecordControlOptions as W, AppDeployOptions as Wt, AudioOptions as X, AppOpenOptions as Xt, ReplayTestOptions as Y, AppListOptions as Yt, EventsOptions as Z, AppOpenResult as Zt, AppStateCommandOptions as _, AgentDeviceSelectionOptions as _n, LongPressOptions as _t, WaitCommandResult as a, AgentDeviceCapabilitiesResult as an, HumanControlHoldOptions as at, ClipboardCommandOptions as b, JsonObject as bn, PressOptions as bt, DebugSymbolsOptions as c, AgentDeviceSessionDevice as cn, LeaseAllocateOptions as ct, PrepareCommandResult as d, StartupPerfSample as dn, ClickOptions as dt, DeviceSelectionMetadata as en, PerfOptions as et, ReplayCommandResult as f, AgentDeviceClientConfig as fn, DragOptions as ft, AlertCommandOptions as g, AgentDeviceRequestOverrides as gn, HoverOptions as gt, ActionButtonCommandOptions as h, AgentDeviceIdentifiers as hn, FocusOptions as ht, TraceCommandResult as i, MaterializationReleaseResult as in, HumanControlHold as it, WaitCommandTarget as j, InteractionTarget as jt, ViewportCommandOptions as k, TypeTextOptions as kt, DebugSymbolsResult as l, DeviceBootOptions as ln, LeaseOptions as lt, TriggerAppEventCommandResult as m, AgentDeviceDaemonTransportContext as mn, FlingOptions as mt, AgentDeviceCommandClient as n, DeviceSelectionSource as nn, TraceOptions as nt, DiffSnapshotCommandResult as o, AgentDeviceDevice as on, HumanControlHoldScope as ot, ReplaySuiteResult as p, AgentDeviceDaemonTransport as pn, FillOptions as pt, BatchStep as q, AppInstallFromSourceResult as qt, RecordingCommandResult as r, MaterializationReleaseOptions as rn, CloudArtifactsOptions as rt, DoctorCommandResult as s, AgentDeviceSession as sn, Lease as st, AgentDeviceClient as t, DeviceSelectionReason as tn, RecordOptions as tt, PushCommandResult as u, DeviceShutdownOptions as un, LeaseScopedOptions as ut, AppSwitcherCommandOptions as v, DeviceCommandBaseOptions as vn, PanOptions as vt, KeyboardCommandOptions as w, ScrollOptions as wt, DoctorCommandOptions as x, JsonPrimitive as xn, ReadinessBudgetOptions as xt, BackCommandOptions as y, TargetShutdownResult as yn, PinchOptions as yt, FindOptions as z, CaptureSnapshotResult as zt };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{v as e}from"./sdk-batch.js";import{o as t}from"./registry.js";const n=t(),r=new Map(n.map(e=>[e.name,e]));function i(){return[...n]}function a(){return e().map(e=>{let t=s(e);if(!t)throw Error(`Missing command metadata for MCP-exposed command: ${e}`);return t})}function o(e){return r.has(e)}function s(e){return r.get(e)}export{a as i,o as n,i as r,s as t};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{
|
|
2
|
-
`)}function De(e,t,n){let r=j({command:e,cwd:process.cwd(),cliFlags:t}),i={};for(let[t,a]of Object.entries(r))Object.hasOwn(n,t)&&A(t,e)&&(i[t]=a);return k(i,t)}const Oe={devices:async e=>({devices:e.map(M)}),apps:async e=>({apps:e})};async function ke(e,t){let n=Oe[e];return n?await n(t):t}function Ae(){let e=new Map;return{pinInput:(t,n,r)=>Ue(t,n,Pe(e,r,n.session)),mergeCommandResult:(t,n,r,i)=>Fe(e,t,n,r,i),mergeErrorDetails:(t,n,r)=>{let i=H(n,r);je(e,i,t),Ve(e,i,t)}}}function je(t,
|
|
1
|
+
import{N as e,X as t,Y as n,q as r,r as i}from"./sdk-contracts.js";import{_ as a,h as o}from"./sdk-batch-runner.js";import{a as s,n as c,t as l}from"./sdk-device.js";import{C as u,T as d,c as f,f as p,m}from"./sdk-batch.js";import{A as h,D as g,E as _,F as ee,L as v,M as y,O as b,P as te,R as ne,b as re,c as ie,d as ae,g as oe,h as se,j as x,k as S,l as ce,m as le,p as ue,s as de,u as fe,v as pe}from"./registry.js";import{n as me}from"./success-text.js";import{t as he}from"./output-common.js";import{i as ge,n as C,r as _e,t as w}from"./command-metadata.js";import{r as ve}from"./replay-divergence.js";import{n as ye,t as T}from"./cli-output.js";import{r as E,t as D}from"./recording-stop-observation.js";import{n as O}from"./error.js";import{n as k,r as A,t as j}from"./cli-config.js";import{n as M}from"./result-serialization.js";const N=x({field:y(),artifactType:y(),path:y(),localPath:y(),fileName:y()},[`field`]),P={record:{type:`object`,oneOf:[x({recording:g(`started`),outPath:y(),sessionStateDir:y(),recordingBackend:y(),recordingScope:y(),recordOnlySession:_(),activeSessionApp:S(),showTouches:_()},[`recording`,`outPath`,`sessionStateDir`,`showTouches`]),x({recording:g(`stopped`),outPath:y(),telemetryPath:y(),artifacts:{type:`array`,items:N},recordingBackend:y(),recordingScope:y(),recordOnlySession:_(),activeSessionApp:S(),durationMs:h(),capturedDurationMs:h(),recorder:b(D,`What the recorder was observed doing when the recording was stopped: confirmed, or lost when the session holding it died. ADR 0024 reserves unconfirmed for the step that gains the probe.`),nativePathDisposition:b(E,`What became of the artifact path the recorder writes to: retirable while it still owes a removal, retired once that removal was verified. ADR 0024 reserves pending.`),showTouches:_(),warning:y(),overlayWarning:y(),chunks:{type:`array`,items:S()}},[`recording`,`outPath`,`artifacts`,`durationMs`,`showTouches`])]},trace:{type:`object`,oneOf:[x({trace:g(`started`),outPath:y()},[`trace`,`outPath`]),x({trace:g(`stopped`),outPath:y(),artifacts:{type:`array`,items:N}},[`trace`,`outPath`,`artifacts`])]}},be=x({settled:_(`Whether the UI held the quiet window before the deadline. false is advisory, not failure.`),waitedMs:h(),captures:h(),quietMs:h(),timeoutMs:h(),refsGeneration:h(`Snapshot generation of the stored settled tree; refs on added diff lines were minted from it.`),refs:{type:`array`,items:x({ref:y(`Plain ref body (e12) minted from the stored settled tree.`)},[`ref`])},surfaceChange:oe,diff:x({summary:x({additions:h(),removals:h(),unchanged:h()},[`additions`,`removals`,`unchanged`]),lines:{type:`array`,items:x({kind:b([`added`,`removed`]),text:y(),ref:y(`Plain ref body (e12) for added lines.`)},[`kind`,`text`])},truncated:_(`Lines were capped to the response bound.`)},[`summary`,`lines`],`Settled diff vs the pre-action tree (changed lines only).`),tail:{type:`array`,description:`Unchanged interactive refs tail: still-present, actionable elements from the settled tree, attached only when diff carries zero added-line refs (a modal-dismiss/toast-only diff).`,items:x({ref:y(`Plain ref body (e12) minted from the stored settled tree.`),role:y(),label:y()},[`ref`,`role`])},tailTruncated:_(`Present (true) when tail candidates exceeded the response cap.`),hint:y()},[`settled`,`waitedMs`,`captures`,`quietMs`,`timeoutMs`]);function F(e){return e.oneOf?{...e,oneOf:e.oneOf.map(F)}:{...e,properties:{...e.properties??{},settle:be}}}function xe(e){let t={...e};for(let e of Object.keys(t))m(e)&&(t[e]=F(t[e]));return t}const Se=xe({scroll:x({direction:b([`up`,`down`,`left`,`right`]),edge:b([`top`,`bottom`]),until:y(`Until scrolls only: the selector the passes stopped on.`),passes:h(`Edge and until scrolls only: how many scroll-and-check passes ran.`),amount:h(),pixels:h(),durationMs:h(),message:y(),keyboardAvoided:_(`Present only when an on-screen keyboard forced the swipe into the band above it; the reported pixels were planned against the shorter referenceHeight.`),keyboardMinY:h(`Where the keyboard began, in the same unit as the gesture coordinates. Clipped scrolls only.`),movement:b([`moved`,`at-edge`,`unchanged`,`unobserved`],"Directional scrolls only: what the owner observed after its gesture. `moved` means the content inside the scroller the swipe ran in differs from the tree the session stored immediately before the gesture; `at-edge` and `unchanged` mean it did not change, with no hidden content left to reveal and with no end-of-content signal to read, respectively; `unobserved` means the pair could not back a claim in either direction — nothing comparable was available (no stored tree, a capture from another lineage, a surface that never came to rest), or every difference sits outside the scroller that was swiped, which a changing status bar does on Android — so the reported distance rests on the gesture plan alone. The field is absent — which is never a claim that nothing moved — on the tiers that verify per pass (`scroll top`/`bottom`, `--until`), on a runtime bound without a capture, on a platform whose scroll dispatches no swipe (the Linux wheel), and where the caller already owns that observation (`--settle`, or a replay with `postGestureStabilization: false`).")},[`direction`]),...re,...pe,...ae,...ue,...le,...fe,...ce,...se,...P,...ie,...de}),Ce={devices:{type:`object`,properties:{devices:{type:`array`,items:{type:`object`,properties:{platform:{type:`string`,enum:s},target:{type:`string`,enum:c},kind:{type:`string`,enum:l},id:{type:`string`},name:{type:`string`}},required:[`platform`,`target`,`kind`,`id`,`name`]}}},required:[`devices`]},apps:{type:`object`,properties:{apps:{type:`array`,items:{type:`string`}}},required:[`apps`]}},I={...Se,...Ce},we={stateDir:{schema:{type:`string`,description:`Agent-device state directory.`},audience:v({operatorConfig:!0})},mcpOutputFormat:{schema:{type:`string`,enum:[`optimized`,`json`],description:`MCP text content format. Defaults to optimized agent-friendly text; use json for JSON text. Structured content is always returned separately.`}},includeCost:{schema:{type:`boolean`,description:`Include per-command agent-cost (cost.wallClockMs, …) in structuredContent. Defaults to off; the default response shape is unchanged.`}},responseLevel:{schema:{type:`string`,enum:[`digest`,`default`,`full`],description:`Response verbosity: token-cheap digest / default (today) / full. Defaults to default; the default response shape is unchanged.`}}},L=Object.entries(we),R=new Set(L.map(([e])=>e)),Te=Object.fromEntries(L.flatMap(([e,t])=>t.audience?[[e,t.audience]]:[]));function Ee(){return Object.fromEntries(L.map(([e,t])=>[e,t.schema]))}function z(e){return r(e)}function B(e){let n=[`Error (${e.code}): ${e.message}`];if(e.cause){let t=e.cause.code?`${e.cause.code} `:``;n.push(`Cause: ${t}${e.cause.message}`)}e.hint&&n.push(`Hint: ${e.hint}`);for(let t of me(e.details))n.push(`Warning: ${he(t)}`);n.push(...O(t(e.details))),e.supportedOn&&n.push(`Supported on: ${e.supportedOn}`);let r=ve(e.details);return r&&n.push(r),n.join(`
|
|
2
|
+
`)}function De(e,t,n){let r=j({command:e,cwd:process.cwd(),cliFlags:t}),i={};for(let[t,a]of Object.entries(r))Object.hasOwn(n,t)&&A(t,e)&&(i[t]=a);return k(i,t)}const Oe={devices:async e=>({devices:e.map(M)}),apps:async e=>({apps:e})};async function ke(e,t){let n=Oe[e];return n?await n(t):t}function Ae(){let e=new Map;return{pinInput:(t,n,r)=>Ue(t,n,Pe(e,r,n.session)),mergeCommandResult:(t,n,r,i)=>Fe(e,t,n,r,i),mergeErrorDetails:(t,n,r)=>{let i=H(n,r);je(e,i,t),Ve(e,i,t)}}}function je(e,t,r){let i=r?.refsGeneration;typeof i==`number`&&U(e,t,n(r),i)}const V=new Set([`snapshot`,`find`]),Me=new Set(p.map(e=>e.name).filter(C).filter(e=>m(e))),Ne=new Set([`press`,`click`,`fill`,`longpress`,`hover`,`get`]);function Pe(e,t,n){return e.get(H(t,n))}function H(e,t){let n=typeof t==`string`&&t.length>0?t:`default`;return`${e??``}\u0000${n}`}function Fe(e,t,n,r,i){let a=H(r,i);if(Me.has(t)){Re(e,a,ze(n));return}V.has(t)&&(t===`find`?Le(e,a,n):Ie(e,a,n))}function Ie(e,t,n){let r=n.refsGeneration;if(typeof r!=`number`){e.delete(t);return}let i=[];for(let{ref:e}of n.refs??[])i.push(e);for(let e of n.nodes??[])i.push(e.ref);U(e,t,i,r)}function Le(e,t,n){let r=n.refsGeneration;if(typeof r!=`number`)return;let i=[];typeof n.ref==`string`&&n.ref.startsWith(`@`)&&i.push(n.ref.slice(1));for(let e of n.matches??[])typeof e.ref==`string`&&e.ref.length>0&&i.push(e.ref.startsWith(`@`)?e.ref.slice(1):e.ref);U(e,t,i,r)}function Re(e,t,n){n?.refsGeneration!==void 0&&U(e,t,[...n.diff?.lines??[],...n.refs??[],...n.tail??[]].map(e=>e.ref).filter(e=>typeof e==`string`),n.refsGeneration)}function ze(e){let t=e.settle;return typeof t==`object`&&t?t:void 0}function U(e,t,n,r){if(n.length===0)return;let i=e.get(t)??new Map;e.set(t,i),Be(i,n,r)}function Be(e,t,n){for(let r of t)e.delete(r),e.set(r,n);for(;e.size>1e3;)e.delete(e.keys().next().value)}function Ve(e,t,n){let r=o(n?.divergence),i=o(r?.screen);if(i?.state!==`available`)return;let a=i.refsGeneration;if(typeof a!=`number`)return;let s=[];He(i.refs,s),U(e,t,s,a)}function He(e,t){if(Array.isArray(e))for(let n of e){let e=o(n)?.ref;typeof e==`string`&&e.length>0&&t.push(e)}}function Ue(e,t,n){return n===void 0||n.size===0?t:e===`wait`?We(t,n)??t:Ne.has(e)?Ge(t,n)??t:t}function We(e,t){if(typeof e.ref!=`string`)return;let n=W(e.ref,t);return n===e.ref?void 0:{...e,ref:n}}function Ge(e,t){let n=o(e.target);if(n?.kind!==`ref`||typeof n.ref!=`string`)return;let r=W(n.ref,t);return r===n.ref?void 0:{...e,target:{...n,ref:r}}}function W(e,t){if(!e.startsWith(`@`)||e.includes(`~`))return e;let n=t.get(e.slice(1));return n===void 0?e:`${e}~s${n}`}const Ke={config:v({operatorPath:`Point the process serving these tools at a config file with the AGENT_DEVICE_CONFIG environment variable.`}),remoteConfig:v({operatorPath:`Configure the remote profile on the process serving these tools, not per tool call.`})},qe=Object.fromEntries(_e().flatMap(e=>Object.entries(e.inputAudience).filter(([,e])=>e.kind===`operator`)));function G(e){return{...e.inputAudience,...ee,...Te,...Ke,...qe}}function Je(){return ge().map(e=>{let t=e.name in I?I[e.name]:void 0,n=J(e.name,e);return{name:e.name,description:it(e.name,te(e)),inputSchema:n,...t?{outputSchema:t}:{}}})}function K(t={}){let n=Ae();return{execute:async(r,i)=>{if(!C(r))throw new e(`INVALID_ARGS`,`Unknown command tool: ${r}`);let a=w(r),o=Y(r,a,i)??X(a.inputSchema,i,r);if(o)return await q(new e(`INVALID_ARGS`,o),n,void 0,i.session);let s=Q(r,a.inputSchema).properties,c=De(r,i,s),l=Qe(c),u=nt(c),d=n.pinInput(r,u,l.client.stateDir),f=await Xe(t,l.client);try{let e=await(t.runCommand??Ze)(f,r,d);return n.mergeCommandResult(r,e,l.client.stateDir,u.session),{isError:!1,structuredContent:await ke(r,e),content:[{type:`text`,text:await at({name:r,input:u,result:e,outputFormat:l.outputFormat,responseLevel:l.client.responseLevel})}]}}catch(e){return await q(e,n,l.client.stateDir,u.session)}}}}async function q(e,t,n,r){let i=z(e);return t.mergeErrorDetails(i.details,n,r),{isError:!0,structuredContent:i,content:[{type:`text`,text:B(i)}]}}const Ye=K();async function Xe(e,t){if(e.createClient)return await e.createClient(t);let{createAgentDeviceClient:n}=await import(`./agent-device-client.js`).then(e=>e.t);return n(t)}async function Ze(e,t,n){return await(await import(`./command-surface.js`).then(e=>e.t)).runCommand(e,t,n)}function Qe(e){return{client:$e(e),outputFormat:tt(e.mcpOutputFormat)}}function $e(t){let n=t.stateDir,r=t.includeCost,i=t.responseLevel,a={};if(n!==void 0){if(typeof n!=`string`||n.length===0)throw new e(`INVALID_ARGS`,`Expected stateDir to be a non-empty string.`);a.stateDir=n}if(r!==void 0){if(typeof r!=`boolean`)throw new e(`INVALID_ARGS`,`Expected includeCost to be a boolean.`);r&&(a.cost=!0)}let o=et(i);return o!==void 0&&(a.responseLevel=o),a}function et(t){if(t===void 0)return;let n=i.find(e=>e===t);if(n===void 0)throw new e(`INVALID_ARGS`,`Expected responseLevel to be one of 'digest', 'default', or 'full'.`);return n}function tt(t){if(t===void 0)return`optimized`;if(t!==`optimized`&&t!==`json`)throw new e(`INVALID_ARGS`,`Expected mcpOutputFormat to be "optimized" or "json".`);return t}function nt(e){return Object.fromEntries(Object.entries(e).filter(([e])=>!R.has(e)))}function J(e,t){let n=G(t),r=Q(e,t.inputSchema);return{...r,properties:Object.fromEntries(Object.entries(r.properties).filter(([e])=>n[e]?.kind!==`operator`))}}function Y(e,t,n){let r=J(e,t).properties,i=G(t);for(let t of Object.keys(n)){if(Object.hasOwn(r,t))continue;let n=Object.hasOwn(i,t)?i[t]:void 0;if(n?.kind!==`retired`)return n?.kind===`operator`?ne(t,n.source):`${t} is not an accepted argument for the ${e} tool.`}}function X(e,t,n){if(!(!e||t===void 0)){if(Array.isArray(t))return Z(t,(t,r)=>X(e.items,t,`${n}[${r}]`));if(a(t))return Z(e.oneOf??[],e=>X(e,t,n))??Z(Object.entries(e.properties??{}),([e,r])=>Object.hasOwn(t,e)?rt(r,t,e,`${n}.${e}`):void 0)}}function rt(e,t,n,r){let i=e.commandInputFor;if(i===void 0)return X(e,t[n],r);let o=t[n],s=f(t[i]);if(s===void 0||!a(o))return;let c=Y(s,w(s),o);return c===void 0?void 0:`${r}: ${c}`}function Z(e,t){for(let[n,r]of e.entries()){let e=t(r,n);if(e)return e}}function it(e,t){let n=d(e);if(n.envelopeMs===`unbounded`)return`${t} Streams progress; no fixed client timeout.`;let r=Math.round(n.envelopeMs/1e3);return n.budget.source===`none`?`${t} Times out after ${r}s.`:`${t} Times out after ${r}s; a caller-supplied budget extends it.`}function Q(e,t){let n=u(e);return{...t,properties:{...t.properties,...n&&!t.properties?.noRecord?{noRecord:{type:`boolean`,description:`Do not record this action.`}}:{},...Ee()}}}async function at(e){if(e.outputFormat===`json`||e.responseLevel!==void 0&&e.responseLevel!=="default")return $(e.result);let t=await T({name:e.name,input:e.input,result:e.result});return typeof t?.text==`string`?ot(e.name,t):$(t?.data??e.result)}function ot(e,t){let n=t.text??``;if(!ye(e))return n;let r=t.stderr?.trimEnd()??``;return r===``?n:`${n}${n.endsWith(`
|
|
3
3
|
`)?``:`
|
|
4
4
|
`}${r}`}function $(e){return typeof e==`string`?e:JSON.stringify(e,null,2)}export{z as a,B as i,K as n,R as o,Je as r,Ye as t};
|
package/dist/src/contracts.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{I as e,
|
|
1
|
+
import{I as e,q as t,y as n}from"./sdk-contracts.js";export{n as centerOfRect,e as defaultHintForCode,t as normalizeError};
|
|
@@ -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{
|
|
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{T as a,on 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=o(a(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,q 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};
|