Files
callstack__agent-device/docs/migrating-gestures.html

193 lines
61 KiB
HTML

<!doctype html>
<html lang="en">
<head><meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Migrating Gestures - agent-device</title>
<script>{;const saved = localStorage.getItem('rspress-theme-appearance');const preferDark = window.matchMedia('(prefers-color-scheme: dark)').matches;const isDark = !saved || saved === 'auto' ? preferDark : saved === 'dark';document.documentElement.classList.toggle('dark', isDark);document.documentElement.classList.toggle('rp-dark', isDark);document.documentElement.style.colorScheme = isDark ? 'dark' : 'light';}</script>
<link href="/agent-device/static/css/styles.cf5e9ab9a4.css" rel="stylesheet">
<script defer src="/agent-device/static/js/styles.308ea4bafe.js"></script>
<script defer src="/agent-device/static/js/lib-react.e84adf13b9.js"></script>
<script defer src="/agent-device/static/js/lib-router.270f17bfa6.js"></script>
<script defer src="/agent-device/static/js/476.52ed165336.js"></script>
<script defer src="/agent-device/static/js/index.8722046b0d.js"></script>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="generator" content="Rspress v2.0.12">
<meta property="og:url" content="https://oss.callstack.com/agent-device">
<meta property="og:type" content="website">
<meta property="og:title" content="Migrating Gestures - agent-device">
<meta property="og:image" content="https://oss.callstack.com/agent-device/og-image.jpg">
<meta property="og:description" content="agent-device 0.20.0 removed the timed forms of swipe, gesture fling, and gesture swipe, and the velocity argument of gesture rotate. Nothing is silently reinterpreted: every removed form now fails with an INVALID_ARGS error that names its replacement. This page is the migration for all four public surfaces — CLI, Node.js, MCP, and saved .ad recordings — plus the policy that governs the next such removal.">
<link rel="icon" href="/agent-device/logo.svg" type="image/svg+xml">
<meta name="description" content="agent-device 0.20.0 removed the timed forms of swipe, gesture fling, and gesture swipe, and the velocity argument of gesture rotate. Nothing is silently reinterpreted: every removed form now fails with an INVALID_ARGS error that names its replacement. This page is the migration for all four public surfaces — CLI, Node.js, MCP, and saved .ad recordings — plus the policy that governs the next such removal."></head>
<body>
<div id="__rspress_root"><link rel="preload" as="image" href="/agent-device/logo-light.svg"/><link rel="preload" as="image" href="/agent-device/logo-dark.svg"/><link rel="preload" as="image" href="/agent-device/static/image/abstract-atom.4eca0300ff.avif"/><header class="rp-nav"><div class="rp-nav__left"><div class="rp-nav__title"><a href="/agent-device/" class="rp-nav__title__link rp-link"><div class="rp-nav__title__logo"><img src="/agent-device/logo-light.svg" alt="logo" id="logo" class="rspress-logo rp-nav__title__logo-image rp-nav__title__logo-image--light"/><img src="/agent-device/logo-dark.svg" alt="logo" id="logo" class="rspress-logo rp-nav__title__logo-image rp-nav__title__logo-image--dark"/></div></a></div></div><div class="rp-nav__right"><button class="rp-search-button"><div class="rp-search-button__content"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" viewBox="0 0 16 16" class="rp-search-button__icon"><path fill="#838289" d="M14.667 14.666h-1.333v-1.333h1.332zm-1.333-1.333H12V12h1.333zm-4-1.333H4v-1.334h5.334zM12 12h-1.335v-1.334h1.335zm-8-1.334H2.665V9.333H4zm6.665 0H9.334V9.333h1.332zm-8-1.333H1.335V4h1.333zm9.335 0h-1.335V4h1.335zM4 4H2.665V2.666H4zm6.665 0H9.334V2.666h1.332zM9.334 2.666H4V1.333h5.334z"></path></svg><span class="rp-search-button__word">Search</span></div><div class="rp-search-button__hotkey" style="opacity:0"><span></span><span>K</span></div></button><div class="rp-search-button--mobile"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" viewBox="0 0 16 16"><path fill="#838289" d="M14.667 14.666h-1.333v-1.333h1.332zm-1.333-1.333H12V12h1.333zm-4-1.333H4v-1.334h5.334zM12 12h-1.335v-1.334h1.335zm-8-1.334H2.665V9.333H4zm6.665 0H9.334V9.333h1.332zm-8-1.333H1.335V4h1.333zm9.335 0h-1.335V4h1.335zM4 4H2.665V2.666H4zm6.665 0H9.334V2.666h1.332zM9.334 2.666H4V1.333h5.334z"></path></svg></div><ul class="rp-nav-menu rp-nav-menu--right"><li class="rp-nav-menu__item"><a href="/agent-device/docs/introduction" class="rp-nav-menu__item__container rp-link">Docs</a></li></ul><div class="rp-nav__others"><div class="rp-nav-menu__divider"></div><div role="button" tabindex="0" class="rspress-nav-appearance"><div class="rp-p-1 rp-border rp-border-solid rp-border-gray-300 rp-text-gray-400 rp-cursor-pointer rp-rounded-md rp-transition-all rp-duration-300 rp-w-7 rp-h-7"><svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" viewBox="0 0 24 24"><path fill="currentColor" d="M18 22H8v-2h10zM8 20H6v-2h2zm12 0h-2v-2h2zM6 18H4v-2h2zm16 0h-2v-4h-2v-2h2v-2h2zM4 16H2V6h2zm14 0h-6v-2h6zm-6-2h-2v-2h2zm-2-2H8V6h2zM6 6H4V4h2zm8-2h-2v2h-2V4H6V2h8z"></path></svg></div></div><div class="rp-social-links"><a href="https://github.com/callstack/agent-device" target="_blank" rel="noopener noreferrer" class="rp-social-links__item"><div class="rp-social-links__icon"><div class="rp-social-links__icon"><svg xmlns="http://www.w3.org/2000/svg" width="100%" viewBox="0 0 24 24"><path fill="currentColor" d="M12 .297c-6.63 0-12 5.373-12 12c0 5.303 3.438 9.8 8.205 11.385c.6.113.82-.258.82-.577c0-.285-.01-1.04-.015-2.04c-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729c1.205.084 1.838 1.236 1.838 1.236c1.07 1.835 2.809 1.305 3.495.998c.108-.776.417-1.305.76-1.605c-2.665-.3-5.466-1.332-5.466-5.93c0-1.31.465-2.38 1.235-3.22c-.135-.303-.54-1.523.105-3.176c0 0 1.005-.322 3.3 1.23c.96-.267 1.98-.399 3-.405c1.02.006 2.04.138 3 .405c2.28-1.552 3.285-1.23 3.285-1.23c.645 1.653.24 2.873.12 3.176c.765.84 1.23 1.91 1.23 3.22c0 4.61-2.805 5.625-5.475 5.92c.42.36.81 1.096.81 2.22c0 1.606-.015 2.896-.015 3.286c0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg></div></div></a><a href="https://discord.gg/eYapw6F3" target="_blank" rel="noopener noreferrer" class="rp-social-links__item"><div class="rp-social-links__icon"><div class="rp-social-links__icon"><svg xmlns="http://www.w3.org/2000/svg" width="100%" viewBox="0 0 24 24"><path fill="currentColor" d="M20.317 4.37a19.8 19.8 0 0 0-4.885-1.515a.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.3 18.3 0 0 0-5.487 0a13 13 0 0 0-.617-1.25a.08.08 0 0 0-.079-.037A19.7 19.7 0 0 0 3.677 4.37a.1.1 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.08.08 0 0 0 .031.057a19.9 19.9 0 0 0 5.993 3.03a.08.08 0 0 0 .084-.028a14 14 0 0 0 1.226-1.994a.076.076 0 0 0-.041-.106a13 13 0 0 1-1.872-.892a.077.077 0 0 1-.008-.128a10 10 0 0 0 .372-.292a.07.07 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.07.07 0 0 1 .078.01q.181.149.373.292a.077.077 0 0 1-.006.127a12.3 12.3 0 0 1-1.873.892a.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.08.08 0 0 0 .084.028a19.8 19.8 0 0 0 6.002-3.03a.08.08 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.06.06 0 0 0-.031-.03M8.02 15.33c-1.182 0-2.157-1.085-2.157-2.419c0-1.333.956-2.419 2.157-2.419c1.21 0 2.176 1.096 2.157 2.42c0 1.333-.956 2.418-2.157 2.418m7.975 0c-1.183 0-2.157-1.085-2.157-2.419c0-1.333.955-2.419 2.157-2.419c1.21 0 2.176 1.096 2.157 2.42c0 1.333-.946 2.418-2.157 2.418"/></svg></div></div></a><ul class="rp-hover-group rp-hover-group--hidden rp-hover-group--right"></ul></div></div><button aria-label="mobile hamburger" class="rp-nav-hamburger rp-nav-hamburger__sm"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="#838289" fill-rule="evenodd" d="M1 9h6v6H1zm2 2v2h2v-2zm6-2h6v6H9zm2 2v2h2v-2zm6-2h6v6h-6zm2 2v2h2v-2z" clip-rule="evenodd"></path></svg></button><button aria-label="mobile hamburger" class="rp-nav-hamburger rp-nav-hamburger__md"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="#838289" fill-rule="evenodd" d="M1 9h6v6H1zm2 2v2h2v-2zm6-2h6v6H9zm2 2v2h2v-2zm6-2h6v6h-6zm2 2v2h2v-2z" clip-rule="evenodd"></path></svg><ul class="rp-hover-group rp-hover-group--hidden rp-hover-group--right"><div class="rp-nav-menu__others-mobile__container"><div class="rp-nav-hamburger__md__hover-group"><div class="rp-nav-screen-appearance"><div class="rp-nav-screen-appearance__left">Theme</div><div class="rp-nav-screen-appearance__right"></div></div><div class="rp-nav-screen-divider"></div><div class="rp-social-links"><a href="https://github.com/callstack/agent-device" target="_blank" rel="noopener noreferrer" class="rp-social-links__item"><div class="rp-social-links__icon"><div class="rp-social-links__icon"><svg xmlns="http://www.w3.org/2000/svg" width="100%" viewBox="0 0 24 24"><path fill="currentColor" d="M12 .297c-6.63 0-12 5.373-12 12c0 5.303 3.438 9.8 8.205 11.385c.6.113.82-.258.82-.577c0-.285-.01-1.04-.015-2.04c-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729c1.205.084 1.838 1.236 1.838 1.236c1.07 1.835 2.809 1.305 3.495.998c.108-.776.417-1.305.76-1.605c-2.665-.3-5.466-1.332-5.466-5.93c0-1.31.465-2.38 1.235-3.22c-.135-.303-.54-1.523.105-3.176c0 0 1.005-.322 3.3 1.23c.96-.267 1.98-.399 3-.405c1.02.006 2.04.138 3 .405c2.28-1.552 3.285-1.23 3.285-1.23c.645 1.653.24 2.873.12 3.176c.765.84 1.23 1.91 1.23 3.22c0 4.61-2.805 5.625-5.475 5.92c.42.36.81 1.096.81 2.22c0 1.606-.015 2.896-.015 3.286c0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg></div></div></a><a href="https://discord.gg/eYapw6F3" target="_blank" rel="noopener noreferrer" class="rp-social-links__item"><div class="rp-social-links__icon"><div class="rp-social-links__icon"><svg xmlns="http://www.w3.org/2000/svg" width="100%" viewBox="0 0 24 24"><path fill="currentColor" d="M20.317 4.37a19.8 19.8 0 0 0-4.885-1.515a.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.3 18.3 0 0 0-5.487 0a13 13 0 0 0-.617-1.25a.08.08 0 0 0-.079-.037A19.7 19.7 0 0 0 3.677 4.37a.1.1 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.08.08 0 0 0 .031.057a19.9 19.9 0 0 0 5.993 3.03a.08.08 0 0 0 .084-.028a14 14 0 0 0 1.226-1.994a.076.076 0 0 0-.041-.106a13 13 0 0 1-1.872-.892a.077.077 0 0 1-.008-.128a10 10 0 0 0 .372-.292a.07.07 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.07.07 0 0 1 .078.01q.181.149.373.292a.077.077 0 0 1-.006.127a12.3 12.3 0 0 1-1.873.892a.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.08.08 0 0 0 .084.028a19.8 19.8 0 0 0 6.002-3.03a.08.08 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.06.06 0 0 0-.031-.03M8.02 15.33c-1.182 0-2.157-1.085-2.157-2.419c0-1.333.956-2.419 2.157-2.419c1.21 0 2.176 1.096 2.157 2.42c0 1.333-.956 2.418-2.157 2.418m7.975 0c-1.183 0-2.157-1.085-2.157-2.419c0-1.333.955-2.419 2.157-2.419c1.21 0 2.176 1.096 2.157 2.42c0 1.333-.946 2.418-2.157 2.418"/></svg></div></div></a><ul class="rp-hover-group rp-hover-group--hidden rp-hover-group--right"></ul></div></div></div></ul></button></div></header><div class="rp-doc-layout__menu"><div class="rp-sidebar-menu"><button type="button" class="rp-sidebar-menu__left"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="#838289" d="M20 18H4v-2h16zm0-5H4v-2h16zm0-5H4V6h16z"></path></svg><span>Menu</span></button><button type="button" class="rp-sidebar-menu__right"><span class="rp-sidebar-menu__right__text">Contents</span><svg width="14" height="14" class="rp-progress-circle"><circle cx="7" cy="7" r="6" stroke-linecap="round" fill="none" stroke="var(--rp-c-divider-light)" stroke-width="2"></circle><circle cx="7" cy="7" r="6" stroke-linecap="round" fill="none" stroke="var(--rp-c-brand)" stroke-width="2" stroke-dasharray="37.69911184307752" stroke-dashoffset="37.69911184307752" transform="rotate(-90 7 7)" style="transition:stroke-dashoffset 0.3s"></circle></svg><svg xmlns="http://www.w3.org/2000/svg" width="12" height="13" fill="none" viewBox="0 0 12 13" class="rp-sidebar-menu__right__icon" style="transform:rotate(0deg);transition:transform 0.2s ease-out"><path fill="#BCBBC2" d="M6.5 4.5h1v-1h-1v-1h-1v1h-1v1h1v6h1zm-2 0h-1v1h1zm4 0h-1v1h1zm-5 2v-1h-1v1zm6-1h-1v1h1z"></path></svg></button></div></div><div class="rp-doc-layout__container"><aside class="rp-doc-layout__sidebar rp-scrollbar"><div class="rp-sidebar-item rp-sidebar-group" style="padding-left:12px" data-depth="0"><div class="rp-sidebar-item__left"><span class="rp-doc">Getting Started</span></div><div class="rp-sidebar-item__right"></div></div><div style="display:grid;grid-template-rows:1fr;transition:grid-template-rows 0.2s ease-out"><div style="overflow:hidden"><a href="/agent-device/docs/introduction" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span class="rp-doc">Introduction</span></div><div class="rp-sidebar-item__right"></div></a><a href="/agent-device/docs/installation" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span class="rp-doc">Installation</span></div><div class="rp-sidebar-item__right"></div></a><a href="/agent-device/docs/agent-setup" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span class="rp-doc">AI Agent Setup</span></div><div class="rp-sidebar-item__right"></div></a><a href="/agent-device/docs/quick-start" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span class="rp-doc">Quick Start</span></div><div class="rp-sidebar-item__right"></div></a></div></div><div class="rp-sidebar-item rp-sidebar-group" style="padding-left:12px" data-depth="0"><div class="rp-sidebar-item__left"><span class="rp-doc">Using agent-device</span></div><div class="rp-sidebar-item__right"></div></div><div style="display:grid;grid-template-rows:1fr;transition:grid-template-rows 0.2s ease-out"><div style="overflow:hidden"><a href="/agent-device/docs/commands" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span class="rp-doc">Commands</span></div><div class="rp-sidebar-item__right"></div></a><a href="/agent-device/docs/configuration" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span class="rp-doc">Configuration</span></div><div class="rp-sidebar-item__right"></div></a><a href="/agent-device/docs/selectors" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span class="rp-doc">Selectors</span></div><div class="rp-sidebar-item__right"></div></a><a href="/agent-device/docs/sessions" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span class="rp-doc">Sessions</span></div><div class="rp-sidebar-item__right"></div></a><a href="/agent-device/docs/batching" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span class="rp-doc">Batching</span></div><div class="rp-sidebar-item__right"></div></a><a href="/agent-device/docs/snapshots" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span class="rp-doc">Snapshots</span></div><div class="rp-sidebar-item__right"></div></a><a href="/agent-device/docs/replay-e2e" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span class="rp-doc">Replay &amp; E2E testing</span></div><div class="rp-sidebar-item__right"></div></a><a href="/agent-device/docs/debugging-profiling" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span class="rp-doc">Debugging &amp; Profiling</span></div><div class="rp-sidebar-item__right"></div></a></div></div><div class="rp-sidebar-item rp-sidebar-group" style="padding-left:12px" data-depth="0"><div class="rp-sidebar-item__left"><span class="rp-doc">Integrations</span></div><div class="rp-sidebar-item__right"></div></div><div style="display:grid;grid-template-rows:1fr;transition:grid-template-rows 0.2s ease-out"><div style="overflow:hidden"><a href="/agent-device/docs/client-api" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span class="rp-doc">Node.js API</span></div><div class="rp-sidebar-item__right"></div></a><a href="/agent-device/docs/ai-sdk" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span class="rp-doc">AI SDK</span></div><div class="rp-sidebar-item__right"></div></a><a href="/agent-device/docs/eve" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span class="rp-doc">Eve</span></div><div class="rp-sidebar-item__right"></div></a><a href="/agent-device/docs/remote-proxy" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span class="rp-doc">Remote Proxy</span></div><div class="rp-sidebar-item__right"></div></a><a href="/agent-device/docs/device-clouds" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span class="rp-doc">Device Clouds</span></div><div class="rp-sidebar-item__right"></div></a><a href="/agent-device/docs/browserstack" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span class="rp-doc">BrowserStack</span></div><div class="rp-sidebar-item__right"></div></a><a href="/agent-device/docs/aws-device-farm" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span class="rp-doc">AWS Device Farm</span></div><div class="rp-sidebar-item__right"></div></a><a href="/agent-device/docs/limrun" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span class="rp-doc">Limrun</span></div><div class="rp-sidebar-item__right"></div></a></div></div><div class="rp-sidebar-item rp-sidebar-group" style="padding-left:12px" data-depth="0"><div class="rp-sidebar-item__left"><span class="rp-doc">Reference</span></div><div class="rp-sidebar-item__right"></div></div><div style="display:grid;grid-template-rows:1fr;transition:grid-template-rows 0.2s ease-out"><div style="overflow:hidden"><a href="/agent-device/docs/security-trust" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span class="rp-doc">Security &amp; Trust</span></div><div class="rp-sidebar-item__right"></div></a><a href="/agent-device/docs/known-limitations" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span class="rp-doc">Known Limitations</span></div><div class="rp-sidebar-item__right"></div></a><a href="/agent-device/docs/migrating-gestures" class="rp-sidebar-item rp-sidebar-item--active rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span class="rp-doc">Migrating Gestures</span></div><div class="rp-sidebar-item__right"></div></a></div></div></aside><div class="rp-doc-layout__doc"><main class="rp-doc-layout__doc-container"><div class="rp-doc rspress-doc"><!--$--><h1 class="rp-toc-include" id="migrating-gestures"><a href="#migrating-gestures" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Migrating Gestures<!-- --> </h1><div class="rp-not-doc rp-llms-container"><button class="rp-not-doc rp-llms-button rp-llms-copy-button"><div class="rp-llms-copy-button__icon-wrapper"><svg xmlns="http://www.w3.org/2000/svg" width="271" height="271" viewBox="0 0 271 271" class="rp-llms-copy-button__icon-success"><path fill="currentColor" d="M112.687 203.223H90.174v-22.514h22.512v-22.514h22.512v22.514h-22.511zm-22.514-22.514H67.66v-22.514h22.513zm-22.514-22.514H45.146v-22.512H67.66zm90.054 0h-22.514v-22.512h22.514zm22.514-22.512h-22.514v-22.514h22.514zm22.513-22.514h-22.513V90.655h22.513zm22.514-22.514H202.74V68.143h22.514z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="272" height="272" viewBox="0 0 272 272" class="rp-llms-copy-button__icon-copy"><path fill="currentColor" fill-rule="evenodd" d="M45.883 23.368h123.823v22.514H68.396v146.336H45.883zm45.026 45.027H225.99v180.107H90.91zm22.514 22.513v135.08h90.053V90.908z" clip-rule="evenodd"></path></svg></div><span>Copy Markdown</span></button><button class="rp-llms-button rp-llms-view-options__trigger "><svg xmlns="http://www.w3.org/2000/svg" width="12" height="13" viewBox="0 0 12 13" class="rp-llms-view-options__arrow "><path fill="currentColor" d="M6.5 8.5h1v1h-1v1h-1v-1h-1v-1h1v-6h1zm-2 0h-1v-1h1zm4 0h-1v-1h1zm-5-2v1h-1v-1zm6 1h-1v-1h1z"></path></svg></button></div>
<p><code>agent-device</code> 0.20.0 removed the timed forms of <code>swipe</code>, <code>gesture fling</code>, and <code>gesture swipe</code>, and
the <code>velocity</code> argument of <code>gesture rotate</code>. Nothing is silently reinterpreted: every removed form
now fails with an <code>INVALID_ARGS</code> error that names its replacement.</p>
<p>This page is the migration for all four public surfaces — CLI, Node.js, MCP, and saved <code>.ad</code>
recordings — plus the policy that governs the next such removal.</p>
<h2 class="rp-toc-include" id="what-changed"><a href="#what-changed" class="rp-header-anchor rp-link" aria-hidden="true">#</a>What changed</h2>
<p>Gesture vocabulary now separates a <em>throw</em> from a <em>deliberate drag</em>:</p>
<ul>
<li><code>swipe</code> and <code>gesture fling</code> are quick, fixed-duration directional throws. They do not take a
duration, because a caller-supplied duration made them something else.</li>
<li><code>gesture pan</code> is the deliberate timed translation. It keeps <code>durationMs</code>.</li>
<li><code>gesture rotate</code> derives its pacing from the requested <code>degrees</code>.</li>
</ul>
<p><code>durationMs</code> remains on <code>gesture pan</code> and <code>gesture transform</code>.</p>
<h2 class="rp-toc-include" id="cli"><a href="#cli" class="rp-header-anchor rp-link" aria-hidden="true">#</a>CLI</h2>
<div class="rp-table-scroll-container rp-scrollbar"><table><thead><tr><th>Removed</th><th>Use instead</th></tr></thead><tbody><tr><td><code>swipe x1 y1 x2 y2 durationMs</code></td><td><code>gesture pan x1 y1 dx dy durationMs</code></td></tr><tr><td><code>gesture fling &lt;direction&gt; x y distance durationMs</code></td><td><code>gesture fling &lt;direction&gt; x y distance</code></td></tr><tr><td><code>gesture swipe &lt;preset&gt; durationMs</code></td><td><code>gesture swipe &lt;preset&gt;</code></td></tr><tr><td><code>gesture rotate degrees x y velocity</code></td><td><code>gesture rotate degrees x y</code></td></tr></tbody></table></div>
<p><code>gesture pan</code> takes an origin plus a <strong>delta</strong>, where <code>swipe</code> took two absolute points, so
<code>dx = x2 - x1</code> and <code>dy = y2 - y1</code>:</p>
<div class="rp-codeblock language-bash"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="bash"><code><span class="line"><span style="color:var(--shiki-token-comment)"># before</span></span>
<span class="line"><span style="color:var(--shiki-token-function)">agent-device</span><span style="color:var(--shiki-token-string)"> swipe</span><span style="color:var(--shiki-token-constant)"> 197</span><span style="color:var(--shiki-token-constant)"> 650</span><span style="color:var(--shiki-token-constant)"> 197</span><span style="color:var(--shiki-token-constant)"> 300</span><span style="color:var(--shiki-token-constant)"> 300</span></span>
<span class="line"><span style="color:var(--shiki-token-comment)"># after — same motion, same 300ms</span></span>
<span class="line"><span style="color:var(--shiki-token-function)">agent-device</span><span style="color:var(--shiki-token-string)"> gesture</span><span style="color:var(--shiki-token-string)"> pan</span><span style="color:var(--shiki-token-constant)"> 197</span><span style="color:var(--shiki-token-constant)"> 650</span><span style="color:var(--shiki-token-constant)"> 0</span><span style="color:var(--shiki-token-string)"> -350</span><span style="color:var(--shiki-token-constant)"> 300</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="Copy code"><svg xmlns="http://www.w3.org/2000/svg" width="272" height="272" viewBox="0 0 272 272" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" fill-rule="evenodd" d="M45.883 23.368h123.823v22.514H68.396v146.336H45.883zm45.026 45.027H225.99v180.107H90.91zm22.514 22.513v135.08h90.053V90.908z" clip-rule="evenodd"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="271" height="271" viewBox="0 0 271 271" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="M112.687 203.223H90.174v-22.514h22.512v-22.514h22.512v22.514h-22.511zm-22.514-22.514H67.66v-22.514h22.513zm-22.514-22.514H45.146v-22.512H67.66zm90.054 0h-22.514v-22.512h22.514zm22.514-22.512h-22.514v-22.514h22.514zm22.513-22.514h-22.513V90.655h22.513zm22.514-22.514H202.74V68.143h22.514z"></path></svg></button></div></div></div>
<p>Drop the duration instead when the timing was incidental and a throw is what you wanted. The
resulting gesture is a 100ms fling, which travels further on a scrollable list than a 300ms drag
over the same distance:</p>
<div class="rp-codeblock language-bash"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="bash"><code><span class="line"><span style="color:var(--shiki-token-function)">agent-device</span><span style="color:var(--shiki-token-string)"> swipe</span><span style="color:var(--shiki-token-constant)"> 197</span><span style="color:var(--shiki-token-constant)"> 650</span><span style="color:var(--shiki-token-constant)"> 197</span><span style="color:var(--shiki-token-constant)"> 300</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="Copy code"><svg xmlns="http://www.w3.org/2000/svg" width="272" height="272" viewBox="0 0 272 272" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" fill-rule="evenodd" d="M45.883 23.368h123.823v22.514H68.396v146.336H45.883zm45.026 45.027H225.99v180.107H90.91zm22.514 22.513v135.08h90.053V90.908z" clip-rule="evenodd"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="271" height="271" viewBox="0 0 271 271" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="M112.687 203.223H90.174v-22.514h22.512v-22.514h22.512v22.514h-22.511zm-22.514-22.514H67.66v-22.514h22.513zm-22.514-22.514H45.146v-22.512H67.66zm90.054 0h-22.514v-22.512h22.514zm22.514-22.512h-22.514v-22.514h22.514zm22.513-22.514h-22.513V90.655h22.513zm22.514-22.514H202.74V68.143h22.514z"></path></svg></button></div></div></div>
<p>The error message computes this for you:</p>
<div class="rp-codeblock language-txt"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="txt"><code><span class="line"><span>swipe accepts 4 arguments: x1 y1 x2 y2. The trailing durationMs positional was removed:</span></span>
<span class="line"><span>use &quot;gesture pan 197 650 0 -350 300&quot; for the same timed drag, or &quot;swipe 197 650 197 300&quot;</span></span>
<span class="line"><span>for a default-duration swipe.</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="Copy code"><svg xmlns="http://www.w3.org/2000/svg" width="272" height="272" viewBox="0 0 272 272" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" fill-rule="evenodd" d="M45.883 23.368h123.823v22.514H68.396v146.336H45.883zm45.026 45.027H225.99v180.107H90.91zm22.514 22.513v135.08h90.053V90.908z" clip-rule="evenodd"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="271" height="271" viewBox="0 0 271 271" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="M112.687 203.223H90.174v-22.514h22.512v-22.514h22.512v22.514h-22.511zm-22.514-22.514H67.66v-22.514h22.513zm-22.514-22.514H45.146v-22.512H67.66zm90.054 0h-22.514v-22.512h22.514zm22.514-22.512h-22.514v-22.514h22.514zm22.513-22.514h-22.513V90.655h22.513zm22.514-22.514H202.74V68.143h22.514z"></path></svg></button></div></div></div>
<h2 class="rp-toc-include" id="nodejs"><a href="#nodejs" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Node.js</h2>
<p><code>interactions.swipe</code>, <code>interactions.fling</code>, and <code>interactions.swipeGesture</code> no longer accept
<code>durationMs</code>; <code>interactions.rotateGesture</code> no longer accepts <code>velocity</code>. Passing them is a type
error at compile time and an <code>INVALID_ARGS</code> rejection at runtime — the rejection happens
client-side, before the request reaches the daemon, so a plain JavaScript caller or a stale
compiled build gets the error rather than a silently retimed gesture.</p>
<div class="rp-codeblock language-ts"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="ts"><code><span class="line"><span style="color:var(--shiki-token-comment)">// before</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">await</span><span style="color:var(--shiki-token-constant)"> device</span><span style="color:var(--shiki-token-function)">.</span><span style="color:var(--shiki-token-constant)">interactions</span><span style="color:var(--shiki-token-function)">.swipe</span><span style="color:var(--shiki-foreground)">({</span></span>
<span class="line"><span style="color:var(--shiki-foreground)"> from</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> { x</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> 197</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> y</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> 650</span><span style="color:var(--shiki-foreground)"> }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)"> to</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> { x</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> 197</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> y</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> 300</span><span style="color:var(--shiki-foreground)"> }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)"> durationMs</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> 300</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">});</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-comment)">// after — same motion, same 300ms</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">await</span><span style="color:var(--shiki-token-constant)"> device</span><span style="color:var(--shiki-token-function)">.</span><span style="color:var(--shiki-token-constant)">interactions</span><span style="color:var(--shiki-token-function)">.pan</span><span style="color:var(--shiki-foreground)">({ x</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> 197</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> y</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> 650</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> dx</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> 0</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> dy</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-keyword)"> -</span><span style="color:var(--shiki-token-constant)">350</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> durationMs</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> 300</span><span style="color:var(--shiki-foreground)"> });</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-comment)">// after — a default-duration throw</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">await</span><span style="color:var(--shiki-token-constant)"> device</span><span style="color:var(--shiki-token-function)">.</span><span style="color:var(--shiki-token-constant)">interactions</span><span style="color:var(--shiki-token-function)">.swipe</span><span style="color:var(--shiki-foreground)">({ from</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> { x</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> 197</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> y</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> 650</span><span style="color:var(--shiki-foreground)"> }</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> to</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> { x</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> 197</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> y</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> 300</span><span style="color:var(--shiki-foreground)"> } });</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="Copy code"><svg xmlns="http://www.w3.org/2000/svg" width="272" height="272" viewBox="0 0 272 272" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" fill-rule="evenodd" d="M45.883 23.368h123.823v22.514H68.396v146.336H45.883zm45.026 45.027H225.99v180.107H90.91zm22.514 22.513v135.08h90.053V90.908z" clip-rule="evenodd"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="271" height="271" viewBox="0 0 271 271" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="M112.687 203.223H90.174v-22.514h22.512v-22.514h22.512v22.514h-22.511zm-22.514-22.514H67.66v-22.514h22.513zm-22.514-22.514H45.146v-22.512H67.66zm90.054 0h-22.514v-22.512h22.514zm22.514-22.512h-22.514v-22.514h22.514zm22.513-22.514h-22.513V90.655h22.513zm22.514-22.514H202.74V68.143h22.514z"></path></svg></button></div></div></div>
<p><code>interactions.pan</code> and <code>interactions.transformGesture</code> keep <code>durationMs</code>.</p>
<h2 class="rp-toc-include" id="mcp"><a href="#mcp" class="rp-header-anchor rp-link" aria-hidden="true">#</a>MCP</h2>
<p>The <code>swipe</code>, <code>gesture</code> (<code>fling</code>, <code>swipe</code> kinds), and <code>gesture rotate</code> tool schemas no longer
advertise <code>durationMs</code> or <code>velocity</code>, so an agent reading the schema will not produce the removed
form. An agent that sends one anyway — from a cached schema or a memorized example — gets an
<code>INVALID_ARGS</code> rejection that names the removed key and the command to use instead, for example
<code>gesture fling does not accept durationMs; use gesture pan for timed movement</code>. This is the
structured-input equivalent of the CLI error; it names the replacement command but, unlike the CLI
and <code>.ad</code> messages, does not echo a fully-substituted rewrite, because the structured request
carries no positional string to rewrite.</p>
<p>No MCP server configuration changes.</p>
<h2 class="rp-toc-include" id="saved-ad-recordings"><a href="#saved-ad-recordings" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Saved <code>.ad</code> recordings</h2>
<p><code>.ad</code> scripts keep their positional syntax: it is the same vocabulary as the CLI, and it is not
scheduled for removal (see <a href="#positional-ad-syntax" class="rp-link">Positional <code>.ad</code> syntax</a> below). Only the removed
arguments have to go.</p>
<p>A script that still carries one fails <strong>when it is parsed</strong>, before the replay executes any device
action, and the error names the line:</p>
<div class="rp-codeblock language-txt"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="txt"><code><span class="line"><span>Error (INVALID_ARGS): swipe accepts 4 arguments: x1 y1 x2 y2 (line 6). The trailing durationMs</span></span>
<span class="line"><span>positional was removed: use &quot;gesture pan 197 650 0 -350 300&quot; for the same timed drag, or</span></span>
<span class="line"><span>&quot;swipe 197 650 197 300&quot; for a default-duration swipe.</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="Copy code"><svg xmlns="http://www.w3.org/2000/svg" width="272" height="272" viewBox="0 0 272 272" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" fill-rule="evenodd" d="M45.883 23.368h123.823v22.514H68.396v146.336H45.883zm45.026 45.027H225.99v180.107H90.91zm22.514 22.513v135.08h90.053V90.908z" clip-rule="evenodd"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="271" height="271" viewBox="0 0 271 271" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="M112.687 203.223H90.174v-22.514h22.512v-22.514h22.512v22.514h-22.511zm-22.514-22.514H67.66v-22.514h22.513zm-22.514-22.514H45.146v-22.512H67.66zm90.054 0h-22.514v-22.512h22.514zm22.514-22.512h-22.514v-22.514h22.514zm22.513-22.514h-22.513V90.655h22.513zm22.514-22.514H202.74V68.143h22.514z"></path></svg></button></div></div></div>
<p>Apply the same rewrites as the CLI table above. Flags are unaffected: <code>--count</code>, <code>--pause-ms</code>, and
<code>--pattern</code> stay on <code>swipe</code>, and <code>--pointer-count</code> stays on <code>gesture pan</code>.</p>
<div class="rp-codeblock language-txt"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="txt"><code><span class="line"><span># before</span></span>
<span class="line"><span>swipe 206 650 206 300 300 --count 2 --pause-ms 200 --pattern one-way</span></span>
<span class="line"><span># after</span></span>
<span class="line"><span>swipe 206 650 206 300 --count 2 --pause-ms 200 --pattern one-way</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="Copy code"><svg xmlns="http://www.w3.org/2000/svg" width="272" height="272" viewBox="0 0 272 272" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" fill-rule="evenodd" d="M45.883 23.368h123.823v22.514H68.396v146.336H45.883zm45.026 45.027H225.99v180.107H90.91zm22.514 22.513v135.08h90.053V90.908z" clip-rule="evenodd"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="271" height="271" viewBox="0 0 271 271" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="M112.687 203.223H90.174v-22.514h22.512v-22.514h22.512v22.514h-22.511zm-22.514-22.514H67.66v-22.514h22.513zm-22.514-22.514H45.146v-22.512H67.66zm90.054 0h-22.514v-22.512h22.514zm22.514-22.512h-22.514v-22.514h22.514zm22.513-22.514h-22.513V90.655h22.513zm22.514-22.514H202.74V68.143h22.514z"></path></svg></button></div></div></div>
<p>A duration held in a variable (<code>swipe 197 650 197 300 ${DURATION}</code>) is reported the same way — the
preflight counts arguments, so it does not need the value.</p>
<p><strong>The authoritative check is the parser itself.</strong> Every retired form is rejected when the script is
parsed, before the replay runs any device action, so running the suite (<code>agent-device test &lt;glob&gt;</code>,
or <code>agent-device replay &lt;file&gt;.ad</code>) finds every stale line by construction and names it — a missed
grep can never let one reach execution. The patterns below are a bulk pre-flight to locate them
without a device. They follow the <code>.ad</code> tokenizer: tokens are separated by any whitespace (space or
tab), and the numeric slots accept a bare or double-quoted number or <code>${VAR}</code> — so
<code>swipe\t…\t&quot;300&quot;</code> is flagged like <code>swipe … 300</code>. They still stop short of the tokenizer&#x27;s rarer
encodings (a quoted command word, backslash escapes inside a quoted token), which is why the parser,
not the grep, is the gate.</p>
<div class="rp-codeblock language-bash"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="bash"><code><span class="line"><span style="color:var(--shiki-token-comment)"># a numeric slot: bare/quoted number (optionally signed) or ${VAR}. Requiring a</span></span>
<span class="line"><span style="color:var(--shiki-token-comment)"># digit keeps a following flag like --count from being read as the retired slot.</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">num</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-token-string-expression)">&#x27;(&quot;-?[0-9][0-9.]*&quot;|&quot;\$\{[^}]*\}&quot;|-?[0-9][0-9.]*|\$\{[^}]*\})&#x27;</span></span>
<span class="line"><span style="color:var(--shiki-token-comment)"># swipe x1 y1 x2 y2 durationMs</span></span>
<span class="line"><span style="color:var(--shiki-token-function)">grep</span><span style="color:var(--shiki-token-string)"> -rnE</span><span style="color:var(--shiki-token-string-expression)"> &quot;\\bswipe([[:space:]]+$num){5}&quot;</span><span style="color:var(--shiki-token-string)"> --include=</span><span style="color:var(--shiki-token-string-expression)">&#x27;*.ad&#x27;</span><span style="color:var(--shiki-token-string)"> .</span></span>
<span class="line"><span style="color:var(--shiki-token-comment)"># gesture fling &lt;direction&gt; x y distance durationMs</span></span>
<span class="line"><span style="color:var(--shiki-token-function)">grep</span><span style="color:var(--shiki-token-string)"> -rnE</span><span style="color:var(--shiki-token-string-expression)"> &quot;\\bgesture[[:space:]]+fling[[:space:]]+\&quot;?[a-z]+\&quot;?([[:space:]]+$num){4}&quot;</span><span style="color:var(--shiki-token-string)"> --include=</span><span style="color:var(--shiki-token-string-expression)">&#x27;*.ad&#x27;</span><span style="color:var(--shiki-token-string)"> .</span></span>
<span class="line"><span style="color:var(--shiki-token-comment)"># gesture swipe &lt;preset&gt; durationMs</span></span>
<span class="line"><span style="color:var(--shiki-token-function)">grep</span><span style="color:var(--shiki-token-string)"> -rnE</span><span style="color:var(--shiki-token-string-expression)"> &quot;\\bgesture[[:space:]]+swipe[[:space:]]+\&quot;?[a-z-]+\&quot;?[[:space:]]+$num&quot;</span><span style="color:var(--shiki-token-string)"> --include=</span><span style="color:var(--shiki-token-string-expression)">&#x27;*.ad&#x27;</span><span style="color:var(--shiki-token-string)"> .</span></span>
<span class="line"><span style="color:var(--shiki-token-comment)"># gesture rotate degrees x y velocity</span></span>
<span class="line"><span style="color:var(--shiki-token-function)">grep</span><span style="color:var(--shiki-token-string)"> -rnE</span><span style="color:var(--shiki-token-string-expression)"> &quot;\\bgesture[[:space:]]+rotate([[:space:]]+$num){4}&quot;</span><span style="color:var(--shiki-token-string)"> --include=</span><span style="color:var(--shiki-token-string-expression)">&#x27;*.ad&#x27;</span><span style="color:var(--shiki-token-string)"> .</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="Copy code"><svg xmlns="http://www.w3.org/2000/svg" width="272" height="272" viewBox="0 0 272 272" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" fill-rule="evenodd" d="M45.883 23.368h123.823v22.514H68.396v146.336H45.883zm45.026 45.027H225.99v180.107H90.91zm22.514 22.513v135.08h90.053V90.908z" clip-rule="evenodd"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="271" height="271" viewBox="0 0 271 271" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="M112.687 203.223H90.174v-22.514h22.512v-22.514h22.512v22.514h-22.511zm-22.514-22.514H67.66v-22.514h22.513zm-22.514-22.514H45.146v-22.512H67.66zm90.054 0h-22.514v-22.512h22.514zm22.514-22.512h-22.514v-22.514h22.514zm22.513-22.514h-22.513V90.655h22.513zm22.514-22.514H202.74V68.143h22.514z"></path></svg></button></div></div></div>
<p>Re-recording also produces a migrated script: the recorder writes the canonical form, so a fresh
<code>open --save-script</code> → interact → <code>close</code> run is a valid alternative to editing by hand. Recording
evidence is only captured from action zero, so arm at <code>open</code>; a bare <code>close --save-script</code> on a
session that was not armed at <code>open</code> is rejected.</p>
<h3 class="rp-toc-include" id="maestro-flows"><a href="#maestro-flows" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Maestro flows</h3>
<p>Maestro <code>swipe</code> with a <code>duration</code> is <strong>not</strong> affected. <code>agent-device</code> runs Maestro YAML through its
own compatibility engine, which normalizes a timed Maestro swipe to the canonical <code>gesture pan</code>
input and preserves Maestro&#x27;s fast-swipe-then-hold execution profile. Maestro flows need no
migration.</p>
<p><code>replay export</code> writes an explicit <code>duration: 100</code> — the canonical fling duration — so an exported
flow runs at the speed the <code>.ad</code> script ran, rather than picking up Maestro&#x27;s own 400ms default.</p>
<h2 class="rp-toc-include" id="deprecation-policy"><a href="#deprecation-policy" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Deprecation policy</h2>
<p>This is the process a public gesture input follows on its way out, and the bar the next removal has
to clear:</p>
<ol>
<li><strong>Announce.</strong> The input is documented as deprecated and recorded in <code>CHANGELOG.md</code> under
<code>Unreleased</code>, together with the replacement.</li>
<li><strong>Warn for one minor release.</strong> The input keeps working and normalizes to the replacement, with a
<code>deprecations</code> entry in the response so an agent sees the migration while the call still
succeeds.</li>
<li><strong>Publish the migration.</strong> A section on this page covers CLI, Node.js, MCP, and <code>.ad</code>, with a
concrete before/after per surface.</li>
<li><strong>Prove the repository is clean.</strong> A repository-wide search for the removed shape returns no hits
in fixtures, examples, skills, docs, or tests. <code>agent-device</code> has no usage telemetry, so this
search — plus the migration guide&#x27;s publication — is the evidence, and it is the reason the
removal cannot be inferred from &quot;nobody complained&quot;.</li>
<li><strong>Remove.</strong> The input is rejected with an <code>INVALID_ARGS</code> error that states the replacement, and
the normalization branch and its compatibility tests are deleted in the same change. For an input
that can appear in a saved recording, the rejection must fire at parse time and name the line, so
a stale script never half-executes.</li>
</ol>
<p>The 0.20.0 removal completed all five steps.</p>
<h2 class="rp-toc-include" id="positional-ad-syntax"><a href="#positional-ad-syntax" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Positional <code>.ad</code> syntax</h2>
<p>Positional gesture parsing in <code>.ad</code> is <strong>not</strong> a compatibility shim and is not scheduled for
removal.</p>
<p><code>.ad</code> is a line-based script format whose syntax is the CLI&#x27;s syntax. Its gesture codec —
<code>gesturePayloadFromPositionals</code> / <code>gesturePayloadToPositionals</code> — is what defines the file format,
not a bridge to an older one. CLI, Node.js, and MCP already send structured input directly; the
codec&#x27;s only remaining jobs are parsing CLI argv and reading and writing <code>.ad</code> lines, and both are
the current public syntax. Replacing it with a structured payload would make recordings
unreadable and ungreppable for no behavioral gain.</p>
<p>See <a href="https://github.com/callstack/agent-device/blob/main/docs/adr/0013-unified-gesture-plans.md" target="_blank" rel="noopener noreferrer" class="rp-link">ADR 0013</a>
for the gesture normalization and planning model this rests on.</p><!--/$--></div><div class="container-uhcWmO"><img class="logo-IwzwG8" src="/agent-device/static/image/abstract-atom.4eca0300ff.avif" alt="Abstract Logo" aria-hidden="true"/><div class="content-uJxcIj"><div class="headlineContainer-NHNT4y"><h1 class="headline-iCUUUl">Need React or React Native
expertise you can count on?</h1></div><div class="buttonContainer-wOj8Y6"><div class="dark"><a href="https://www.callstack.com/contact?utm_campaign=open_source&amp;utm_source=agent-device&amp;utm_medium=referral&amp;utm_content=FOOTER_CTA" class="button-DogSnd brand-rT2ahT ">Let&#x27;s talk<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" viewBox="0 0 16 16" class="button-icon-Okk0hT" aria-hidden="true" focusable="false"><path fill="currentColor" d="M9.333 13.333h1.334V12H9.333zm-6.666-2.666h8V12H12v-1.333h1.333V9.333H12V8h-1.333v1.333H4V2.667H2.667zM9.333 8h1.334V6.667H9.333z"></path></svg></a></div></div></div></div><footer class="rp-doc-footer"><div class="rp-doc-footer__edit"><a href="https://github.com/callstack/agent-device/edit/main/website/docs/migrating-gestures.md" target="_blank" rel="noopener noreferrer" class="rp-edit-link rp-link">Edit this page on GitHub</a></div><div class="rp-doc-footer__divider"></div><div class="container-aZLxg0"><a href="/agent-device/docs/known-limitations" class="pagerLink-_WIlZJ rp-link"><span class="iconBox-AUO0Le"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 24 24" class="icon-WRLCnG"><path d="M4 20h2V4H4zm8-5v2h2v-2zm-2-4H8v2h2v2h2v-2h8v-2h-8V9h-2zm2-2h2V7h-2z"></path></svg></span><span class="textWrap-lmdyLc"><span class="desc-sp3vRh">Previous page</span><span class="title-hrit_i">Known Limitations</span></span></a><div class="placeholder-V1DSp3"></div></div></footer></main></div><aside class="rp-doc-layout__outline rp-scrollbar"><div class="rp-outline"><div class="rp-outline__title">Contents<svg width="14" height="14" class="rp-progress-circle"><circle cx="7" cy="7" r="6" stroke-linecap="round" fill="none" stroke="var(--rp-c-divider-light)" stroke-width="2"></circle><circle cx="7" cy="7" r="6" stroke-linecap="round" fill="none" stroke="var(--rp-c-brand)" stroke-width="2" stroke-dasharray="37.69911184307752" stroke-dashoffset="37.69911184307752" transform="rotate(-90 7 7)" style="transition:stroke-dashoffset 0.3s"></circle></svg></div><nav class="rp-outline__toc rp-scrollbar"><a href="#what-changed" class="rp-toc-item rp-link" title="What changed" style="padding-left:0" data-depth="0"><span class="rp-toc-item__text rp-doc">What changed</span></a><a href="#cli" class="rp-toc-item rp-link" title="CLI" style="padding-left:0" data-depth="0"><span class="rp-toc-item__text rp-doc">CLI</span></a><a href="#nodejs" class="rp-toc-item rp-link" title="Node.js" style="padding-left:0" data-depth="0"><span class="rp-toc-item__text rp-doc">Node.js</span></a><a href="#mcp" class="rp-toc-item rp-link" title="MCP" style="padding-left:0" data-depth="0"><span class="rp-toc-item__text rp-doc">MCP</span></a><a href="#saved-ad-recordings" class="rp-toc-item rp-link" title="Saved .ad recordings" style="padding-left:0" data-depth="0"><span class="rp-toc-item__text rp-doc">Saved <code>.ad</code> recordings</span></a><a href="#maestro-flows" class="rp-toc-item rp-link" title="Maestro flows" style="padding-left:12px" data-depth="1"><span class="rp-toc-item__text rp-doc">Maestro flows</span></a><a href="#deprecation-policy" class="rp-toc-item rp-link" title="Deprecation policy" style="padding-left:0" data-depth="0"><span class="rp-toc-item__text rp-doc">Deprecation policy</span></a><a href="#positional-ad-syntax" class="rp-toc-item rp-link" title="Positional .ad syntax" style="padding-left:0" data-depth="0"><span class="rp-toc-item__text rp-doc">Positional <code>.ad</code> syntax</span></a></nav><div class="rp-outline__divider"></div><div class="rp-outline__bottom"><a href="https://github.com/callstack/agent-device/edit/main/website/docs/migrating-gestures.md" target="_blank" rel="noopener noreferrer" class="rp-outline__action-row rp-edit-link rp-link"><svg width="16" height="16" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24"><path d="M17 3a2.828 2.828 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5z"></path></svg><span>Edit this page on GitHub</span></a></div></div><div class="container-LzbylO"><div><div class="headline-y75_LS">Curious about developing mobile apps with AI agents?</div><div class="description-muYVs3">We can help you take your agentic workflows to the next level and ship faster.</div></div><a href="https://www.callstack.com/contact?utm_campaign=open_source&amp;utm_source=agent-device&amp;utm_medium=referral&amp;utm_content=OUTLINE_CTA" class="button-DogSnd brand-rT2ahT ">Book a call<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" viewBox="0 0 16 16" class="button-icon-Okk0hT" aria-hidden="true" focusable="false"><path fill="currentColor" d="M9.333 13.333h1.334V12H9.333zm-6.666-2.666h8V12H12v-1.333h1.333V9.333H12V8h-1.333v1.333H4V2.667H2.667zM9.333 8h1.334V6.667H9.333z"></path></svg></a></div></aside></div></div>
<div id="__rspress_modal_container"></div>
</body>
</html>