agent-device 0.19.0 → 0.19.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/README.md +5 -1
  2. package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.19.0.apk → agent-device-android-multitouch-helper-0.19.1.apk} +0 -0
  3. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.19.1.apk.sha256 +1 -0
  4. package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.19.0.manifest.json → agent-device-android-multitouch-helper-0.19.1.manifest.json} +4 -4
  5. package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.19.0.apk → agent-device-android-snapshot-helper-0.19.1.apk} +0 -0
  6. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.19.1.apk.sha256 +1 -0
  7. package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.19.0.manifest.json → agent-device-android-snapshot-helper-0.19.1.manifest.json} +6 -6
  8. package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +24 -7
  9. package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +506 -119
  10. package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +153 -48
  11. package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Navigation.swift +172 -0
  12. package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SequenceExecution.swift +76 -5
  13. package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +60 -52
  14. package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +159 -56
  15. package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedGesturePolicy.swift +142 -0
  16. package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +16 -14
  17. package/dist/src/android-adb.d.ts +1 -2
  18. package/dist/src/android-adb.js +1 -1
  19. package/dist/src/android-input-ownership.js +6 -0
  20. package/dist/src/android.js +1 -1
  21. package/dist/src/app-lifecycle.js +3 -3
  22. package/dist/src/apple-runner-options.js +1 -1
  23. package/dist/src/apps.js +5 -5
  24. package/dist/src/cli-help.js +131 -34
  25. package/dist/src/cli-runner.js +1 -1
  26. package/dist/src/cli.js +11 -11
  27. package/dist/src/client.js +2 -2
  28. package/dist/src/command-metadata.js +1 -1
  29. package/dist/src/command-schema.js +3 -3
  30. package/dist/src/device-input-state.js +2 -2
  31. package/dist/src/devices2.js +1 -1
  32. package/dist/src/find.js +1 -1
  33. package/dist/src/generic.js +1 -1
  34. package/dist/src/index.d.ts +199 -20
  35. package/dist/src/input-actions.js +3 -3
  36. package/dist/src/interaction-snapshot.js +1 -1
  37. package/dist/src/interaction.js +1 -1
  38. package/dist/src/interactor.js +2 -2
  39. package/dist/src/internal/bin.js +1 -1
  40. package/dist/src/internal/daemon.js +17 -15
  41. package/dist/src/lease.js +1 -1
  42. package/dist/src/linux.js +1 -1
  43. package/dist/src/metro.d.ts +0 -1
  44. package/dist/src/notifications.js +1 -1
  45. package/dist/src/points.js +1 -1
  46. package/dist/src/project-runtime.js +1 -1
  47. package/dist/src/providers.js +1 -1
  48. package/dist/src/react-native.js +1 -1
  49. package/dist/src/record-trace-recording.js +2 -2
  50. package/dist/src/record-trace.js +1 -1
  51. package/dist/src/registry.js +24 -23
  52. package/dist/src/reporting.js +3 -3
  53. package/dist/src/runner-client.js +1 -1
  54. package/dist/src/runtime.js +2 -2
  55. package/dist/src/sdk-android-adb.d.ts +2 -2
  56. package/dist/src/sdk-batch-runner.d.ts +0 -1
  57. package/dist/src/sdk-batch.js +2 -2
  58. package/dist/src/sdk-finders.d.ts +1 -2
  59. package/dist/src/sdk-finders.js +1 -1
  60. package/dist/src/sdk-io.d.ts +0 -1
  61. package/dist/src/sdk-remote-config.d.ts +1 -2
  62. package/dist/src/sdk-remote-config.js +1 -1
  63. package/dist/src/sdk-selectors.js +1 -1
  64. package/dist/src/selector-runtime.js +1 -1
  65. package/dist/src/selectors.d.ts +0 -1
  66. package/dist/src/selectors.js +1 -1
  67. package/dist/src/selectors2.js +1 -1
  68. package/dist/src/server.js +3 -3
  69. package/dist/src/session.js +10 -10
  70. package/dist/src/simctl.js +1 -1
  71. package/dist/src/simulator.js +1 -1
  72. package/dist/src/snapshot-diagnostics.js +2 -2
  73. package/dist/src/snapshot-helper.js +4 -4
  74. package/dist/src/snapshot-quality.js +1 -1
  75. package/dist/src/snapshot2.js +2 -2
  76. package/dist/src/tv-remote.js +14 -0
  77. package/dist/src/web.js +1 -1
  78. package/package.json +5 -4
  79. package/server.json +2 -2
  80. package/skills/agent-device/SKILL.md +8 -7
  81. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.19.0.apk.sha256 +0 -1
  82. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.19.0.apk.sha256 +0 -1
  83. package/dist/src/device-rotation.js +0 -14
  84. package/dist/src/logcat.js +0 -6
@@ -1 +1 @@
1
- import{B as e,D as t,F as n,I as r,M as i,N as a,T as o,b as s,f as c,m as l,p as u}from"./sdk-contracts.js";import{j as d}from"./sdk-android-adb.js";import{h as f,y as p}from"./sdk-batch.js";import{H as ee,c as m}from"./device-rotation.js";import{N as h,P as te,a as ne,i as re,m as ie,n as ae,r as oe,t as se,u as ce}from"./sdk-selectors.js";import{t as le}from"./snapshot-quality.js";import{a as ue}from"./sdk-finders.js";import"./selectors2.js";import{n as de,t as fe}from"./runtime.js";import{r as pe}from"./app-lifecycle.js";import{c as me,f as he,i as g}from"./runner-client.js";import{Et as ge,Ht as _e,It as ve,Ot as _,Qt as v,Tt as ye,Xt as y,Zt as be,jt as b,kt as x,on as S,zt as C}from"./internal/daemon.js";import{a as w,t as T}from"./apple-runner-options.js";import{o as xe}from"./apps.js";function E(e){if(e.length<2)return null;let t=Number(e[0]),n=Number(e[1]);return!Number.isFinite(t)||!Number.isFinite(n)?null:{x:t,y:n}}async function D(e){let{device:t,node:n,flags:r,appBundleId:i,traceOutPath:a,surface:o,contextFromFlags:s}=e,c=ce(n),l=ee(n.rect);if(!l||u(t)&&c&&!te(n.type??``))return c;try{let e=await _e(t,`read`,[String(l.x),String(l.y)],void 0,{...s(r,i,a),surface:o}),u=e&&typeof e==`object`?e:void 0,f=typeof u?.text==`string`?u.text:``;return f.trim()?f:(d({level:`warn`,phase:`interaction_read_fallback`,data:{reason:`empty_backend_text`,nodeRef:n.ref,surface:o,platform:t.platform}}),c)}catch(e){return d({level:`warn`,phase:`interaction_read_fallback`,data:{reason:`backend_read_failed`,nodeRef:n.ref,surface:o,platform:t.platform,error:e instanceof Error?e.message:String(e)}}),c}}async function O(e,t,n){let r=e.get(t),i=r?.device??await S(n??{});return r||await w(i),{session:r,device:i}}async function k(e,t,n){let r=!e&&u(t);try{return await n()}finally{r&&(await me(t.id),await Se(t))}}async function Se(e){let t=he();await xe(e,t).catch(n=>{d({level:`debug`,phase:`ios_sessionless_runner_host_close_failed`,data:{deviceId:e.id,bundleId:t,error:n instanceof Error?n.message:String(n)}})})}function Ce(e,t,n,r){t&&e.recordAction(t,{command:n.command,positionals:n.positionals??[],flags:n.flags??{},result:r})}function we(e){let{session:t,sessionName:n,device:r,snapshot:i,appBundleId:a}=e;return t?{...t,snapshot:i,lastComparisonSafeSnapshot:i?.comparisonSafe===!0?i:t.lastComparisonSafeSnapshot}:{name:n,device:r,createdAt:Date.now(),appBundleId:a,snapshot:i,...i?.comparisonSafe===!0?{lastComparisonSafeSnapshot:i}:{},actions:[]}}const Te=[[`snapshotDepth`,`--depth`],[`snapshotScope`,`--scope`],[`snapshotRaw`,`--raw`]];function A(e,t){let n=Ee(t);return n.length===0?null:y(`INVALID_ARGS`,`${e} @ref does not support ${n.join(`, `)}.`)}function Ee(e){if(!e)return[];let t=[];for(let[n,r]of Te)e[n]!==void 0&&t.push(r);return t}function De(e,t){if(!t||t.settle===!0)return null;let n=[];return t.settleQuietMs!==void 0&&n.push(`--settle-quiet`),n.length===0?null:y(`INVALID_ARGS`,`${e}: ${n.join(`, `)} require${n.length===1?`s`:``} --settle.`)}function Oe(e){if(e?.settle===!0)return{...e.settleQuietMs===void 0?{}:{quietMs:e.settleQuietMs},...e.timeoutMs===void 0?{}:{timeoutMs:e.timeoutMs}}}function j(e){let t=a(e);return t?{ok:!0,ref:t.base,generation:t.generation}:{ok:!1,response:y(`INVALID_ARGS`,`Invalid ref "${e}" — malformed generation suffix.`,{hint:o})}}function ke(e,t){let n=E(e);if(n)return{ok:!0,target:{kind:`point`,x:n.x,y:n.y}};let r=e[0]??``;if(r.startsWith(`@`)){let t=j(r);return t.ok?{ok:!0,target:{kind:`ref`,ref:t.ref,fallbackLabel:e.slice(1).join(` `).trim()},refGeneration:t.generation}:{ok:!1,response:t.response}}let i=e.join(` `).trim();return i?{ok:!0,target:{kind:`selector`,selector:i}}:{ok:!1,response:y(`INVALID_ARGS`,`${t} requires @ref, selector expression, or x y coordinates`)}}function Ae(e){let t=E(e);if(t)return{ok:!0,target:{kind:`point`,x:t.x,y:t.y},...Le(e[2])};let n=Ie(e),r=ke(n.targetPositionals,`longpress`);return r.ok?{ok:!0,target:r.target,refGeneration:r.refGeneration,...n.duration}:r}function je(e){let t=e[0]??``;if(t.startsWith(`@`)){let n=j(t);if(!n.ok)return{ok:!1,response:n.response};let r=m(e).text;return r?{ok:!0,target:{kind:`ref`,ref:n.ref,fallbackLabel:Fe(e)},refGeneration:n.generation,text:r}:{ok:!1,response:y(`INVALID_ARGS`,`fill requires text after ref`)}}let n=E(e);if(n){let t=e.slice(2).join(` `);return t?{ok:!0,target:{kind:`point`,x:n.x,y:n.y},text:t}:{ok:!1,response:y(`INVALID_ARGS`,`fill requires text after coordinates`)}}let r=Me(e);return!r||r.kind!==`selector`?{ok:!1,response:y(`INVALID_ARGS`,`fill requires x y text, @ref text, or selector text`)}:r.text.trim()?{ok:!0,target:{kind:`selector`,selector:r.target.selector},text:r.text}:{ok:!1,response:y(`INVALID_ARGS`,`fill requires text after selector`)}}function Me(e){try{return m(e)}catch{return null}}function Ne(e){let t=`evidence`in e?e.evidence:void 0,n=e.settle;return e.kind===`ref`?{ref:M(e.target?.kind===`ref`?e.target.ref:void 0),refLabel:e.refLabel,selectorChain:e.selectorChain,targetHittable:e.targetHittable,hint:e.hint,evidence:t,settle:n}:e.kind===`selector`?{selector:e.target?.kind===`selector`?e.target.selector:void 0,selectorChain:e.selectorChain,refLabel:e.refLabel,targetHittable:e.targetHittable,hint:e.hint,evidence:t,settle:n}:{evidence:t,settle:n}}function Pe(e,t){return e.kind===`point`?`coordinate tap`:t.kind===`ref`&&t.target?.kind===`ref`?t.target.ref:t.kind===`selector`&&t.target?.kind===`selector`?t.target.selector:`target`}function M(e){return e?.startsWith(`@`)?e.slice(1):e}function Fe(e){return e.length>=3&&e[1]?.trim()||``}function Ie(e){let t=e.at(-1);return e.length>1&&Re(t)?{targetPositionals:e.slice(0,-1),duration:{durationMs:Number(t)}}:{targetPositionals:e,duration:{}}}function Le(e){return e===void 0?{}:{durationMs:Number(e)}}function Re(e){return e===void 0||e.trim()===``?!1:Number.isFinite(Number(e))}async function ze(e,t){let r=await N(e);if(r)throw new n(`COMMAND_FAILED`,`press ${t} left ${e.appBundleId} and foregrounded ${r.foregroundPackage}. The tap likely escaped the app.`,r)}async function N(e){if(e.device.platform!==`android`||!e.appBundleId)return null;let t=await pe(e.device),n=t.package?.trim();return!n||n===e.appBundleId||!Ue(n)?null:{expectedPackage:e.appBundleId,foregroundPackage:n,activity:t.activity,hint:He(n)}}function Be(e){return e.foregroundPackage===`com.google.android.permissioncontroller`?`Android permission dialog is blocking ${e.expectedPackage}`:`${e.foregroundPackage} is foreground instead of ${e.expectedPackage}`}function Ve(e){return e.code===`COMMAND_FAILED`&&typeof e.details?.expectedPackage==`string`&&typeof e.details?.foregroundPackage==`string`}function He(e){return e===`com.google.android.permissioncontroller`?`Dismiss or allow the permission prompt, then retry the smoke assertion.`:`Use screenshot as visual truth, then take a fresh snapshot -i before retrying.`}function Ue(e){return e===`com.android.settings`||e===`com.android.systemui`||e===`com.google.android.permissioncontroller`||e.includes(`launcher`)}function We(e,t){if(t===`exists`)return{found:!0};if(t===`wait`)return{found:!0,waitedMs:e.waitedMs};let n=typeof e.ref==`string`?e.ref:void 0;return t===`get_attrs`?{ref:n,action:`get attrs`}:{ref:n,action:`get text`,text:typeof e.text==`string`?e.text:``}}function Ge(e){return e.kind===`found`?{found:!0,...typeof e.waitedMs==`number`?{waitedMs:e.waitedMs}:{}}:{...typeof e.ref==`string`?{ref:e.ref}:{},...typeof e.text==`string`?{text:e.text}:{},...e.node&&typeof e.node==`object`?{node:e.node}:{}}}function P(e,t){let n=Array.isArray(e.selectorChain)?e.selectorChain:void 0,r=R(e),i=r?.kind===`ref`?z(r.ref):void 0,a=r?.kind===`selector`?r.selector:void 0,o={...i?{ref:i}:{},...a?{selector:a}:{},...n?{selectorChain:n}:{}};if(t===`attrs`)return o;let s=typeof e.text==`string`?e.text:``;return{...o,text:s,refLabel:qe(s)}}function F(e){let t=R(e);return{...t?.kind===`ref`?{ref:z(t.ref)}:{},...t?.kind===`selector`?{selector:t.selector}:{},...typeof e.text==`string`?{text:e.text}:{},...e.node&&typeof e.node==`object`?{node:e.node}:{}}}function Ke(e){return{waitedMs:e.waitedMs,...typeof e.text==`string`?{text:e.text}:{},...typeof e.selector==`string`?{selector:e.selector}:{},...typeof e.captures==`number`?{captures:e.captures}:{},...typeof e.nodeCount==`number`?{nodeCount:e.nodeCount}:{},...typeof e.hint==`string`?{hint:e.hint}:{}}}function I(e){let{selectorChain:t,...n}=e;return n}function L(e,t,n,r){let i=e.get(t);i&&e.recordAction(i,{command:n.command,positionals:n.positionals??[],flags:n.flags??{},result:r})}function qe(e){let t=e.trim();if(!(!t||t.length>80||/[\r\n]/.test(t)))return t}function R(e){let t=e.target;if(!t||typeof t!=`object`)return;let n=t;if(n.kind===`ref`&&typeof n.ref==`string`)return{kind:`ref`,ref:n.ref};if(n.kind===`selector`&&typeof n.selector==`string`)return{kind:`selector`,selector:n.selector}}function z(e){return e.startsWith(`@`)?e.slice(1):e}const Je=[`application`,`window`,`tabbar`,`scrollbar`,`image`],Ye=new Set([`tab bar`]);async function B(e,t){if(t.ok||!Xe(t.error.message)||t.error.details?.captureStalled===!0)return t;let n=await Ze(e).catch(()=>null);return n?y(t.error.code,`${t.error.message}. Current surface: ${n.summary}.`,{...t.error.details??{},currentSurface:n.details}):t}function Xe(e){return/^wait timed out (?:for (?:selector|text): |waiting for a stable UI)/i.test(e)}async function Ze(e){let t=[...(await b({device:e.device,session:e.session,flags:{...e.req.flags,snapshotInteractiveOnly:!0},logPath:e.logPath??``})).snapshot.nodes].sort(Qe),n=V(t,6,{includeIdentifiers:!0});if(n.length===0)return null;let r=V(t.filter(e=>!W(e)),4,{includeIdentifiers:!1}),i=V(t.filter(et),4,{includeIdentifiers:!0});return{summary:(r.length>0?r:n.slice(0,4)).join(`, `),details:{labels:n,...i.length>0?{buttons:i}:{}}}}function V(e,t,n){let r=new Set,i=[];for(let a of e){let e=U(a,n);if(!(!e||r.has(e))&&(r.add(e),i.push(e),i.length>=t))break}return i}function Qe(e,t){return H(e)-H(t)||$e(e,t)}function H(e){let t=!!U(e,{includeIdentifiers:!1});return(W(e)?2:0)+ +!t}function $e(e,t){return e.rect&&t.rect?e.rect.y-t.rect.y||e.rect.x-t.rect.x:e.rect?-1:t.rect?1:(e.depth??0)-(t.depth??0)||e.index-t.index}function U(e,t){let n=(t.includeIdentifiers?[e.label,e.value,e.identifier]:[e.label,e.value]).map(e=>typeof e==`string`?e.trim():``).find(e=>e.length>0);return n?n.replace(/\s+/g,` `).slice(0,80):``}function W(e){let t=h(`${e.type??``} ${e.role??``} ${e.subrole??``}`),n=`${e.label??``} ${e.value??``}`.trim().toLowerCase();return Je.some(e=>t.includes(e))||Ye.has(n)||n.endsWith(`.fill`)}function et(e){return h(`${e.type??``} ${e.role??``} ${e.subrole??``}`).includes(`button`)}function G(e){let{session:t,selectorExpression:n}=e;if(!t||!u(t.device)||t.postGestureStabilization)return null;let r=p(n);if(!r||r.selectors.length!==1)return null;let i=r.selectors[0];if(!i||i.terms.length!==1)return null;let a=i.terms[0];return!a||typeof a.value!=`string`||!tt(a.key)?null:{key:a.key,value:a.value,raw:i.raw}}function tt(e){return e===`id`||e===`label`||e===`text`||e===`value`}function K(e,t={}){let n=r(e);if(n.code===`ELEMENT_NOT_FOUND`)return t.delegateSemanticFailures===!0||t.allowElementNotFound===!0;if(n.code===`AMBIGUOUS_MATCH`)return t.delegateSemanticFailures===!0;if(n.code===`ELEMENT_OFFSCREEN`)return!0;if(n.code!==`COMMAND_FAILED`)return!1;let i=n.message.toLowerCase();return i.includes(`fetch failed`)||i.includes(`timed out`)||i.includes(`timeout`)||i.includes(`runner did not accept connection`)||i.includes(`invalid runner response`)}function nt(e,t={}){let r=t.plural===!0?`do`:`does`;return{resolveInput:async()=>{throw new n(`UNSUPPORTED_OPERATION`,`${e} ${r} not resolve input artifacts`)},reserveOutput:async()=>{throw new n(`UNSUPPORTED_OPERATION`,`${e} ${r} not reserve output artifacts`)},createTempFile:async()=>{throw new n(`UNSUPPORTED_OPERATION`,`${e} ${r} not create temporary files`)}}}function rt(e,t={}){return{artifacts:nt(e,t),policy:de()}}function q(e){let{session:t,sessionStore:n,sessionName:r}=e,i=0,a,o;return{capture:async s=>{let c=Date.now(),l=pt(s,e.req.flags?.out),u=st({timestamp:c,lastSnapshotAt:i,lastSnapshotResult:a,lastSnapshotCacheKey:o,session:t,request:s,cacheKey:l});if(u)return u;let d=ct({session:t,timestamp:c,request:s});if(d)return i=d.createdAt,a={snapshot:d},o=l,a;let f=await it({params:e,request:s}),p={snapshot:f};return ht({session:t,sessionStore:n,sessionName:r,snapshot:f}),i=c,a=p,o=l,p}}}async function it(e){let{params:t,request:n}=e,r=await J(t,n,n.snapshotScope);return n.recovery?.legacyIosSparse&&gt(r)?await at({runtimeParams:t,request:n,policy:n.recovery.legacyIosSparse}):n.recovery?.sparseVerdictQueryScope?.shouldScope&&le(r.snapshotQuality)?await ot({runtimeParams:t,request:n,policy:n.recovery.sparseVerdictQueryScope,snapshot:r}):r}async function at(e){let{runtimeParams:t,request:n,policy:r}=e;try{return await J(t,n,r.scope,!1)}catch(e){if(!r.shouldScope)throw e;return await J(t,n,r.query,!1)}}async function ot(e){let{runtimeParams:t,request:n,policy:r,snapshot:i}=e;try{return await J(t,n,r.query,!1)}catch{return i}}async function J(e,t,n,r=t.flags?.snapshotInteractiveOnly){return(await b({device:e.device,session:e.session,flags:{...t.flags,snapshotInteractiveOnly:r},outPath:t.outPath??e.req.flags?.out,logPath:e.logPath??``,snapshotScope:n,includeRects:t.includeRects})).snapshot}function st(e){let{timestamp:t,lastSnapshotAt:n,lastSnapshotResult:r,lastSnapshotCacheKey:i,session:a,request:o,cacheKey:s}=e;if(o.cache?.forceFresh!==!0&&r&&i===s&&!(t-n>=750)&&!C(a)&&!dt(a,o))return r}function ct(e){let{session:t,timestamp:n,request:r}=e,i=t?.snapshot;if(i&&lt(t,r)&&ut(i,n)&&i.presentationKey===ft(r))return i}function lt(e,t){return!(t.cache?.forceFresh===!0||t.cache?.useSessionSnapshot!==!0||C(e)||dt(e,t))}function ut(e,t){return t-e.createdAt<750}function dt(e,t){return t.cache?.bypassForPostGestureStabilization===!0&&!!e?.postGestureStabilization}function ft(e){return t(i(mt(e)))}function pt(e,t){return JSON.stringify({presentationKey:ft(e),includeRects:e.includeRects===!0,outPath:e.outPath??t??null})}function mt(e){return e.snapshotScope===void 0?e.flags:{...e.flags,snapshotScope:e.snapshotScope}}function ht(e){let{session:t,sessionStore:n,sessionName:r,snapshot:i}=e;!t||le(i.snapshotQuality)||(x(t,i),n.set(r,t))}function gt(e){return e.snapshotQuality||e.backend!==`xctest`||e.nodes.length!==1?!1:e.nodes[0]?.type===`Application`}function _t(e){return fe({backend:vt(e),...rt(`selector commands`,{plural:!0}),sessions:ye({sessionName:e.sessionName,getSession:()=>e.session,recordOptions:{includeSnapshot:!0},setRecord:t=>{!e.session||!t.snapshot||(x(e.session,t.snapshot),e.sessionStore.set(e.sessionName,e.session))}})})}async function Y(e,t){let n=e.sessionStore.get(e.sessionName);if(!n&&t.requireSession)return{ok:!1,response:be()};let r=n?.device??await S(e.req.flags??{});n||await w(r);let i=v(t.capability,r);return i?{ok:!1,response:i}:{ok:!0,runtime:_t({...e,session:n,device:r})}}function vt(e){let{req:t,session:n,device:r,logPath:i,sessionName:a,sessionStore:o}=e,c=q({device:r,session:n,sessionStore:o,sessionName:a,req:t,logPath:i});return{platform:s(r),captureSnapshot:async(e,n)=>{let i={...t.flags,...yt(n)},a=n?.includeRects===!0,o=n?.scope??t.flags?.snapshotScope,s=t.command===`wait`||t.command===`find`||a&&r.platform===`web`;return await c.capture({flags:i,snapshotScope:o,includeRects:a,cache:{forceFresh:s,useSessionSnapshot:!0,bypassForPostGestureStabilization:!0}})},readText:async(a,o)=>({text:await D({device:r,node:o,flags:t.flags,appBundleId:n?.appBundleId,traceOutPath:n?.trace?.outPath,surface:n?.surface,contextFromFlags:e.contextFromFlags??((e,t,n)=>ve(i??``,e,t,n))})}),findText:async(t,n)=>({found:await bt(e,n)})}}function yt(e){let t={};return e?.interactiveOnly!==void 0&&(t.snapshotInteractiveOnly=e.interactiveOnly),e?.scope!==void 0&&(t.snapshotScope=e.scope),e?.depth!==void 0&&(t.snapshotDepth=e.depth),e?.raw!==void 0&&(t.snapshotRaw=e.raw),t}async function bt(e,t){let n=await xt(e,t);if(n!==null)return n;let r=await St(e,t);return r===null?await Tt(e,t):r}async function xt(e,t){return!l(e.device)||!e.session?.surface||e.session.surface===`app`?null:await Tt(e,t)}async function St(e,t){let n=Ct(e);return n?(await g(n.device,{command:`findText`,text:t,appBundleId:n.appBundleId},wt(e,n)))?.found===!0:null}function Ct(e){return!c(e.device.platform)||!e.session?.appBundleId?null:{device:e.device,appBundleId:e.session.appBundleId,traceLogPath:e.session.trace?.outPath}}function wt(e,t){return T({req:e.req,logPath:e.logPath,traceLogPath:t.traceLogPath})}async function Tt(e,t){return!!ie((await Et(e)).nodes,t)}async function Et(e){let{snapshot:t}=await q({device:e.device,session:e.session,sessionStore:e.sessionStore,sessionName:e.sessionName,req:e.req,logPath:e.logPath}).capture({flags:{...e.req.flags,snapshotInteractiveOnly:!1},cache:{forceFresh:!0,bypassForPostGestureStabilization:!0}});return t}async function Dt(e){let{req:t}=e;if(t.command!==`find`)return null;let n=t.positionals??[];if(n.length===0)return y(`INVALID_ARGS`,`find requires a locator or text`);let r=ue(n);if(!r.query)return y(`INVALID_ARGS`,`find requires a value`);if(t.flags?.findFirst&&t.flags?.findLast)return y(`INVALID_ARGS`,`find accepts only one of --first or --last`);let i=r.action;if(!Vt(i))return null;let a=await Y(e,{requireSession:!1,capability:`find`});return a.ok?await Q(async()=>{let n=await a.runtime.selectors.find({session:e.sessionName,requestId:t.meta?.requestId,locator:r.locator,query:r.query,action:i,timeoutMs:r.timeoutMs});L(e.sessionStore,e.sessionName,t,We(n,i));let o=Ge(n);if(typeof o.ref==`string`){let t=e.sessionStore.get(e.sessionName);if(t&&(ge(t),e.sessionStore.set(e.sessionName,t),t.snapshotGeneration!==void 0))return{...o,refsGeneration:t.snapshotGeneration}}return o}):a.response}async function Ot(e){let{req:t}=e;if(t.command!==`get`)return null;let n=t.positionals?.[0];if(n!==`text`&&n!==`attrs`)return y(`INVALID_ARGS`,`get only supports text or attrs`);let r=zt(t);if(!r.ok)return r.response;if(r.target.kind===`ref`){let e=A(`get`,t.flags);if(e)return e}if(r.target.kind===`selector`){let t=await jt(e,n,r.target.selector);if(t)return t}let i=await Y(e,{requireSession:!0,capability:`get`});if(!i.ok)return i.response;let a=r.target.kind===`ref`?_({session:e.sessionStore.get(e.sessionName),ref:r.target.ref,mintedGeneration:r.refGeneration}):void 0;return await Q(async()=>{let o=await i.runtime.selectors.get({session:e.sessionName,requestId:t.meta?.requestId,property:n,target:r.target});L(e.sessionStore,e.sessionName,t,P(o,n));let s=F(o);return a?{...s,warning:a}:s})}async function kt(e){let{req:t}=e;if(t.command!==`is`)return null;let{predicate:n,split:r}=se(t.positionals??[]),i=n.toLowerCase();if(!ne(i))return y(`INVALID_ARGS`,ae,{hint:oe});if(!r)return y(`INVALID_ARGS`,`is requires a selector expression`);let a=r.rest.join(` `).trim();if(i===`text`&&!a)return y(`INVALID_ARGS`,`is text requires expected text value`);if(i!==`text`&&r.rest.length>0)return y(`INVALID_ARGS`,`is ${i} does not accept trailing values`);let o=await Mt(e,i,r.selectorExpression,a);if(o)return o;let s=await Y(e,{requireSession:!0,capability:`is`});return s.ok?await $(e,await Q(async()=>{let n=await s.runtime.selectors.is({session:e.sessionName,requestId:t.meta?.requestId,predicate:i,selector:r.selectorExpression,expectedText:a});return L(e.sessionStore,e.sessionName,t,n),I(n)}),`is ${i}`):s.response}async function At(e){let{req:t,sessionName:n,sessionStore:r}=e,i=f(t.positionals??[]);if(!i)return y(`INVALID_ARGS`,`wait requires a duration or text`);let{session:a,device:o}=await O(r,n,t.flags);if(i.kind!==`sleep`){let e=v(`wait`,o);if(e)return e}if(i.kind===`selector`){let t=await Nt({...e,session:a,device:o,selectorExpression:i.selectorExpression,timeoutMs:i.timeoutMs});if(t)return t}let s=i,c;if(i.kind===`ref`){let e=j(i.rawRef);if(!e.ok)return e.response;s={...i,rawRef:e.ref},c=_({session:a,ref:e.ref,mintedGeneration:e.generation})}let l=async()=>{let i=_t({...e,session:a,device:o}),l=await Q(async()=>{let e=await i.selectors.wait({session:n,requestId:t.meta?.requestId,target:Bt(s,a)});L(r,n,t,e);let o=Ke(e);return c?{...o,warning:c}:o});return await $(e,await B({req:t,logPath:e.logPath,session:a,device:o},l),`wait`)};return i.kind===`sleep`?await l():await k(a,o,l)}async function jt(e,t,n){let r=e.sessionStore.get(e.sessionName),i=G({session:r,selectorExpression:n});if(!r||!i||t===`text`&&i.key!==`id`)return null;let a=await X(e,r,i);if(Z(a))return a.response;if(!a)return null;let o={session:r,selector:i,result:a},s=It(t,o.selector.raw,o.result);return s?(L(e.sessionStore,e.sessionName,e.req,P(s,t)),{ok:!0,data:F(s)}):null}async function Mt(e,t,n,r){if(t===`hidden`)return null;let i=await Pt(e,n);if(Z(i))return i.response;if(!i?.result.found||!i.result.node)return null;let a=t===`exists`?{predicate:t,pass:!0,selector:i.selector.raw,matches:1,selectorChain:[i.selector.raw]}:Lt(t,r,i.selector.raw,i.session,i.result.node);return a?(L(e.sessionStore,e.sessionName,e.req,a),{ok:!0,data:I(a)}):null}async function Nt(e){let t=G({session:e.session,selectorExpression:e.selectorExpression});if(!e.session||!t)return null;let n=Date.now(),r=await X(e,e.session,t);if(Z(r))return r.response;if(!r?.found)return null;let i={kind:`selector`,selector:t.raw,waitedMs:Date.now()-n,selectorChain:[t.raw]};L(e.sessionStore,e.sessionName,e.req,i);let a={ok:!0,data:i};return await B({req:e.req,logPath:e.logPath,session:e.session,device:e.device},a)}async function Pt(e,t){let n=e.sessionStore.get(e.sessionName),r=G({session:n,selectorExpression:t});if(!n||!r)return null;let i=await X(e,n,r);return Z(i)?i:i?{session:n,selector:r,result:i}:null}async function Ft(e,t,n){let r=await g(t.device,{command:`querySelector`,selectorKey:n.key,selectorValue:n.value,appBundleId:t.appBundleId},T({req:e.req,logPath:e.logPath,traceLogPath:t.trace?.outPath})),i=r.found===!0,a=Rt(r);return{found:i,...typeof r.text==`string`?{text:r.text}:{},...a?{node:a}:{}}}async function X(t,n,r){try{return await Ft(t,n,r)}catch(t){return K(t,{allowElementNotFound:!0})?null:{kind:`error`,response:{ok:!1,error:e(t)}}}}function Z(e){return e!==null&&`kind`in e&&e.kind===`error`}function It(e,t,n){if(!n.found||!n.node)return null;let r={target:{kind:`selector`,selector:t},node:n.node,selectorChain:[t]};return e===`attrs`?{kind:`attrs`,...r}:typeof n.text==`string`?{kind:`text`,...r,text:n.text}:null}function Lt(e,t,n,r,i){let a=re({predicate:e,node:i,nodes:[i],expectedText:t,platform:r.device.platform});return{predicate:e,pass:a.pass,selector:n,...e===`text`?{text:a.actualText}:{},selectorChain:[n]}}function Rt(e){let t=e.nodes;if(!Array.isArray(t))return;let n=t[0];if(!(!n||typeof n!=`object`))return n}function zt(e){let t=e.positionals?.[1]??``;if(t.startsWith(`@`)){let n=j(t);return n.ok?{ok:!0,target:{kind:`ref`,ref:n.ref,fallbackLabel:e.positionals.length>2?e.positionals.slice(2).join(` `).trim():``},refGeneration:n.generation}:{ok:!1,response:n.response}}let n=e.positionals?.slice(1).join(` `).trim()??``;return n?{ok:!0,target:{kind:`selector`,selector:n}}:{ok:!1,response:y(`INVALID_ARGS`,`get requires @ref or selector expression`)}}function Bt(e,t){if(e.kind===`sleep`)return{kind:`sleep`,durationMs:e.durationMs};if(e.kind===`selector`)return{kind:`selector`,selector:e.selectorExpression,timeoutMs:e.timeoutMs};if(e.kind===`ref`){if(!t?.snapshot)throw new n(`INVALID_ARGS`,`Ref wait requires an existing snapshot in session.`);return{kind:`ref`,ref:e.rawRef,timeoutMs:e.timeoutMs}}if(e.kind===`stable`)return{kind:`stable`,quietMs:e.quietMs,timeoutMs:e.timeoutMs};if(!e.text)throw new n(`INVALID_ARGS`,`wait requires text`);return{kind:`text`,text:e.text,timeoutMs:e.timeoutMs}}async function Q(e){try{return{ok:!0,data:await e()}}catch(e){let t=r(e);return y(t.code,t.message,t.details)}}async function $(e,t,n){if(t.ok)return t;let r=e.sessionStore.get(e.sessionName);if(!r)return t;let i;try{i=await N(r)}catch{return t}return i?y(t.error.code,`${n} failed because ${Be(i)}.`,{...t.error.details??{},...i,blockedBy:`android_foreground_surface`,originalMessage:t.error.message}):t}function Vt(e){return e===`exists`||e===`wait`||e===`get_text`||e===`get_attrs`}export{k as C,O as S,Oe as _,q as a,we as b,G as c,Pe as d,Ne as f,M as g,ke as h,At as i,ze as l,Ae as m,Ot as n,rt as o,je as p,kt as r,K as s,Dt as t,Ve as u,A as v,D as w,Ce as x,De as y};
1
+ import{B as e,D as t,F as n,I as r,M as i,N as a,T as o,b as s,f as c,m as l,p as u}from"./sdk-contracts.js";import{j as d}from"./sdk-android-adb.js";import{S as f,v as p}from"./sdk-batch.js";import{J as ee,m}from"./tv-remote.js";import{N as h,P as te,a as ne,i as re,m as ie,n as ae,r as oe,t as se,u as ce}from"./sdk-selectors.js";import{t as le}from"./snapshot-quality.js";import{a as ue}from"./sdk-finders.js";import"./selectors2.js";import{n as de,t as fe}from"./runtime.js";import{r as pe}from"./app-lifecycle.js";import{c as me,f as he,i as g}from"./runner-client.js";import{$t as _,Gt as ge,Ht as v,Mt as y,Ot as _e,Pt as b,en as ve,jt as x,kt as ye,ln as S,tn as C,zt as be}from"./internal/daemon.js";import{a as w,t as T}from"./apple-runner-options.js";import{o as xe}from"./apps.js";function E(e){if(e.length<2)return null;let t=Number(e[0]),n=Number(e[1]);return!Number.isFinite(t)||!Number.isFinite(n)?null:{x:t,y:n}}async function D(e){let{device:t,node:n,flags:r,appBundleId:i,traceOutPath:a,surface:o,contextFromFlags:s}=e,c=ce(n),l=ee(n.rect);if(!l||u(t)&&c&&!te(n.type??``))return c;try{let e=await ge(t,`read`,[String(l.x),String(l.y)],void 0,{...s(r,i,a),surface:o}),u=e&&typeof e==`object`?e:void 0,f=typeof u?.text==`string`?u.text:``;return f.trim()?f:(d({level:`warn`,phase:`interaction_read_fallback`,data:{reason:`empty_backend_text`,nodeRef:n.ref,surface:o,platform:t.platform}}),c)}catch(e){return d({level:`warn`,phase:`interaction_read_fallback`,data:{reason:`backend_read_failed`,nodeRef:n.ref,surface:o,platform:t.platform,error:e instanceof Error?e.message:String(e)}}),c}}async function O(e,t,n){let r=e.get(t),i=r?.device??await S(n??{});return r||await w(i),{session:r,device:i}}async function k(e,t,n){let r=!e&&u(t);try{return await n()}finally{r&&(await me(t.id),await Se(t))}}async function Se(e){let t=he();await xe(e,t).catch(n=>{d({level:`debug`,phase:`ios_sessionless_runner_host_close_failed`,data:{deviceId:e.id,bundleId:t,error:n instanceof Error?n.message:String(n)}})})}function Ce(e,t,n,r){t&&e.recordAction(t,{command:n.command,positionals:n.positionals??[],flags:n.flags??{},result:r})}function we(e){let{session:t,sessionName:n,device:r,snapshot:i,appBundleId:a}=e;return t?{...t,snapshot:i,lastComparisonSafeSnapshot:i?.comparisonSafe===!0?i:t.lastComparisonSafeSnapshot}:{name:n,device:r,createdAt:Date.now(),appBundleId:a,snapshot:i,...i?.comparisonSafe===!0?{lastComparisonSafeSnapshot:i}:{},actions:[]}}const Te=[[`snapshotDepth`,`--depth`],[`snapshotScope`,`--scope`],[`snapshotRaw`,`--raw`]];function A(e,t){let n=Ee(t);return n.length===0?null:_(`INVALID_ARGS`,`${e} @ref does not support ${n.join(`, `)}.`)}function Ee(e){if(!e)return[];let t=[];for(let[n,r]of Te)e[n]!==void 0&&t.push(r);return t}function De(e,t){if(!t||t.settle===!0)return null;let n=[];return t.settleQuietMs!==void 0&&n.push(`--settle-quiet`),n.length===0?null:_(`INVALID_ARGS`,`${e}: ${n.join(`, `)} require${n.length===1?`s`:``} --settle.`)}function Oe(e){if(e?.settle===!0)return{...e.settleQuietMs===void 0?{}:{quietMs:e.settleQuietMs},...e.timeoutMs===void 0?{}:{timeoutMs:e.timeoutMs}}}function j(e){let t=a(e);return t?{ok:!0,ref:t.base,generation:t.generation}:{ok:!1,response:_(`INVALID_ARGS`,`Invalid ref "${e}" — malformed generation suffix.`,{hint:o})}}function ke(e,t){let n=E(e);if(n)return{ok:!0,target:{kind:`point`,x:n.x,y:n.y}};let r=e[0]??``;if(r.startsWith(`@`)){let t=j(r);return t.ok?{ok:!0,target:{kind:`ref`,ref:t.ref,fallbackLabel:e.slice(1).join(` `).trim()},refGeneration:t.generation}:{ok:!1,response:t.response}}let i=e.join(` `).trim();return i?{ok:!0,target:{kind:`selector`,selector:i}}:{ok:!1,response:_(`INVALID_ARGS`,`${t} requires @ref, selector expression, or x y coordinates`)}}function Ae(e){let t=E(e);if(t)return{ok:!0,target:{kind:`point`,x:t.x,y:t.y},...Le(e[2])};let n=Ie(e),r=ke(n.targetPositionals,`longpress`);return r.ok?{ok:!0,target:r.target,refGeneration:r.refGeneration,...n.duration}:r}function je(e){let t=e[0]??``;if(t.startsWith(`@`)){let n=j(t);if(!n.ok)return{ok:!1,response:n.response};let r=m(e).text;return r?{ok:!0,target:{kind:`ref`,ref:n.ref,fallbackLabel:Fe(e)},refGeneration:n.generation,text:r}:{ok:!1,response:_(`INVALID_ARGS`,`fill requires text after ref`)}}let n=E(e);if(n){let t=e.slice(2).join(` `);return t?{ok:!0,target:{kind:`point`,x:n.x,y:n.y},text:t}:{ok:!1,response:_(`INVALID_ARGS`,`fill requires text after coordinates`)}}let r=Me(e);return!r||r.kind!==`selector`?{ok:!1,response:_(`INVALID_ARGS`,`fill requires x y text, @ref text, or selector text`)}:r.text.trim()?{ok:!0,target:{kind:`selector`,selector:r.target.selector},text:r.text}:{ok:!1,response:_(`INVALID_ARGS`,`fill requires text after selector`)}}function Me(e){try{return m(e)}catch{return null}}function Ne(e){let t=`evidence`in e?e.evidence:void 0,n=e.settle;return e.kind===`ref`?{ref:M(e.target?.kind===`ref`?e.target.ref:void 0),refLabel:e.refLabel,selectorChain:e.selectorChain,targetHittable:e.targetHittable,hint:e.hint,evidence:t,settle:n}:e.kind===`selector`?{selector:e.target?.kind===`selector`?e.target.selector:void 0,selectorChain:e.selectorChain,refLabel:e.refLabel,targetHittable:e.targetHittable,hint:e.hint,evidence:t,settle:n}:{evidence:t,settle:n}}function Pe(e,t){return e.kind===`point`?`coordinate tap`:t.kind===`ref`&&t.target?.kind===`ref`?t.target.ref:t.kind===`selector`&&t.target?.kind===`selector`?t.target.selector:`target`}function M(e){return e?.startsWith(`@`)?e.slice(1):e}function Fe(e){return e.length>=3&&e[1]?.trim()||``}function Ie(e){let t=e.at(-1);return e.length>1&&Re(t)?{targetPositionals:e.slice(0,-1),duration:{durationMs:Number(t)}}:{targetPositionals:e,duration:{}}}function Le(e){return e===void 0?{}:{durationMs:Number(e)}}function Re(e){return e===void 0||e.trim()===``?!1:Number.isFinite(Number(e))}async function ze(e,t){let r=await N(e);if(r)throw new n(`COMMAND_FAILED`,`press ${t} left ${e.appBundleId} and foregrounded ${r.foregroundPackage}. The tap likely escaped the app.`,r)}async function N(e){if(e.device.platform!==`android`||!e.appBundleId)return null;let t=await pe(e.device),n=t.package?.trim();return!n||n===e.appBundleId||!Ue(n)?null:{expectedPackage:e.appBundleId,foregroundPackage:n,activity:t.activity,hint:He(n)}}function Be(e){return e.foregroundPackage===`com.google.android.permissioncontroller`?`Android permission dialog is blocking ${e.expectedPackage}`:`${e.foregroundPackage} is foreground instead of ${e.expectedPackage}`}function Ve(e){return e.code===`COMMAND_FAILED`&&typeof e.details?.expectedPackage==`string`&&typeof e.details?.foregroundPackage==`string`}function He(e){return e===`com.google.android.permissioncontroller`?`Dismiss or allow the permission prompt, then retry the smoke assertion.`:`Use screenshot as visual truth, then take a fresh snapshot -i before retrying.`}function Ue(e){return e===`com.android.settings`||e===`com.android.systemui`||e===`com.google.android.permissioncontroller`||e.includes(`launcher`)}function We(e,t){if(t===`exists`)return{found:!0};if(t===`wait`)return{found:!0,waitedMs:e.waitedMs};let n=typeof e.ref==`string`?e.ref:void 0;return t===`get_attrs`?{ref:n,action:`get attrs`}:{ref:n,action:`get text`,text:typeof e.text==`string`?e.text:``}}function Ge(e){return e.kind===`found`?{found:!0,...typeof e.waitedMs==`number`?{waitedMs:e.waitedMs}:{}}:{...typeof e.ref==`string`?{ref:e.ref}:{},...typeof e.text==`string`?{text:e.text}:{},...e.node&&typeof e.node==`object`?{node:e.node}:{}}}function P(e,t){let n=Array.isArray(e.selectorChain)?e.selectorChain:void 0,r=R(e),i=r?.kind===`ref`?z(r.ref):void 0,a=r?.kind===`selector`?r.selector:void 0,o={...i?{ref:i}:{},...a?{selector:a}:{},...n?{selectorChain:n}:{}};if(t===`attrs`)return o;let s=typeof e.text==`string`?e.text:``;return{...o,text:s,refLabel:qe(s)}}function F(e){let t=R(e);return{...t?.kind===`ref`?{ref:z(t.ref)}:{},...t?.kind===`selector`?{selector:t.selector}:{},...typeof e.text==`string`?{text:e.text}:{},...e.node&&typeof e.node==`object`?{node:e.node}:{}}}function Ke(e){return{waitedMs:e.waitedMs,...typeof e.text==`string`?{text:e.text}:{},...typeof e.selector==`string`?{selector:e.selector}:{},...typeof e.captures==`number`?{captures:e.captures}:{},...typeof e.nodeCount==`number`?{nodeCount:e.nodeCount}:{},...typeof e.hint==`string`?{hint:e.hint}:{}}}function I(e){let{selectorChain:t,...n}=e;return n}function L(e,t,n,r){let i=e.get(t);i&&e.recordAction(i,{command:n.command,positionals:n.positionals??[],flags:n.flags??{},result:r})}function qe(e){let t=e.trim();if(!(!t||t.length>80||/[\r\n]/.test(t)))return t}function R(e){let t=e.target;if(!t||typeof t!=`object`)return;let n=t;if(n.kind===`ref`&&typeof n.ref==`string`)return{kind:`ref`,ref:n.ref};if(n.kind===`selector`&&typeof n.selector==`string`)return{kind:`selector`,selector:n.selector}}function z(e){return e.startsWith(`@`)?e.slice(1):e}const Je=[`application`,`window`,`tabbar`,`scrollbar`,`image`],Ye=new Set([`tab bar`]);async function B(e,t){if(t.ok||!Xe(t.error.message)||t.error.details?.captureStalled===!0)return t;let n=await Ze(e).catch(()=>null);return n?_(t.error.code,`${t.error.message}. Current surface: ${n.summary}.`,{...t.error.details??{},currentSurface:n.details}):t}function Xe(e){return/^wait timed out (?:for (?:selector|text): |waiting for a stable UI)/i.test(e)}async function Ze(e){let t=[...(await b({device:e.device,session:e.session,flags:{...e.req.flags,snapshotInteractiveOnly:!0},logPath:e.logPath??``})).snapshot.nodes].sort(Qe),n=V(t,6,{includeIdentifiers:!0});if(n.length===0)return null;let r=V(t.filter(e=>!W(e)),4,{includeIdentifiers:!1}),i=V(t.filter(et),4,{includeIdentifiers:!0});return{summary:(r.length>0?r:n.slice(0,4)).join(`, `),details:{labels:n,...i.length>0?{buttons:i}:{}}}}function V(e,t,n){let r=new Set,i=[];for(let a of e){let e=U(a,n);if(!(!e||r.has(e))&&(r.add(e),i.push(e),i.length>=t))break}return i}function Qe(e,t){return H(e)-H(t)||$e(e,t)}function H(e){let t=!!U(e,{includeIdentifiers:!1});return(W(e)?2:0)+ +!t}function $e(e,t){return e.rect&&t.rect?e.rect.y-t.rect.y||e.rect.x-t.rect.x:e.rect?-1:t.rect?1:(e.depth??0)-(t.depth??0)||e.index-t.index}function U(e,t){let n=(t.includeIdentifiers?[e.label,e.value,e.identifier]:[e.label,e.value]).map(e=>typeof e==`string`?e.trim():``).find(e=>e.length>0);return n?n.replace(/\s+/g,` `).slice(0,80):``}function W(e){let t=h(`${e.type??``} ${e.role??``} ${e.subrole??``}`),n=`${e.label??``} ${e.value??``}`.trim().toLowerCase();return Je.some(e=>t.includes(e))||Ye.has(n)||n.endsWith(`.fill`)}function et(e){return h(`${e.type??``} ${e.role??``} ${e.subrole??``}`).includes(`button`)}function G(e){let{session:t,selectorExpression:n}=e;if(!t||!u(t.device)||t.postGestureStabilization)return null;let r=f(n);if(!r||r.selectors.length!==1)return null;let i=r.selectors[0];if(!i||i.terms.length!==1)return null;let a=i.terms[0];return!a||typeof a.value!=`string`||!tt(a.key)?null:{key:a.key,value:a.value,raw:i.raw}}function tt(e){return e===`id`||e===`label`||e===`text`||e===`value`}function K(e,t={}){let n=r(e);if(n.code===`ELEMENT_NOT_FOUND`)return t.delegateSemanticFailures===!0||t.allowElementNotFound===!0;if(n.code===`AMBIGUOUS_MATCH`)return t.delegateSemanticFailures===!0;if(n.code===`ELEMENT_OFFSCREEN`)return!0;if(n.code!==`COMMAND_FAILED`)return!1;let i=n.message.toLowerCase();return i.includes(`fetch failed`)||i.includes(`timed out`)||i.includes(`timeout`)||i.includes(`runner did not accept connection`)||i.includes(`invalid runner response`)}function nt(e,t={}){let r=t.plural===!0?`do`:`does`;return{resolveInput:async()=>{throw new n(`UNSUPPORTED_OPERATION`,`${e} ${r} not resolve input artifacts`)},reserveOutput:async()=>{throw new n(`UNSUPPORTED_OPERATION`,`${e} ${r} not reserve output artifacts`)},createTempFile:async()=>{throw new n(`UNSUPPORTED_OPERATION`,`${e} ${r} not create temporary files`)}}}function rt(e,t={}){return{artifacts:nt(e,t),policy:de()}}function q(e){let{session:t,sessionStore:n,sessionName:r}=e,i=0,a,o;return{capture:async s=>{let c=Date.now(),l=pt(s,e.req.flags?.out),u=st({timestamp:c,lastSnapshotAt:i,lastSnapshotResult:a,lastSnapshotCacheKey:o,session:t,request:s,cacheKey:l});if(u)return u;let d=ct({session:t,timestamp:c,request:s});if(d)return i=d.createdAt,a={snapshot:d},o=l,a;let f=await it({params:e,request:s}),p={snapshot:f};return ht({session:t,sessionStore:n,sessionName:r,snapshot:f}),i=c,a=p,o=l,p}}}async function it(e){let{params:t,request:n}=e,r=await J(t,n,n.snapshotScope);return n.recovery?.legacyIosSparse&&gt(r)?await at({runtimeParams:t,request:n,policy:n.recovery.legacyIosSparse}):n.recovery?.sparseVerdictQueryScope?.shouldScope&&le(r.snapshotQuality)?await ot({runtimeParams:t,request:n,policy:n.recovery.sparseVerdictQueryScope,snapshot:r}):r}async function at(e){let{runtimeParams:t,request:n,policy:r}=e;try{return await J(t,n,r.scope,!1)}catch(e){if(!r.shouldScope)throw e;return await J(t,n,r.query,!1)}}async function ot(e){let{runtimeParams:t,request:n,policy:r,snapshot:i}=e;try{return await J(t,n,r.query,!1)}catch{return i}}async function J(e,t,n,r=t.flags?.snapshotInteractiveOnly){return(await b({device:e.device,session:e.session,flags:{...t.flags,snapshotInteractiveOnly:r},outPath:t.outPath??e.req.flags?.out,logPath:e.logPath??``,snapshotScope:n,includeRects:t.includeRects})).snapshot}function st(e){let{timestamp:t,lastSnapshotAt:n,lastSnapshotResult:r,lastSnapshotCacheKey:i,session:a,request:o,cacheKey:s}=e;if(o.cache?.forceFresh!==!0&&r&&i===s&&!(t-n>=750)&&!v(a)&&!dt(a,o))return r}function ct(e){let{session:t,timestamp:n,request:r}=e,i=t?.snapshot;if(i&&lt(t,r)&&ut(i,n)&&i.presentationKey===ft(r))return i}function lt(e,t){return!(t.cache?.forceFresh===!0||t.cache?.useSessionSnapshot!==!0||v(e)||dt(e,t))}function ut(e,t){return t-e.createdAt<750}function dt(e,t){return t.cache?.bypassForPostGestureStabilization===!0&&!!e?.postGestureStabilization}function ft(e){return t(i(mt(e)))}function pt(e,t){return JSON.stringify({presentationKey:ft(e),includeRects:e.includeRects===!0,outPath:e.outPath??t??null})}function mt(e){return e.snapshotScope===void 0?e.flags:{...e.flags,snapshotScope:e.snapshotScope}}function ht(e){let{session:t,sessionStore:n,sessionName:r,snapshot:i}=e;!t||le(i.snapshotQuality)||(y(t,i),n.set(r,t))}function gt(e){return e.snapshotQuality||e.backend!==`xctest`||e.nodes.length!==1?!1:e.nodes[0]?.type===`Application`}function _t(e){return fe({backend:vt(e),...rt(`selector commands`,{plural:!0}),sessions:_e({sessionName:e.sessionName,getSession:()=>e.session,recordOptions:{includeSnapshot:!0},setRecord:t=>{!e.session||!t.snapshot||(y(e.session,t.snapshot),e.sessionStore.set(e.sessionName,e.session))}})})}async function Y(e,t){let n=e.sessionStore.get(e.sessionName);if(!n&&t.requireSession)return{ok:!1,response:ve()};let r=n?.device??await S(e.req.flags??{});n||await w(r);let i=C(t.capability,r);return i?{ok:!1,response:i}:{ok:!0,runtime:_t({...e,session:n,device:r})}}function vt(e){let{req:t,session:n,device:r,logPath:i,sessionName:a,sessionStore:o}=e,c=q({device:r,session:n,sessionStore:o,sessionName:a,req:t,logPath:i});return{platform:s(r),captureSnapshot:async(e,n)=>{let i={...t.flags,...yt(n)},a=n?.includeRects===!0,o=n?.scope??t.flags?.snapshotScope,s=t.command===`wait`||t.command===`find`||a&&r.platform===`web`;return await c.capture({flags:i,snapshotScope:o,includeRects:a,cache:{forceFresh:s,useSessionSnapshot:!0,bypassForPostGestureStabilization:!0}})},readText:async(a,o)=>({text:await D({device:r,node:o,flags:t.flags,appBundleId:n?.appBundleId,traceOutPath:n?.trace?.outPath,surface:n?.surface,contextFromFlags:e.contextFromFlags??((e,t,n)=>be(i??``,e,t,n))})}),findText:async(t,n)=>({found:await bt(e,n)})}}function yt(e){let t={};return e?.interactiveOnly!==void 0&&(t.snapshotInteractiveOnly=e.interactiveOnly),e?.scope!==void 0&&(t.snapshotScope=e.scope),e?.depth!==void 0&&(t.snapshotDepth=e.depth),e?.raw!==void 0&&(t.snapshotRaw=e.raw),t}async function bt(e,t){let n=await xt(e,t);if(n!==null)return n;let r=await St(e,t);return r===null?await Tt(e,t):r}async function xt(e,t){return!l(e.device)||!e.session?.surface||e.session.surface===`app`?null:await Tt(e,t)}async function St(e,t){let n=Ct(e);return n?(await g(n.device,{command:`findText`,text:t,appBundleId:n.appBundleId},wt(e,n)))?.found===!0:null}function Ct(e){return!c(e.device.platform)||!e.session?.appBundleId?null:{device:e.device,appBundleId:e.session.appBundleId,traceLogPath:e.session.trace?.outPath}}function wt(e,t){return T({req:e.req,logPath:e.logPath,traceLogPath:t.traceLogPath})}async function Tt(e,t){return!!ie((await Et(e)).nodes,t)}async function Et(e){let{snapshot:t}=await q({device:e.device,session:e.session,sessionStore:e.sessionStore,sessionName:e.sessionName,req:e.req,logPath:e.logPath}).capture({flags:{...e.req.flags,snapshotInteractiveOnly:!1},cache:{forceFresh:!0,bypassForPostGestureStabilization:!0}});return t}async function Dt(e){let{req:t}=e;if(t.command!==`find`)return null;let n=t.positionals??[];if(n.length===0)return _(`INVALID_ARGS`,`find requires a locator or text`);let r=ue(n);if(!r.query)return _(`INVALID_ARGS`,`find requires a value`);if(t.flags?.findFirst&&t.flags?.findLast)return _(`INVALID_ARGS`,`find accepts only one of --first or --last`);let i=r.action;if(!Vt(i))return null;let a=await Y(e,{requireSession:!1,capability:`find`});return a.ok?await Q(async()=>{let n=await a.runtime.selectors.find({session:e.sessionName,requestId:t.meta?.requestId,locator:r.locator,query:r.query,action:i,timeoutMs:r.timeoutMs});L(e.sessionStore,e.sessionName,t,We(n,i));let o=Ge(n);if(typeof o.ref==`string`){let t=e.sessionStore.get(e.sessionName);if(t&&(ye(t),e.sessionStore.set(e.sessionName,t),t.snapshotGeneration!==void 0))return{...o,refsGeneration:t.snapshotGeneration}}return o}):a.response}async function Ot(e){let{req:t}=e;if(t.command!==`get`)return null;let n=t.positionals?.[0];if(n!==`text`&&n!==`attrs`)return _(`INVALID_ARGS`,`get only supports text or attrs`);let r=zt(t);if(!r.ok)return r.response;if(r.target.kind===`ref`){let e=A(`get`,t.flags);if(e)return e}if(r.target.kind===`selector`){let t=await jt(e,n,r.target.selector);if(t)return t}let i=await Y(e,{requireSession:!0,capability:`get`});if(!i.ok)return i.response;let a=r.target.kind===`ref`?x({session:e.sessionStore.get(e.sessionName),ref:r.target.ref,mintedGeneration:r.refGeneration}):void 0;return await Q(async()=>{let o=await i.runtime.selectors.get({session:e.sessionName,requestId:t.meta?.requestId,property:n,target:r.target});L(e.sessionStore,e.sessionName,t,P(o,n));let s=F(o);return a?{...s,warning:a}:s})}async function kt(e){let{req:t}=e;if(t.command!==`is`)return null;let{predicate:n,split:r}=se(t.positionals??[]),i=n.toLowerCase();if(!ne(i))return _(`INVALID_ARGS`,ae,{hint:oe});if(!r)return _(`INVALID_ARGS`,`is requires a selector expression`);let a=r.rest.join(` `).trim();if(i===`text`&&!a)return _(`INVALID_ARGS`,`is text requires expected text value`);if(i!==`text`&&r.rest.length>0)return _(`INVALID_ARGS`,`is ${i} does not accept trailing values`);let o=await Mt(e,i,r.selectorExpression,a);if(o)return o;let s=await Y(e,{requireSession:!0,capability:`is`});return s.ok?await $(e,await Q(async()=>{let n=await s.runtime.selectors.is({session:e.sessionName,requestId:t.meta?.requestId,predicate:i,selector:r.selectorExpression,expectedText:a});return L(e.sessionStore,e.sessionName,t,n),I(n)}),`is ${i}`):s.response}async function At(e){let{req:t,sessionName:n,sessionStore:r}=e,i=p(t.positionals??[]);if(!i)return _(`INVALID_ARGS`,`wait requires a duration or text`);let{session:a,device:o}=await O(r,n,t.flags);if(i.kind!==`sleep`){let e=C(`wait`,o);if(e)return e}if(i.kind===`selector`){let t=await Nt({...e,session:a,device:o,selectorExpression:i.selectorExpression,timeoutMs:i.timeoutMs});if(t)return t}let s=i,c;if(i.kind===`ref`){let e=j(i.rawRef);if(!e.ok)return e.response;s={...i,rawRef:e.ref},c=x({session:a,ref:e.ref,mintedGeneration:e.generation})}let l=async()=>{let i=_t({...e,session:a,device:o}),l=await Q(async()=>{let e=await i.selectors.wait({session:n,requestId:t.meta?.requestId,target:Bt(s,a)});L(r,n,t,e);let o=Ke(e);return c?{...o,warning:c}:o});return await $(e,await B({req:t,logPath:e.logPath,session:a,device:o},l),`wait`)};return i.kind===`sleep`?await l():await k(a,o,l)}async function jt(e,t,n){let r=e.sessionStore.get(e.sessionName),i=G({session:r,selectorExpression:n});if(!r||!i||t===`text`&&i.key!==`id`)return null;let a=await X(e,r,i);if(Z(a))return a.response;if(!a)return null;let o={session:r,selector:i,result:a},s=It(t,o.selector.raw,o.result);return s?(L(e.sessionStore,e.sessionName,e.req,P(s,t)),{ok:!0,data:F(s)}):null}async function Mt(e,t,n,r){if(t===`hidden`)return null;let i=await Pt(e,n);if(Z(i))return i.response;if(!i?.result.found||!i.result.node)return null;let a=t===`exists`?{predicate:t,pass:!0,selector:i.selector.raw,matches:1,selectorChain:[i.selector.raw]}:Lt(t,r,i.selector.raw,i.session,i.result.node);return a?(L(e.sessionStore,e.sessionName,e.req,a),{ok:!0,data:I(a)}):null}async function Nt(e){let t=G({session:e.session,selectorExpression:e.selectorExpression});if(!e.session||!t)return null;let n=Date.now(),r=await X(e,e.session,t);if(Z(r))return r.response;if(!r?.found)return null;let i={kind:`selector`,selector:t.raw,waitedMs:Date.now()-n,selectorChain:[t.raw]};L(e.sessionStore,e.sessionName,e.req,i);let a={ok:!0,data:I(i)};return await B({req:e.req,logPath:e.logPath,session:e.session,device:e.device},a)}async function Pt(e,t){let n=e.sessionStore.get(e.sessionName),r=G({session:n,selectorExpression:t});if(!n||!r)return null;let i=await X(e,n,r);return Z(i)?i:i?{session:n,selector:r,result:i}:null}async function Ft(e,t,n){let r=await g(t.device,{command:`querySelector`,selectorKey:n.key,selectorValue:n.value,appBundleId:t.appBundleId},T({req:e.req,logPath:e.logPath,traceLogPath:t.trace?.outPath})),i=r.found===!0,a=Rt(r);return{found:i,...typeof r.text==`string`?{text:r.text}:{},...a?{node:a}:{}}}async function X(t,n,r){try{return await Ft(t,n,r)}catch(t){return K(t,{allowElementNotFound:!0})?null:{kind:`error`,response:{ok:!1,error:e(t)}}}}function Z(e){return e!==null&&`kind`in e&&e.kind===`error`}function It(e,t,n){if(!n.found||!n.node)return null;let r={target:{kind:`selector`,selector:t},node:n.node,selectorChain:[t]};return e===`attrs`?{kind:`attrs`,...r}:typeof n.text==`string`?{kind:`text`,...r,text:n.text}:null}function Lt(e,t,n,r,i){let a=re({predicate:e,node:i,nodes:[i],expectedText:t,platform:r.device.platform});return{predicate:e,pass:a.pass,selector:n,...e===`text`?{text:a.actualText}:{},selectorChain:[n]}}function Rt(e){let t=e.nodes;if(!Array.isArray(t))return;let n=t[0];if(!(!n||typeof n!=`object`))return n}function zt(e){let t=e.positionals?.[1]??``;if(t.startsWith(`@`)){let n=j(t);return n.ok?{ok:!0,target:{kind:`ref`,ref:n.ref,fallbackLabel:e.positionals.length>2?e.positionals.slice(2).join(` `).trim():``},refGeneration:n.generation}:{ok:!1,response:n.response}}let n=e.positionals?.slice(1).join(` `).trim()??``;return n?{ok:!0,target:{kind:`selector`,selector:n}}:{ok:!1,response:_(`INVALID_ARGS`,`get requires @ref or selector expression`)}}function Bt(e,t){if(e.kind===`sleep`)return{kind:`sleep`,durationMs:e.durationMs};if(e.kind===`selector`)return{kind:`selector`,selector:e.selectorExpression,timeoutMs:e.timeoutMs};if(e.kind===`ref`){if(!t?.snapshot)throw new n(`INVALID_ARGS`,`Ref wait requires an existing snapshot in session.`);return{kind:`ref`,ref:e.rawRef,timeoutMs:e.timeoutMs}}if(e.kind===`stable`)return{kind:`stable`,quietMs:e.quietMs,timeoutMs:e.timeoutMs};if(!e.text)throw new n(`INVALID_ARGS`,`wait requires text`);return{kind:`text`,text:e.text,timeoutMs:e.timeoutMs}}async function Q(e){try{return{ok:!0,data:await e()}}catch(e){let t=r(e);return _(t.code,t.message,t.details)}}async function $(e,t,n){if(t.ok)return t;let r=e.sessionStore.get(e.sessionName);if(!r)return t;let i;try{i=await N(r)}catch{return t}return i?_(t.error.code,`${n} failed because ${Be(i)}.`,{...t.error.details??{},...i,blockedBy:`android_foreground_surface`,originalMessage:t.error.message}):t}function Vt(e){return e===`exists`||e===`wait`||e===`get_text`||e===`get_attrs`}export{k as C,O as S,Oe as _,q as a,we as b,G as c,Pe as d,Ne as f,M as g,ke as h,At as i,ze as l,Ae as m,Ot as n,rt as o,je as p,kt as r,K as s,Dt as t,Ve as u,A as v,D as w,Ce as x,De as y};
@@ -1,6 +1,5 @@
1
1
  import { S as SnapshotNode, V as PublicPlatform, w as SnapshotState, z as Platform } from "./sdk-contracts.js";
2
2
  import { a as Selector, c as parseSelectorChain, l as tryParseSelectorChain, o as SelectorChain, s as isSelectorToken } from "./sdk-finders.js";
3
-
4
3
  //#region src/daemon/selectors-resolve.d.ts
5
4
  type SelectorDiagnostics = {
6
5
  selector: string;
@@ -1 +1 @@
1
- import{_ as e,g as t,y as n}from"./sdk-batch.js";import{c as r,s as i}from"./sdk-selectors.js";import{a,i as o,r as s}from"./selectors2.js";export{s as findSelectorChainMatch,o as formatSelectorFailure,i as isNodeEditable,r as isNodeVisible,t as isSelectorToken,e as parseSelectorChain,a as resolveSelectorChain,n as tryParseSelectorChain};
1
+ import{S as e,b as t,y as n}from"./sdk-batch.js";import{c as r,s as i}from"./sdk-selectors.js";import{a,i as o,r as s}from"./selectors2.js";export{s as findSelectorChainMatch,o as formatSelectorFailure,i as isNodeEditable,r as isNodeVisible,n as isSelectorToken,t as parseSelectorChain,a as resolveSelectorChain,e as tryParseSelectorChain};
@@ -1 +1 @@
1
- import{C as e,N as t,R as n,c as r,d as i,s as a}from"./sdk-selectors.js";import{i as o}from"./sdk-finders.js";function s(e,t,n){return t.terms.every(t=>c(e,t,n))}function c(e,n,o){switch(n.key){case`id`:return l(e.identifier,String(n.value));case`role`:return l(t(e.type??``),String(n.value));case`label`:return l(e.label,String(n.value));case`value`:return l(e.value,String(n.value));case`text`:return l(i(e),String(n.value));case`appname`:return l(e.appName,String(n.value));case`windowtitle`:return l(e.windowTitle,String(n.value));case`visible`:return r(e)===!!n.value;case`hidden`:return!r(e)==!!n.value;case`editable`:return a(e,o)===!!n.value;case`selected`:return e.selected===!0==!!n.value;case`enabled`:return e.enabled!==!1==!!n.value;case`hittable`:return e.hittable===!0==!!n.value;default:return!1}}function l(e,t){return o(e??``)===o(t)}function u(e,t,n){let r=n.requireRect??!1,i=n.requireUnique??!0,a=[];for(let[o,s]of t.selectors.entries()){let t=h(e,s,n.platform,r);if(a.push({selector:s.raw,matches:t.count}),!(t.count===0||!t.firstNode)){if(i&&t.count!==1){if(!n.disambiguateAmbiguous||!t.disambiguated)continue;return{node:t.disambiguated,selector:s,selectorIndex:o,matches:t.count,diagnostics:a}}return{node:t.firstNode,selector:s,selectorIndex:o,matches:t.count,diagnostics:a}}}return null}function d(e,t,n){let r=n.requireRect??!1,i=[];for(let[a,o]of t.selectors.entries()){let t=_(e,o,n.platform,r);if(i.push({selector:o.raw,matches:t}),t>0)return{selectorIndex:a,selector:o,matches:t,diagnostics:i}}return null}const f=`Snapshot refs expire when the UI changes. Run snapshot -i and retry with a fresh @ref.`;function p(e){return e.some(e=>e.matches>1)?`Add more terms to disambiguate (e.g. role=button text="Sign in"), use an @ref from snapshot -i, or use find <text> --first/--last.`:`Selector text/label values match exactly (quote multi-word values: text="Sign in"). Run snapshot -i to see current elements and refs, or use find <text> for contains matching.`}function m(e,t,n){if(t.length===0)return`Selector did not match: ${e.raw}`;let r=t.map(e=>`${e.selector} -> ${e.matches}`).join(`, `);return n.unique??!0?`Selector did not resolve uniquely (${r})`:`Selector did not match (${r})`}function h(t,r,i,a){let o=0,c=null,l={best:null,bestVisible:!1,tie:!1},u,d=r=>(u??=n(t),e(r,t,u));for(let e of t)a&&!e.rect||s(e,r,i)&&(o+=1,c??=e,g(l,e,d));return{count:o,firstNode:c,disambiguated:l.tie?null:l.best}}function g(e,t,n){if(!e.best){e.best=t;return}e.bestVisible||=n(e.best);let r=n(t);if(r!==e.bestVisible){r&&(e.best=t,e.bestVisible=!0,e.tie=!1);return}let i=v(t,e.best);i>0?(e.best=t,e.tie=!1):i===0&&(e.tie=!0)}function _(e,t,n,r){let i=0;for(let a of e)r&&!a.rect||s(a,t,n)&&(i+=1);return i}function v(e,t){let n=e.depth??0,r=t.depth??0;if(n!==r)return n>r?1:-1;let i=y(e),a=y(t);return i===a?0:i<a?1:-1}function y(e){return e.rect?e.rect.width*e.rect.height:1/0}function b(e,n,a={}){let o=[],s=t(e.type??``),c=C(e.identifier),l=C(e.label),u=C(e.value),d=C(i(e)),f=a.action===`fill`;c&&o.push(`id=${S(c)}`),s&&l&&o.push(f?`role=${S(s)} label=${S(l)} editable=true`:`role=${S(s)} label=${S(l)}`),l&&o.push(f?`label=${S(l)} editable=true`:`label=${S(l)}`),u&&o.push(f?`value=${S(u)} editable=true`:`value=${S(u)}`),d&&d!==l&&d!==u&&o.push(f?`text=${S(d)} editable=true`:`text=${S(d)}`),s&&f&&!o.some(e=>e.includes(`editable=true`))&&o.push(`role=${S(s)} editable=true`);let p=x(o);return p.length===0&&s&&p.push(f?`role=${S(s)} editable=true`:`role=${S(s)}`),p.length===0&&r(e)&&p.push(`visible=true`),p}function x(e){return Array.from(new Set(e))}function S(e){return JSON.stringify(e)}function C(e){return e&&e.trim()||null}export{u as a,m as i,f as n,p as o,d as r,s,b as t};
1
+ import{C as e,N as t,R as n,c as r,d as i,s as a}from"./sdk-selectors.js";import{i as o}from"./sdk-finders.js";function s(e,t,n){return t.terms.every(t=>c(e,t,n))}function c(e,n,o){switch(n.key){case`id`:return l(e.identifier,String(n.value));case`role`:return l(t(e.type??``),String(n.value));case`label`:return l(e.label,String(n.value));case`value`:return l(e.value,String(n.value));case`text`:return l(i(e),String(n.value));case`appname`:return l(e.appName,String(n.value));case`windowtitle`:return l(e.windowTitle,String(n.value));case`visible`:return r(e)===!!n.value;case`hidden`:return!r(e)==!!n.value;case`editable`:return a(e,o)===!!n.value;case`selected`:return e.selected===!0==!!n.value;case`focused`:return e.focused===!0==!!n.value;case`enabled`:return e.enabled!==!1==!!n.value;case`hittable`:return e.hittable===!0==!!n.value;default:return!1}}function l(e,t){return o(e??``)===o(t)}function u(e,t,n){let r=n.requireRect??!1,i=n.requireUnique??!0,a=[];for(let[o,s]of t.selectors.entries()){let t=h(e,s,n.platform,r);if(a.push({selector:s.raw,matches:t.count}),!(t.count===0||!t.firstNode)){if(i&&t.count!==1){if(!n.disambiguateAmbiguous||!t.disambiguated)continue;return{node:t.disambiguated,selector:s,selectorIndex:o,matches:t.count,diagnostics:a}}return{node:t.firstNode,selector:s,selectorIndex:o,matches:t.count,diagnostics:a}}}return null}function d(e,t,n){let r=n.requireRect??!1,i=[];for(let[a,o]of t.selectors.entries()){let t=_(e,o,n.platform,r);if(i.push({selector:o.raw,matches:t}),t>0)return{selectorIndex:a,selector:o,matches:t,diagnostics:i}}return null}const f=`Snapshot refs expire when the UI changes. Run snapshot -i and retry with a fresh @ref.`;function p(e){return e.some(e=>e.matches>1)?`Add more terms to disambiguate (e.g. role=button text="Sign in"), use an @ref from snapshot -i, or use find <text> --first/--last.`:`Selector text/label values match exactly (quote multi-word values: text="Sign in"). Run snapshot -i to see current elements and refs, or use find <text> for contains matching.`}function m(e,t,n){if(t.length===0)return`Selector did not match: ${e.raw}`;let r=t.map(e=>`${e.selector} -> ${e.matches}`).join(`, `);return n.unique??!0?`Selector did not resolve uniquely (${r})`:`Selector did not match (${r})`}function h(t,r,i,a){let o=0,c=null,l={best:null,bestVisible:!1,tie:!1},u,d=r=>(u??=n(t),e(r,t,u));for(let e of t)a&&!e.rect||s(e,r,i)&&(o+=1,c??=e,g(l,e,d));return{count:o,firstNode:c,disambiguated:l.tie?null:l.best}}function g(e,t,n){if(!e.best){e.best=t;return}e.bestVisible||=n(e.best);let r=n(t);if(r!==e.bestVisible){r&&(e.best=t,e.bestVisible=!0,e.tie=!1);return}let i=v(t,e.best);i>0?(e.best=t,e.tie=!1):i===0&&(e.tie=!0)}function _(e,t,n,r){let i=0;for(let a of e)r&&!a.rect||s(a,t,n)&&(i+=1);return i}function v(e,t){let n=e.depth??0,r=t.depth??0;if(n!==r)return n>r?1:-1;let i=y(e),a=y(t);return i===a?0:i<a?1:-1}function y(e){return e.rect?e.rect.width*e.rect.height:1/0}function b(e,n,a={}){let o=[],s=t(e.type??``),c=C(e.identifier),l=C(e.label),u=C(e.value),d=C(i(e)),f=a.action===`fill`;c&&o.push(`id=${S(c)}`),s&&l&&o.push(f?`role=${S(s)} label=${S(l)} editable=true`:`role=${S(s)} label=${S(l)}`),l&&o.push(f?`label=${S(l)} editable=true`:`label=${S(l)}`),u&&o.push(f?`value=${S(u)} editable=true`:`value=${S(u)}`),d&&d!==l&&d!==u&&o.push(f?`text=${S(d)} editable=true`:`text=${S(d)}`),s&&f&&!o.some(e=>e.includes(`editable=true`))&&o.push(`role=${S(s)} editable=true`);let p=x(o);return p.length===0&&s&&p.push(f?`role=${S(s)} editable=true`:`role=${S(s)}`),p.length===0&&r(e)&&p.push(`visible=true`),p}function x(e){return Array.from(new Set(e))}function S(e){return JSON.stringify(e)}function C(e){return e&&e.trim()||null}export{u as a,m as i,f as n,p as o,d as r,s,b as t};
@@ -1,3 +1,3 @@
1
- import{B as e,F as t,c as n,n as r,o as i,s as a}from"./sdk-contracts.js";import{n as o}from"./version.js";import{Wt as s,t as c}from"./device-rotation.js";import{A as l,j as u,k as d,s as f}from"./registry.js";import{i as p,n as m}from"./command-metadata.js";import{t as ee}from"./cli-output.js";const h=[`simulator`,`emulator`,`device`];function g(e){return{type:`number`,...e?{description:e}:{}}}function _(e,t){return{type:`string`,enum:e,...t?{description:t}:{}}}function v(e){return{type:`string`,const:e}}function y(e,t=[],n){return{type:`object`,...n?{description:n}:{},properties:e,...t.length>0?{required:t}:{}}}const te={type:`array`,items:{type:`string`}};function b(e={}){let t=e.properties??{},n=e.required??[];return y({targetKind:_([`point`,`ref`,`selector`],`Resolved interaction target kind.`),x:g(`Resolved interaction x coordinate when available.`),y:g(`Resolved interaction y coordinate when available.`),referenceWidth:g(`Reference frame width for visualizing the interaction point.`),referenceHeight:g(`Reference frame height for visualizing the interaction point.`),ref:u(`Snapshot ref without the @ prefix when the target was an @ref.`),selector:u(`Selector expression when the target was a selector.`),selectorChain:te,refLabel:u(),targetHittable:d(),hint:u(),warning:u(),message:u(),evidence:x,...t},[`targetKind`,...n])}const x=y({foregroundApp:u(`Foreground app bundle id or name, when the capture carries it.`),nodeCount:g(`Node count in the post-action interactive-only capture.`),interactiveNodeCount:g(`Subset of nodeCount the platform reports as hittable.`),digest:u(`Order-independent digest of the post-action node multiset.`),changedFromBefore:d(`Whether the post-action digest differs from the pre-action capture digest. false is evidence, not failure.`)},[`nodeCount`,`interactiveNodeCount`,`digest`,`changedFromBefore`]),S=y({settled:d(`Whether the UI held the quiet window before the deadline. false is advisory, not failure.`),waitedMs:g(),captures:g(),quietMs:g(),timeoutMs:g(),refsGeneration:g(`Snapshot generation of the stored settled tree; refs on added diff lines were minted from it.`),refs:{type:`array`,items:y({ref:u(`Plain ref body (e12) minted from the stored settled tree.`)},[`ref`])},diff:y({summary:y({additions:g(),removals:g(),unchanged:g()},[`additions`,`removals`,`unchanged`]),lines:{type:`array`,items:y({kind:_([`added`,`removed`]),text:u(),ref:u(`Plain ref body (e12) for added lines.`)},[`kind`,`text`])},truncated:d(`Lines were capped to the response bound.`)},[`summary`,`lines`],`Settled diff vs the pre-action tree (changed lines only).`),hint:u()},[`settled`,`waitedMs`,`captures`,`quietMs`,`timeoutMs`]),C={platform:_(n),target:_(a),device:u(`Human-readable device name.`),id:u(`Stable device id.`),kind:_(h)},w=[`platform`,`target`,`device`,`id`,`kind`],ne=y({success:d(),exitCode:g(),stdout:u(),stderr:u(),error:l(`Normalized error detail when shutdown failed.`)},[`success`,`exitCode`,`stdout`,`stderr`]),T={press:b({properties:{evidence:x,settle:S,button:_([`secondary`,`middle`])}}),fill:b({properties:{text:u(`Text submitted to the field.`),delayMs:g(`Delay between typed characters in milliseconds.`),evidence:x,settle:S},required:[`text`]}),longpress:b({properties:{durationMs:g(),settle:S,gesture:v(`longpress`)}}),boot:y({...C,booted:{type:`boolean`,const:!0}},[...w,`booted`]),shutdown:y({...C,shutdown:ne},[...w,`shutdown`]),viewport:y({width:g(),height:g(),message:u()},[`width`,`height`,`message`]),home:y({action:v(`home`),message:u()},[`action`,`message`]),back:y({action:v(`back`),mode:_(f),message:u()},[`action`,`mode`,`message`]),rotate:y({action:v(`rotate`),orientation:_(c),message:u()},[`action`,`orientation`,`message`]),"app-switcher":y({action:v(`app-switcher`),message:u()},[`action`,`message`]),clipboard:{type:`object`,oneOf:[y({action:v(`read`),text:u()},[`action`,`text`]),y({action:v(`write`),textLength:g(),message:u()},[`action`,`textLength`,`message`])]},appstate:{type:`object`,oneOf:[y({platform:_([`ios`,`macos`]),appName:u(),appBundleId:u(),source:v(`session`),surface:_(s),device_udid:u(`iOS only — the session device UDID.`),ios_simulator_device_set:{type:[`string`,`null`],description:`iOS only — the simulator set path, or null when unknown.`}},[`platform`,`appName`,`source`,`surface`]),y({platform:v(`android`),package:u(),activity:u()},[`platform`,`package`,`activity`])]},keyboard:y({platform:_([`android`,`ios`]),action:_([`status`,`dismiss`,`enter`]),visible:d(),wasVisible:d(),dismissed:d(),attempts:g(),inputType:u(),type:_([`text`,`number`,`email`,`phone`,`password`,`datetime`,`unknown`]),inputMethodPackage:u(),focusedPackage:u(),focusedResourceId:u(),inputOwner:_([`app`,`ime`,`unknown`]),message:u()},[`platform`,`action`])};function re(){return p().map(e=>{let t=e.name in T?T[e.name]:void 0;return{name:e.name,description:e.description,inputSchema:se(e.inputSchema),...t?{outputSchema:t}:{}}})}function ie(e={}){let n=new Map;return{execute:async(r,i)=>{if(!m(r))throw new t(`INVALID_ARGS`,`Unknown command tool: ${r}`);let a=V(i),o=G(i),s=D(a,o),c=N(r,o,n.get(s)),l=await z(e,a.client),u=await(e.runCommand??B)(l,r,c);return O(n,s,r,u),{isError:!1,structuredContent:u,content:[{type:`text`,text:K({name:r,input:o,result:u,outputFormat:a.outputFormat,responseLevel:a.client.responseLevel})}]}}}}const ae=new Set([`snapshot`,`find`]),oe=new Set([`press`,`click`,`fill`,`longpress`]),E=new Set([`press`,`click`,`fill`,`longpress`,`get`]);function D(e,t){let n=L(t)?.session,r=typeof n==`string`&&n.length>0?n:`default`;return`${e.client.stateDir??``}\u0000${r}`}function O(e,t,n,r){if(oe.has(n)){k(e,t,r);return}if(!ae.has(n))return;let i=L(r),a=i?.refsGeneration;if(i===void 0||typeof a!=`number`){e.delete(t);return}let o=j(i);if(o.length===0)return;let s=e.get(t)??new Map;e.set(t,s),A(s,o,a)}function k(e,t,n){let r=L(L(n)?.settle);if(!r)return;let i=r?.refsGeneration;if(typeof i!=`number`)return;let a=L(r?.diff)?.lines,o=[];if(M(a,o),M(r.refs,o),o.length===0)return;let s=e.get(t)??new Map;e.set(t,s),A(s,o,i)}function A(e,t,n){for(let r of t)e.delete(r),e.set(r,n);for(;e.size>1e3;){let t=e.keys().next().value;if(t===void 0)break;e.delete(t)}}function j(e){let t=[];return typeof e.ref==`string`&&e.ref.startsWith(`@`)&&t.push(e.ref.slice(1)),M(e.nodes,t),M(e.refs,t),t}function M(e,t){if(Array.isArray(e))for(let n of e){let e=L(n)?.ref;typeof e==`string`&&e.length>0&&t.push(e)}}function N(e,t,n){if(n===void 0||n.size===0)return t;let r=L(t);return r?e===`wait`?P(r,n)??t:E.has(e)?F(r,n)??t:t:t}function P(e,t){if(typeof e.ref!=`string`)return;let n=I(e.ref,t);return n===e.ref?void 0:{...e,ref:n}}function F(e,t){let n=L(e.target);if(n?.kind!==`ref`||typeof n.ref!=`string`)return;let r=I(n.ref,t);return r===n.ref?void 0:{...e,target:{...n,ref:r}}}function I(e,t){if(!e.startsWith(`@`)||e.includes(`~`))return e;let n=t.get(e.slice(1));return n===void 0?e:`${e}~s${n}`}function L(e){if(!(!e||typeof e!=`object`||Array.isArray(e)))return e}const R=ie();async function z(e,t){if(e.createClient)return await e.createClient(t);let{createAgentDeviceClient:n}=await import(`./client.js`).then(e=>e.t);return n(t)}async function B(e,t,n){return await(await import(`./command-surface.js`).then(e=>e.t)).runCommand(e,t,n)}function V(e){if(!e||typeof e!=`object`||Array.isArray(e))return{client:{},outputFormat:`optimized`};let t=e;return{client:H(t),outputFormat:W(t.mcpOutputFormat)}}function H(e){let n=e.stateDir,r=e.includeCost,i=e.responseLevel,a={};if(n!==void 0&&(typeof n!=`string`||n.length===0))throw new t(`INVALID_ARGS`,`Expected stateDir to be a non-empty string.`);if(typeof n==`string`&&(a.stateDir=n),r!==void 0&&typeof r!=`boolean`)throw new t(`INVALID_ARGS`,`Expected includeCost to be a boolean.`);r===!0&&(a.cost=!0);let o=U(i);return o!==void 0&&(a.responseLevel=o),a}function U(e){if(e!==void 0){if(typeof e!=`string`||!r.includes(e))throw new t(`INVALID_ARGS`,`Expected responseLevel to be one of 'digest', 'default', or 'full'.`);return e}}function W(e){if(e===void 0)return`optimized`;if(e!==`optimized`&&e!==`json`)throw new t(`INVALID_ARGS`,`Expected mcpOutputFormat to be "optimized" or "json".`);return e}function G(e){if(!e||typeof e!=`object`||Array.isArray(e))return e;let{stateDir:t,mcpOutputFormat:n,includeCost:r,responseLevel:i,...a}=e;return a}function se(e){return{...e,properties:{...e.properties,stateDir:{type:`string`,description:`Agent-device state directory.`},mcpOutputFormat:{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:{type:`boolean`,description:`Include per-command agent-cost (cost.wallClockMs, …) in structuredContent. Defaults to off; the default response shape is unchanged.`},responseLevel:{type:`string`,enum:[`digest`,`default`,`full`],description:`Response verbosity: token-cheap digest / default (today) / full. Defaults to default; the default response shape is unchanged.`}}}}function K(e){if(e.outputFormat===`json`||e.responseLevel!==void 0&&e.responseLevel!=="default")return q(e.result);let t=ee({name:e.name,input:e.input,result:e.result});return typeof t?.text==`string`?t.text:q(t?.data??e.result)}function q(e){return typeof e==`string`?e:JSON.stringify(e,null,2)}async function ce(e){if(e.jsonrpc!==`2.0`||typeof e.method!=`string`)return J(e.id??null,-32600,`Invalid JSON-RPC request.`);if(e.id===void 0)return null;try{return me(e.id,await le(e.method,e.params))}catch(t){return t instanceof Y?J(e.id,-32601,t.message):J(e.id,-32602,t instanceof Error?t.message:String(t))}}async function le(e,t){switch(e){case`initialize`:return{protocolVersion:fe(t),capabilities:{tools:{}},serverInfo:{name:`agent-device`,version:o()}};case`ping`:return{};case`tools/list`:return{tools:re()};case`tools/call`:return await ue(t);default:throw new Y(`Unsupported MCP method: ${e}`)}}async function ue(e){let t=he(e),n=ge(t,`name`);try{return await R.execute(n,t.arguments)}catch(e){return pe(de(e),!0)}}function de(t){let n=e(t),r=[`Error (${n.code}): ${n.message}`];return n.hint&&r.push(`Hint: ${n.hint}`),n.supportedOn&&r.push(`Supported on: ${n.supportedOn}`),r.join(`
2
- `)}function fe(e){return`2025-11-25`}function pe(e,t=!1){return{isError:t,content:[{type:`text`,text:e}]}}function me(e,t){return{jsonrpc:`2.0`,id:e,result:t}}function J(e,t,n){return{jsonrpc:`2.0`,id:e,error:{code:t,message:n}}}function he(e){if(!e||typeof e!=`object`||Array.isArray(e))throw new t(`INVALID_ARGS`,`Expected object parameters.`);return e}function ge(e,n){let r=e[n];if(typeof r!=`string`||r.length===0)throw new t(`INVALID_ARGS`,`Expected ${n} to be a non-empty string.`);return r}var Y=class extends Error{};async function _e(){let e=ve(),t=new Se(t=>{e.push(t)});process.stdin.setEncoding(`utf8`),process.stdin.on(`data`,e=>{try{t.push(e)}catch(e){$({jsonrpc:`2.0`,id:null,error:{code:-32700,message:e instanceof Error?e.message:String(e)}})}}),await new Promise(e=>{process.stdin.on(`end`,e),process.stdin.on(`close`,e),process.stdin.resume()}),await e.idle()}function ve(e={}){let t=e.handlePayload??ye,n=e.write??$,r=Promise.resolve();return{push:e=>{let i=xe(e);r=r.then(async()=>{let r=await t(e);r&&n(r)}).catch(e=>{n({jsonrpc:`2.0`,id:i,error:{code:-32603,message:e instanceof Error?e.message:String(e)}})})},idle:async()=>{await r}}}function ye(e){return Array.isArray(e)?X(e):Z(e)}async function X(e){let t=[];for(let n of e)t.push(...Ce(await Z(n)));return t.length>0?t:null}async function Z(e){let t;try{t=i.parse(e)}catch{return be(Q(e))}return ce(t)}function be(e){return{jsonrpc:`2.0`,id:e,error:{code:-32600,message:`Invalid JSON-RPC request.`}}}function xe(e){return Array.isArray(e)?e.length===1?Q(e[0]):null:Q(e)}function Q(e){if(e&&typeof e==`object`&&!Array.isArray(e)){let t=e.id;if(typeof t==`string`||typeof t==`number`||t===null)return t}return null}var Se=class{buffer=``;sink;constructor(e){this.sink=e}push(e){for(this.buffer+=e;;){let e=this.tryReadLineMessage();if(e!==void 0){this.emit(e);continue}break}}tryReadLineMessage(){let e=this.buffer.indexOf(`
3
- `);if(e===-1)return;let t=this.buffer.slice(0,e).trim();return this.buffer=this.buffer.slice(e+1),t.length>0?t:void 0}emit(e){this.sink(JSON.parse(e))}};function Ce(e){return e?[e]:[]}function $(e){process.stdout.write(`${JSON.stringify(e)}\n`)}export{_e as runAgentDeviceMcpServer};
1
+ import{B as e,F as t,c as n,n as r,o as i,s as a}from"./sdk-contracts.js";import{Qt as o,s,t as c}from"./tv-remote.js";import{n as l}from"./version.js";import{M as u,N as d,c as f,j as p}from"./registry.js";import{i as ee,n as m}from"./command-metadata.js";import{t as h}from"./cli-output.js";const g=[`simulator`,`emulator`,`device`];function _(e){return{type:`number`,...e?{description:e}:{}}}function v(e,t){return{type:`string`,enum:e,...t?{description:t}:{}}}function y(e){return{type:`string`,const:e}}function b(e,t=[],n){return{type:`object`,...n?{description:n}:{},properties:e,...t.length>0?{required:t}:{}}}const x={type:`array`,items:{type:`string`}};function S(e={}){let t=e.properties??{},n=e.required??[];return b({targetKind:v([`point`,`ref`,`selector`],`Resolved interaction target kind.`),x:_(`Resolved interaction x coordinate when available.`),y:_(`Resolved interaction y coordinate when available.`),referenceWidth:_(`Reference frame width for visualizing the interaction point.`),referenceHeight:_(`Reference frame height for visualizing the interaction point.`),ref:d(`Snapshot ref without the @ prefix when the target was an @ref.`),selector:d(`Selector expression when the target was a selector.`),selectorChain:x,refLabel:d(),targetHittable:p(),hint:d(),warning:d(),message:d(),evidence:C,...t},[`targetKind`,...n])}const C=b({foregroundApp:d(`Foreground app bundle id or name, when the capture carries it.`),nodeCount:_(`Node count in the post-action interactive-only capture.`),interactiveNodeCount:_(`Subset of nodeCount the platform reports as hittable.`),digest:d(`Order-independent digest of the post-action node multiset.`),changedFromBefore:p(`Whether the post-action digest differs from the pre-action capture digest. false is evidence, not failure.`)},[`nodeCount`,`interactiveNodeCount`,`digest`,`changedFromBefore`]),w=b({settled:p(`Whether the UI held the quiet window before the deadline. false is advisory, not failure.`),waitedMs:_(),captures:_(),quietMs:_(),timeoutMs:_(),refsGeneration:_(`Snapshot generation of the stored settled tree; refs on added diff lines were minted from it.`),refs:{type:`array`,items:b({ref:d(`Plain ref body (e12) minted from the stored settled tree.`)},[`ref`])},diff:b({summary:b({additions:_(),removals:_(),unchanged:_()},[`additions`,`removals`,`unchanged`]),lines:{type:`array`,items:b({kind:v([`added`,`removed`]),text:d(),ref:d(`Plain ref body (e12) for added lines.`)},[`kind`,`text`])},truncated:p(`Lines were capped to the response bound.`)},[`summary`,`lines`],`Settled diff vs the pre-action tree (changed lines only).`),hint:d()},[`settled`,`waitedMs`,`captures`,`quietMs`,`timeoutMs`]),T={platform:v(n),target:v(a),device:d(`Human-readable device name.`),id:d(`Stable device id.`),kind:v(g)},E=[`platform`,`target`,`device`,`id`,`kind`],te=b({success:p(),exitCode:_(),stdout:d(),stderr:d(),error:u(`Normalized error detail when shutdown failed.`)},[`success`,`exitCode`,`stdout`,`stderr`]),D={press:S({properties:{evidence:C,settle:w,button:v([`secondary`,`middle`]),count:_(`Number of press/click repetitions.`),intervalMs:_(`Delay between repeated press/click actions.`),holdMs:_(`Hold duration for each action.`),jitterPx:_(`Randomization radius in pixels.`),doubleTap:p(`Whether the command requested a double-tap action.`)}}),fill:S({properties:{text:d(`Text submitted to the field.`),delayMs:_(`Delay between typed characters in milliseconds.`),evidence:C,settle:w},required:[`text`]}),longpress:S({properties:{durationMs:_(),settle:w,gesture:y(`longpress`)}}),boot:b({...T,booted:{type:`boolean`,const:!0}},[...E,`booted`]),shutdown:b({...T,shutdown:te},[...E,`shutdown`]),viewport:b({width:_(),height:_(),message:d()},[`width`,`height`,`message`]),home:b({action:y(`home`),message:d()},[`action`,`message`]),back:b({action:y(`back`),mode:v(f),message:d()},[`action`,`mode`,`message`]),rotate:b({action:y(`rotate`),orientation:v(s),message:d()},[`action`,`orientation`,`message`]),"app-switcher":b({action:y(`app-switcher`),message:d()},[`action`,`message`]),"tv-remote":b({action:y(`tv-remote`),button:v(c),durationMs:_(),message:d()},[`action`,`button`,`message`]),wait:b({waitedMs:_(),kind:y(`selector`),text:d(),selector:d(),captures:_(),nodeCount:_(),hint:d(),warning:d()},[`waitedMs`]),prepare:b({action:y(`ios-runner`),platform:v(n),deviceId:d(),deviceName:d(),kind:v(g),durationMs:_(),runner:b({},[]),cache:v([`exact`,`restore-key`,`miss`,`external`]),artifact:v([`valid`,`rebuilt`]),buildMs:_(),connectMs:_(),healthCheckMs:_(),xctestrunPath:d(),recoveryReason:d(),failureReason:d(),timing:b({totalMs:_(),additiveParts:b({buildMs:_(),connectAfterBuildMs:_(),healthCheckMs:_()},[`connectAfterBuildMs`,`healthCheckMs`]),containment:b({connectMs:{type:`array`,items:y(`buildMs`)},healthCheckMs:{type:`array`,items:d()}},[`healthCheckMs`]),note:d()},[`totalMs`,`additiveParts`,`containment`,`note`]),message:d()},[`action`,`platform`,`deviceId`,`deviceName`,`kind`,`durationMs`,`runner`,`connectMs`,`healthCheckMs`,`timing`,`message`]),push:{type:`object`,oneOf:[b({platform:y(`ios`),bundleId:d(),message:d()},[`platform`,`bundleId`,`message`]),b({platform:y(`android`),package:d(),action:d(),extrasCount:_(),message:d()},[`platform`,`package`,`action`,`extrasCount`,`message`])]},"trigger-app-event":b({event:d(),eventUrl:d(),transport:y(`deep-link`),message:d()},[`event`,`eventUrl`,`transport`,`message`]),clipboard:{type:`object`,oneOf:[b({action:y(`read`),text:d()},[`action`,`text`]),b({action:y(`write`),textLength:_(),message:d()},[`action`,`textLength`,`message`])]},appstate:{type:`object`,oneOf:[b({platform:v([`ios`,`macos`]),appName:d(),appBundleId:d(),source:y(`session`),surface:v(o),device_udid:d(`iOS only — the session device UDID.`),ios_simulator_device_set:{type:[`string`,`null`],description:`iOS only — the simulator set path, or null when unknown.`}},[`platform`,`appName`,`source`,`surface`]),b({platform:y(`android`),package:d(),activity:d()},[`platform`,`package`,`activity`])]},keyboard:b({platform:v([`android`,`ios`]),action:v([`status`,`dismiss`,`enter`]),visible:p(),wasVisible:p(),dismissed:p(),attempts:_(),inputType:d(),type:v([`text`,`number`,`email`,`phone`,`password`,`datetime`,`unknown`]),inputMethodPackage:d(),focusedPackage:d(),focusedResourceId:d(),inputOwner:v([`app`,`ime`,`unknown`]),message:d()},[`platform`,`action`])};function ne(){return ee().map(e=>{let t=e.name in D?D[e.name]:void 0;return{name:e.name,description:e.description,inputSchema:K(e.inputSchema),...t?{outputSchema:t}:{}}})}function re(e={}){let n=new Map;return{execute:async(r,i)=>{if(!m(r))throw new t(`INVALID_ARGS`,`Unknown command tool: ${r}`);let a=V(i),o=G(i),s=se(a,o),c=N(r,o,n.get(s)),l=await z(e,a.client),u=await(e.runCommand??B)(l,r,c);return O(n,s,r,u),{isError:!1,structuredContent:u,content:[{type:`text`,text:ce({name:r,input:o,result:u,outputFormat:a.outputFormat,responseLevel:a.client.responseLevel})}]}}}}const ie=new Set([`snapshot`,`find`]),ae=new Set([`press`,`click`,`fill`,`longpress`]),oe=new Set([`press`,`click`,`fill`,`longpress`,`get`]);function se(e,t){let n=L(t)?.session,r=typeof n==`string`&&n.length>0?n:`default`;return`${e.client.stateDir??``}\u0000${r}`}function O(e,t,n,r){if(ae.has(n)){k(e,t,r);return}if(!ie.has(n))return;let i=L(r),a=i?.refsGeneration;if(i===void 0||typeof a!=`number`){e.delete(t);return}let o=j(i);if(o.length===0)return;let s=e.get(t)??new Map;e.set(t,s),A(s,o,a)}function k(e,t,n){let r=L(L(n)?.settle);if(!r)return;let i=r?.refsGeneration;if(typeof i!=`number`)return;let a=L(r?.diff)?.lines,o=[];if(M(a,o),M(r.refs,o),o.length===0)return;let s=e.get(t)??new Map;e.set(t,s),A(s,o,i)}function A(e,t,n){for(let r of t)e.delete(r),e.set(r,n);for(;e.size>1e3;){let t=e.keys().next().value;if(t===void 0)break;e.delete(t)}}function j(e){let t=[];return typeof e.ref==`string`&&e.ref.startsWith(`@`)&&t.push(e.ref.slice(1)),M(e.nodes,t),M(e.refs,t),t}function M(e,t){if(Array.isArray(e))for(let n of e){let e=L(n)?.ref;typeof e==`string`&&e.length>0&&t.push(e)}}function N(e,t,n){if(n===void 0||n.size===0)return t;let r=L(t);return r?e===`wait`?P(r,n)??t:oe.has(e)?F(r,n)??t:t:t}function P(e,t){if(typeof e.ref!=`string`)return;let n=I(e.ref,t);return n===e.ref?void 0:{...e,ref:n}}function F(e,t){let n=L(e.target);if(n?.kind!==`ref`||typeof n.ref!=`string`)return;let r=I(n.ref,t);return r===n.ref?void 0:{...e,target:{...n,ref:r}}}function I(e,t){if(!e.startsWith(`@`)||e.includes(`~`))return e;let n=t.get(e.slice(1));return n===void 0?e:`${e}~s${n}`}function L(e){if(!(!e||typeof e!=`object`||Array.isArray(e)))return e}const R=re();async function z(e,t){if(e.createClient)return await e.createClient(t);let{createAgentDeviceClient:n}=await import(`./client.js`).then(e=>e.t);return n(t)}async function B(e,t,n){return await(await import(`./command-surface.js`).then(e=>e.t)).runCommand(e,t,n)}function V(e){if(!e||typeof e!=`object`||Array.isArray(e))return{client:{},outputFormat:`optimized`};let t=e;return{client:H(t),outputFormat:W(t.mcpOutputFormat)}}function H(e){let n=e.stateDir,r=e.includeCost,i=e.responseLevel,a={};if(n!==void 0&&(typeof n!=`string`||n.length===0))throw new t(`INVALID_ARGS`,`Expected stateDir to be a non-empty string.`);if(typeof n==`string`&&(a.stateDir=n),r!==void 0&&typeof r!=`boolean`)throw new t(`INVALID_ARGS`,`Expected includeCost to be a boolean.`);r===!0&&(a.cost=!0);let o=U(i);return o!==void 0&&(a.responseLevel=o),a}function U(e){if(e!==void 0){if(typeof e!=`string`||!r.includes(e))throw new t(`INVALID_ARGS`,`Expected responseLevel to be one of 'digest', 'default', or 'full'.`);return e}}function W(e){if(e===void 0)return`optimized`;if(e!==`optimized`&&e!==`json`)throw new t(`INVALID_ARGS`,`Expected mcpOutputFormat to be "optimized" or "json".`);return e}function G(e){if(!e||typeof e!=`object`||Array.isArray(e))return e;let{stateDir:t,mcpOutputFormat:n,includeCost:r,responseLevel:i,...a}=e;return a}function K(e){return{...e,properties:{...e.properties,stateDir:{type:`string`,description:`Agent-device state directory.`},mcpOutputFormat:{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:{type:`boolean`,description:`Include per-command agent-cost (cost.wallClockMs, …) in structuredContent. Defaults to off; the default response shape is unchanged.`},responseLevel:{type:`string`,enum:[`digest`,`default`,`full`],description:`Response verbosity: token-cheap digest / default (today) / full. Defaults to default; the default response shape is unchanged.`}}}}function ce(e){if(e.outputFormat===`json`||e.responseLevel!==void 0&&e.responseLevel!=="default")return q(e.result);let t=h({name:e.name,input:e.input,result:e.result});return typeof t?.text==`string`?t.text:q(t?.data??e.result)}function q(e){return typeof e==`string`?e:JSON.stringify(e,null,2)}async function le(e){if(e.jsonrpc!==`2.0`||typeof e.method!=`string`)return J(e.id??null,-32600,`Invalid JSON-RPC request.`);if(e.id===void 0)return null;try{return he(e.id,await ue(e.method,e.params))}catch(t){return t instanceof Y?J(e.id,-32601,t.message):J(e.id,-32602,t instanceof Error?t.message:String(t))}}async function ue(e,t){switch(e){case`initialize`:return{protocolVersion:pe(t),capabilities:{tools:{}},serverInfo:{name:`agent-device`,version:l()}};case`ping`:return{};case`tools/list`:return{tools:ne()};case`tools/call`:return await de(t);default:throw new Y(`Unsupported MCP method: ${e}`)}}async function de(e){let t=ge(e),n=_e(t,`name`);try{return await R.execute(n,t.arguments)}catch(e){return me(fe(e),!0)}}function fe(t){let n=e(t),r=[`Error (${n.code}): ${n.message}`];return n.hint&&r.push(`Hint: ${n.hint}`),n.supportedOn&&r.push(`Supported on: ${n.supportedOn}`),r.join(`
2
+ `)}function pe(e){return`2025-11-25`}function me(e,t=!1){return{isError:t,content:[{type:`text`,text:e}]}}function he(e,t){return{jsonrpc:`2.0`,id:e,result:t}}function J(e,t,n){return{jsonrpc:`2.0`,id:e,error:{code:t,message:n}}}function ge(e){if(!e||typeof e!=`object`||Array.isArray(e))throw new t(`INVALID_ARGS`,`Expected object parameters.`);return e}function _e(e,n){let r=e[n];if(typeof r!=`string`||r.length===0)throw new t(`INVALID_ARGS`,`Expected ${n} to be a non-empty string.`);return r}var Y=class extends Error{};async function ve(){let e=ye(),t=new Ce(t=>{e.push(t)});process.stdin.setEncoding(`utf8`),process.stdin.on(`data`,e=>{try{t.push(e)}catch(e){$({jsonrpc:`2.0`,id:null,error:{code:-32700,message:e instanceof Error?e.message:String(e)}})}}),await new Promise(e=>{process.stdin.on(`end`,e),process.stdin.on(`close`,e),process.stdin.resume()}),await e.idle()}function ye(e={}){let t=e.handlePayload??X,n=e.write??$,r=Promise.resolve();return{push:e=>{let i=Se(e);r=r.then(async()=>{let r=await t(e);r&&n(r)}).catch(e=>{n({jsonrpc:`2.0`,id:i,error:{code:-32603,message:e instanceof Error?e.message:String(e)}})})},idle:async()=>{await r}}}function X(e){return Array.isArray(e)?be(e):Z(e)}async function be(e){let t=[];for(let n of e)t.push(...we(await Z(n)));return t.length>0?t:null}async function Z(e){let t;try{t=i.parse(e)}catch{return xe(Q(e))}return le(t)}function xe(e){return{jsonrpc:`2.0`,id:e,error:{code:-32600,message:`Invalid JSON-RPC request.`}}}function Se(e){return Array.isArray(e)?e.length===1?Q(e[0]):null:Q(e)}function Q(e){if(e&&typeof e==`object`&&!Array.isArray(e)){let t=e.id;if(typeof t==`string`||typeof t==`number`||t===null)return t}return null}var Ce=class{buffer=``;sink;constructor(e){this.sink=e}push(e){for(this.buffer+=e;;){let e=this.tryReadLineMessage();if(e!==void 0){this.emit(e);continue}break}}tryReadLineMessage(){let e=this.buffer.indexOf(`
3
+ `);if(e===-1)return;let t=this.buffer.slice(0,e).trim();return this.buffer=this.buffer.slice(e+1),t.length>0?t:void 0}emit(e){this.sink(JSON.parse(e))}};function we(e){return e?[e]:[]}function $(e){process.stdout.write(`${JSON.stringify(e)}\n`)}export{ve as runAgentDeviceMcpServer};