- name
- lynx-devtool
- description
- Use when working with Lynx DevTool or debugging a Lynx app, page, or device, especially when the task mentions clients or sessions, CDP or App commands, DOM/CSS inspection, runtime or console logs, evaluating JavaScript on a device, screenshots, heap snapshots, performance traces, Page.reload or App.openPage, global switches, interactive snapshot refs and taps/fills/scrolls, inspecting or searching a ReactLynx component tree, linking DOM Snapshot refs to ReactLynx components (`reactlynx link`), or mutating ReactLynx props/state/context on Android, iOS, or Desktop.
# Agent Lynx DevTool Skill
This skill allows you to interact with Lynx applications running on connected devices (Android, iOS, Desktop) using the `agent-lynx` CLI.
## Usage
Use the `agent-lynx` CLI. The published package is `agent-lynx`.
This package, `@lynx-js/skill-lynx-devtool`, is the canonical source of this
Skill's instructions and resources. `agent-lynx` depends on it and reads it
directly for `skills list/get`. A compatibility launcher also keeps the historic
one-shot `npx -y @lynx-js/skill-lynx-devtool` invocation working.
The programmatic API is exported from `agent-lynx/connector`. This entry re-exports everything from `@lynx-js/devtool-connector`, `@lynx-js/devtool-connector/transport`, and `@lynx-js/devtool-connector/streams`, and also provides daemon-only `createDefaultTransports()` and `createDefaultConnector()` helpers. The helpers use one `DaemonTransport` so independent scripts share the daemon-owned device connection. Construct a `Connector` with explicit transports only when intentionally testing a non-daemon path.
Online CLI commands follow the same daemon-only default. `--no-daemon` is an
explicit escape hatch that replaces the daemon with direct Android, iOS,
OpenHarmony, and Desktop transports for that invocation. The built-in headless
runtime remains daemon-only. `ADB_SERVER_HOST` and `ADB_SERVER_PORT` configure
only this direct mode. Daemon mode ignores them with a stderr warning.
The `agent-lynx` CLI is normally available on `PATH`. If
`command -v agent-lynx` fails, use `npx` instead:
```bash
npx --yes agent-lynx <command>
```
This published skill does not ship a local CLI entry script. Use:
```bash
agent-lynx <command>
```
**Note:** Most command outputs are JSON. You can use `jq` or Node.js to process the data.
### Discover Built-in Skills
The installed `@lynx-js/skill-lynx-devtool` dependency provides the
`lynx-devtool` skill. Discover it or load its complete instructions with:
```bash
agent-lynx skills list
agent-lynx skills get lynx-devtool
```
`skills list` reads each name and description directly from that package's
`SKILL.md` YAML frontmatter. `skills get` returns the selected Markdown body and
recursively lists regular files under `references/`, `assets/`, and `examples/`
when those directories exist. Symlinks and build output are not included. The
stable name is `lynx-devtool`.
### Snapshot Workflow
```bash
agent-lynx snapshot
agent-lynx tap @e3 --snapshot
agent-lynx fill @e1 "Alice"
agent-lynx clear @e1
agent-lynx scroll @e2 --direction down
agent-lynx get text @e3
agent-lynx get style @e3 --property color,width
agent-lynx wait --text Ready
agent-lynx screenshot --annotate -o page.jpeg
```
Snapshot refs live in daemon memory across CLI invocations. Do not pass
`--no-daemon` to `snapshot`, `tap`, `long-press`, `fill`, `clear`, `scroll`,
`get text`, `get style`, `wait`, or `screenshot`. `wait` uses the daemon's SSE
command route; the other snapshot commands use `POST /command/<action>`.
`screenshot --annotate` refreshes and caches snapshot refs, then draws numbered
labels directly into one JPEG. Label `[N]` maps to ref `@eN`, so an agent can
inspect the image and immediately use the matching ref. The image labels a
sparse actionable subset of the visible refs: direct action targets, editable
fields, explicit test targets, and scroll containers. Generic layout and text
refs remain available in the cached snapshot without cluttering the image.
Viewport-sized scroll containers use a corner badge instead of a full-frame
border. With `--json`, the result also carries the complete fresh snapshot used
by this same ActionCore call, so consumers can compare the image and refs
without issuing a second refresh. Pixel mapping uses the screencast frame's
logical-size metadata separately from the potentially inset snapshot viewport;
the command fails instead of guessing when that metadata is unavailable. Do not
combine `--annotate` with `--fullscreen`; use unannotated
`screenshot --fullscreen` or the legacy
`take-screenshot --fullscreen` command instead. See
[Annotated Screenshots Reference](references/screenshot-annotate.md).
Programmatic connector imports require a project dependency:
```bash
npm install agent-lynx
```
This project-local install is needed only for connector workflows, not for
CLI-only use through the `agent-lynx` CLI on `PATH` or `npx`.
### Use as a Library
If you want to drive Lynx DevTool directly from JavaScript instead of shelling out to the CLI, import from `agent-lynx/connector`.
```js
import { Connector, createDefaultConnector } from "agent-lynx/connector";
const connector = createDefaultConnector();
const clients = await connector.listClients();
console.log(clients);
```
For fuller programmatic workflows, see [Library Usage Reference](references/library-usage.md) and [Programmatic Debugging Example](examples/programmatic-debugging.md).
You can also construct the connector manually if you intentionally need custom, non-daemon transports:
```js
import {
AndroidTransport,
Connector,
DesktopTransport,
iOSTransport,
} from "agent-lynx/connector";
const connector = new Connector([
new AndroidTransport({ host: "127.0.0.1", port: 5037 }),
new DesktopTransport(),
new iOSTransport(),
]);
```
### Global Options
- `-h, --help`: Display help for command.
- `--no-daemon`: Bypass the shared daemon and use direct device transports for this invocation. Stop the daemon first if it may own a connection to the same DebugRouter target.
**Note:** Each subcommand supports the `--help` flag (e.g. `agent-lynx cdp --help`). Use this to view the full list of available arguments and their descriptions.
### Commands
#### 1. List Clients
List all available Lynx clients (apps with DevTool enabled).
```bash
agent-lynx list-clients
```
#### 2. Wait For Client
Wait until a client is available.
```bash
agent-lynx wait-for-client --client-name com.lynx.uiapp
```
- `--client-name <name>`: Optional package/app name to wait for. Matches `AppProcessName`, `bundleId`, `bundleName`, or `App`. If multiple clients match, all matching clients are returned. If omitted, the first non-headless client is returned. Output is always a JSON array.
- `--timeout <seconds>`: Maximum seconds to wait. Defaults to `30`.
- `--interval <seconds>`: Seconds between discovery attempts. Defaults to `1`.
#### 3. List Sessions
List all active debugging sessions. A session corresponds to a specific Lynx view or context.
```bash
agent-lynx list-sessions
# Optional: Filter by client ID
agent-lynx list-sessions --client <clientId>
```
#### 4. Send CDP Command
Send a Chrome DevTools Protocol (CDP) command to a specific session.
> Note that Lynx only supports a part of the standard CDP command.
> LynxView note: when the target session is a LynxView, you **MUST** read [Supported CDP Methods](references/cdp/index.md) before sending a CDP command.
> WebView note: when the target session is a WebView (for example `type: "web"` or an HTTP/HTTPS URL), use the standard Chrome DevTools Protocol documentation for CDP method names, parameters, and enable prerequisites. The local `references/cdp` pages focus on LynxView support and Lynx-specific extensions, which may return `method not found` on WebView targets.
```bash
agent-lynx cdp -m <method> [options] [params]
```
- `-m, --method <method>`: The CDP method name (e.g., `DOM.getDocument`, `Page.reload`).
- `-c, --client <clientId>`: (Optional) The Client ID. If omitted, uses the first available client.
- `-s, --session <sessionId>`: (Optional) The Session ID. If omitted, uses the latest session (with the largest session ID).
- `--thread <thread>`: (Optional) Target VM thread, `background` or `main`. Defaults to `background`.
- `[params]`: (Optional) JSON string of parameters for the command.
When `--thread main` is used, only `Debugger.*`, `Runtime.*`, `HeapProfiler.*`, and `Profiler.*` methods are supported.
Example:
```bash
# Get the document root
agent-lynx cdp -m DOM.getDocument
```
#### 5. Evaluate JavaScript
Evaluate a JavaScript expression. On the background VM, the current app's `lynx` and `nativeLynx` objects are available as local variables. Expressions targeting the main VM are sent unchanged.
```bash
agent-lynx evaluate 'JSON.stringify(lynx.__globalProps)'
agent-lynx evaluate '2 + 2' --thread main
agent-lynx evaluate 'lynx' --no-return-by-value
```
- `<expression>`: JavaScript expression to evaluate.
- `-c, --client <clientId>`: (Optional) Client ID.
- `-s, --session <sessionId>`: (Optional) Session ID.
- `--thread <thread>`: (Optional) Target VM thread, `background` or `main`. Defaults to `background`. Only background expressions are wrapped to expose `lynx` and `nativeLynx`; main-thread expressions are sent unchanged.
- The command requests results by value by default. Engines that support `returnByValue` serialize ordinary JSON-like objects into `result.value`; current Android Lynx runtimes may ignore it for object values and still return an `objectId`. Use `JSON.stringify(lynx.__globalProps)` when JSON output is desired. Use `--no-return-by-value` to deliberately receive an `objectId` for later `Runtime.getProperties` or `Runtime.callFunctionOn` requests. `--return-by-value` remains accepted as an explicit form of the default.
- `--silent`, `--context-id`, `--throw-on-side-effect`, `--generate-preview`, `--object-group`, `--await-promise`, `--include-command-line-api`: Optional evaluation parameters. Engine support varies.
#### 6. Send App Command
Send an App-level command.
```bash
agent-lynx app -m <method> [options] [params]
```
- `-m, --method <method>`: The App method name (e.g., `App.openPage`).
- `-c, --client <clientId>`: (Optional) Client ID.
- `[params]`: (Optional) JSON string of parameters.
> You **MUST** read [Supported App Methods](references/app/index.md) before sending an App command.
#### 7. Open URL
Open a specific URL in the Lynx app.
```bash
agent-lynx open <url> [options]
```
- `<url>`: The URL to open.
- `-c, --client <clientId>`: (Optional) Client ID.
Example:
```bash
agent-lynx open "lynx://example/page"
```
#### 8. Get Console
Capture console logs from the device.
```bash
agent-lynx get-console [options]
```
- `-c, --client <clientId>`: (Optional) Client ID.
- `-s, --session <sessionId>`: (Optional) Session ID.
- `--offset <number>`: Skip N messages.
- `--limit <number>`: Limit number of messages.
- `--include-stack-traces`: Include stack traces for non-error messages.
- `--level <levels>`: Filter log levels (e.g., `error,warning`).
- `--thread <thread...>`: Target VM thread(s): `background` or `main`. If omitted, both threads are collected by default.
#### 9. Get Sources
List all parsed scripts. This is useful for finding script IDs to use with other commands (e.g., `Debugger.getScriptSource`). The command automatically fetches all currently loaded scripts.
```bash
agent-lynx get-sources [options]
```
- `-c, --client <clientId>`: (Optional) Client ID.
- `-s, --session <sessionId>`: (Optional) Session ID.
#### 10. Inspect
Print the DevTool inspector URL served by the connector daemon for a
client/session pair. Open the printed URL in a browser to attach a graphical
inspector to the same session the CLI targets.
```bash
agent-lynx inspect [options]
```
- `-c, --client <clientId>`: (Optional) Client ID.
- `-s, --session <sessionId>`: (Optional) Session ID.
- `--port <port>`: (Optional) Daemon port. Defaults to `21783`.
#### 11. Agent Screenshot
Capture through ActionCore, optionally drawing fresh snapshot refs directly
into the resulting JPEG.
```bash
agent-lynx screenshot [options]
```
- `-c, --client <clientId>`: (Optional) Client ID.
- `-s, --session <sessionId>`: (Optional) Session ID.
- `--annotate`: (Optional) Refresh refs and draw `[N]` labels, where `[N]` maps to `@eN`.
- `--fullscreen`: (Optional) Capture fullscreen instead of LynxView. Cannot be combined with `--annotate`.
- `-o, --output <path>`: (Optional) JPEG output path.
- `--json`: (Optional) Return the path, image dimensions, complete fresh snapshot, and annotation metadata.
This command requires the persistent daemon. See
[Annotated Screenshots Reference](references/screenshot-annotate.md) for its
single-image output contract and target restrictions.
#### 12. Legacy Take Screenshot
Take a direct screenshot of the current page using the pre-Agent-Lynx command.
```bash
agent-lynx take-screenshot [options]
```
- `-c, --client <clientId>`: (Optional) Client ID.
- `-s, --session <sessionId>`: (Optional) Session ID.
- `--fullscreen`: (Optional) Capture the screenshot in `fullscreen` mode. Defaults to `lynxview` mode if not provided.
- `-o, --output <path>`: (Optional) Output file path.
#### 13. Take Content Screenshot
Capture the full scrollable content of the first node matching a CSS selector.
```bash
agent-lynx take-content-screenshot --selector <selector> [options]
```
- `--selector <selector>`: CSS selector for a `scroll-view` or compatible `list`. Required.
- `--format <jpeg|png>`: (Optional) Image format. Defaults to `jpeg`.
- `--scale <number>`: (Optional) Positive output scale. Defaults to `1`.
- `-c, --client <clientId>`: (Optional) Client ID.
- `-s, --session <sessionId>`: (Optional) Session ID.
- `-o, --output <path>`: (Optional) Output file path.
`takeContentScreenshot` is officially defined for `scroll-view`. The command accepts any CSS selector so runtimes that expose the same method on `list` can also be used; unsupported nodes return the UI Method failure.
See [Take Content Screenshot Reference](references/take-content-screenshot.md) for behavior and examples.
#### 14. Global Switch
View on GitHub