AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified Apache-2.0 Self-run

Lynx Devtool

skill-lynx-community-skills-lynx-devtool · by lynx-community

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, screenshots, heap snapshots, Page.reload or App.openPage, global switches, or inspecting a ReactLynx component tree (`reactlynx tree`), searching components (`reactlynx find`), inspecting props/state/h…

No reviews yet
0 installs
22 views
0.0% view→install

Install

$ agentstack add skill-lynx-community-skills-lynx-devtool

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-lynx-community-skills-lynx-devtool)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
1mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Lynx Devtool? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

DevTool Skill

This skill allows you to interact with Lynx applications running on connected devices (Android, iOS, Desktop) using the Lynx DevTool CLI.

Usage

The CLI is located at /scripts/index.mjs relative to this skill's directory. You can run it using node.

The programmatic API is located at /scripts/connector.mjs. This entry re-exports everything from @lynx-js/devtool-connector, @lynx-js/devtool-connector/transport, and @lynx-js/devtool-connector/streams, and also provides createDefaultTransports() and createDefaultConnector() helpers that match the CLI defaults.

In the skill directory, use:

node /scripts/index.mjs 

Note: All command outputs are multi-line JSON. You can use jq or Node.js to process the data.

Use as a Library

If you want to drive Lynx DevTool directly from JavaScript instead of shelling out to the CLI, import from scripts/connector.mjs.

import {
  Connector,
  createDefaultConnector,
} from "/scripts/connector.mjs";

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 need custom transports:

import {
  AndroidTransport,
  Connector,
  DesktopTransport,
  iOSTransport,
} from "/scripts/connector.mjs";

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.

Note: Each subcommand supports the --help flag (e.g. node /scripts/index.mjs cdp --help). Use this to view the full list of available arguments and their descriptions.

Client Targeting

Commands that accept -c, --client also accept --client-name . Use --client-name to resolve a client from list-clients by package/app identifier (AppProcessName, bundleId, bundleName, or App), for example:

node /scripts/index.mjs cdp --client-name com.example.app -m DOM.getDocument
node /scripts/index.mjs list-sessions --client-name com.lynx.uiapp

If multiple clients match the name, use list-clients and pass the exact client ID with --client.

Commands

1. List Clients

List all available Lynx clients (apps with DevTool enabled).

node /scripts/index.mjs list-clients
2. List Sessions

List all active debugging sessions. A session corresponds to a specific Lynx view or context.

node /scripts/index.mjs list-sessions
# Optional: Filter by client ID
node /scripts/index.mjs list-sessions --client 
3. 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.

node /scripts/index.mjs cdp -m  [options] [params]
  • -m, --method : The CDP method name (e.g., DOM.getDocument, Runtime.evaluate).
  • -c, --client : (Optional) The Client ID. If omitted, uses the first available client.
  • --client-name : (Optional) Package/app name resolved from list-clients.
  • -s, --session : (Optional) The Session ID. If omitted, uses the latest session (with the largest session ID).
  • --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:

# Get the document root
node /scripts/index.mjs cdp -m DOM.getDocument

# Evaluate JavaScript
node /scripts/index.mjs cdp -m Runtime.evaluate '{"expression": "2 + 2"}'

# Evaluate JavaScript on the main-thread VM
node /scripts/index.mjs cdp --thread main -m Runtime.evaluate '{"expression": "2 + 2"}'
4. Send App Command

Send an App-level command.

node /scripts/index.mjs app -m  [options] [params]
  • -m, --method : The App method name (e.g., App.openPage).
  • -c, --client : (Optional) Client ID.
  • --client-name : (Optional) Package/app name resolved from list-clients.
  • [params]: (Optional) JSON string of parameters.

> You MUST read [Supported App Methods](references/app/index.md) before sending an App command.

5. Open URL

Open a specific URL in the Lynx app.

node /scripts/index.mjs open  [options]
  • ``: The URL to open.
  • -c, --client : (Optional) Client ID.

Example:

node /scripts/index.mjs open "lynx://example/page"
6. Inspect

Output the inspector URL for a client/session.

node /scripts/index.mjs inspect [options]
  • -c, --client : (Optional) Client ID.
  • -s, --session : (Optional) Session ID.
  • --port : (Optional) Daemon port. Defaults to 21783.
7. Get Console

Capture console logs from the device.

node /scripts/index.mjs get-console [options]
  • -c, --client : (Optional) Client ID.
  • -s, --session : (Optional) Session ID.
  • --offset : Skip N messages.
  • --limit : Limit number of messages.
  • --include-stack-traces: Include stack traces for non-error messages.
  • --level : Filter log levels (e.g., error,warning).
  • --thread : Target VM thread(s): background or main. If omitted, both threads are collected by default.
8. 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.

node /scripts/index.mjs get-sources [options]
  • -c, --client : (Optional) Client ID.
  • -s, --session : (Optional) Session ID.
9. Take Screenshot

Take a screenshot of the current page.

node /scripts/index.mjs take-screenshot [options]
  • -c, --client : (Optional) Client ID.
  • -s, --session : (Optional) Session ID.
  • --fullscreen: (Optional) Capture the screenshot in fullscreen mode. Defaults to lynxview mode if not provided.
  • -o, --output : (Optional) Output file path.
10. Take Heap Snapshot

Capture a QuickJS heap snapshot from the current Lynx session and save it as a .heapsnapshot file.

node /scripts/index.mjs take-heap-snapshot [options]
  • -c, --client : (Optional) Client ID.
  • -s, --session : (Optional) Session ID.
  • --thread : (Optional) Target VM thread, background or main. Defaults to background.
  • -o, --output : (Optional) Output file path. Defaults to the OS temp directory.
11. Global Switch

Manage DevTool global switches.

# List all supported keys and their current values
node /scripts/index.mjs global-switch list [options]

# Get one key
node /scripts/index.mjs global-switch get --key  [options]

# Set one key
node /scripts/index.mjs global-switch set --key  --status  [options]
  • -c, --client : (Optional) Client ID.

global-switch list options:

  • --fail-fast: Abort on first key-read failure.

global-switch get options:

  • --key : Global switch key. (Required)

global-switch set options:

  • --key : Global switch key. (Required)
  • --status : Target switch status. (Required)

For the full key list and examples, see [Global Switch Reference](references/global-switch.md).

12. Query Global Memory Usage

Query Lynx global memory usage through the global Memory.* CDP domain. Use the generic cdp command and send the request to the global DevTool handler with session ID -1.

# Get global Lynx memory usage across live instances
node /scripts/index.mjs cdp -s -1 -m Memory.getAllMemoryUsage
node /scripts/index.mjs cdp -s -1 -m Memory.getAllMemoryUsage '{"timeoutMs":50000}'
  • -c, --client : (Optional) Client ID.
  • -s, --session : CDP session ID. Use -1 for the global DevTool handler unless you have a platform-specific reason to override it.
  • params.timeoutMs (Optional): Non-negative timeout in milliseconds. Maximum value is 300000.

When the DevTool MCP server is available, prefer the Memory_getAllMemoryUsage MCP tool for the same raw payload instead of shelling out to the CLI.

13. Recording

Record Lynx page interactions via TestBench (CDP-based). Captures all actions (template loads, touch events, JS module calls, data updates) and produces a JSON replay file.

# Start recording (BEFORE opening the target page)
node /scripts/index.mjs recorder start [options]

# Stop recording and save the replay file
node /scripts/index.mjs recorder end [options]
  • -c, --client : (Optional) Client ID for start and end.
  • -o, --output : (Optional) Output file or directory path for end. Defaults to ~/.lynx-devtool/files/lynxrecorder/recording--.json.

Workflow:

  1. Run recorder start. If it enables enable_debug_mode, restart the app and run recorder start again.
  2. User opens and interacts with the Lynx page.
  3. Run recorder end --output to stop and save.
  4. Report the absolute file path to the user.

Important: For a replayable file, open or reload the target page after recorder start so the recording includes loadTemplate.

See [Recording Reference](references/recorder.md) for more details.

14. ReactLynx Component Tree

Print the component tree of a running ReactLynx page, decoded from @lynx-js/preact-devtools. The CLI opens a Lynx.onVMEvent stream, sends a Preact DevTools init+refresh handshake, and renders the resulting operation_v2 payloads as an ASCII tree.

node /scripts/index.mjs reactlynx tree [options]
  • -c, --client : (Optional) Client ID.
  • -s, --session : (Optional) Session ID.
  • --depth : (Optional) Maximum tree depth to print. Default: unbounded.
  • --show-shells: Include the synthetic Fragment / Root / Anonymous wrappers ReactLynx inserts. They are hidden by default.
  • --json: Emit { labels, roots, nodes } instead of ASCII; use this when a script will consume the tree.

Output uses @cN [type] Name references (the convention from agent-react-devtools). Labels are pre-order DFS over visible roots and reset on every invocation, so they are stable within a single command but not across runs:

@c1 [fn] App
├─ @c2 [fn] Header
│  └─ @c3 [fn] Logo
└─ @c4 [fn] Body

Requirements:

  • The page must be a dev build running @lynx-js/preact-devtools (production bundles strip setupReactLynx()). Successful initialization logs [PREACT DEVTOOLS] Devtools initialized successfully to the device console.
  • @lynx-js/preact-devtools must include the document.body and preactDevtoolsCtx.Node fixes (PR #2 + PR #5 against lynx-family/preact-devtools). Without them, the refresh channel will return zero operation_v2 frames and the CLI will print the "stale preact-devtools" diagnostic.

When the tree comes back empty, the CLI exits with code 1 and writes one of three targeted diagnostics on stderr:

  • saw 0 frames: nothing replied on the PreactDevtools channel. The App is most likely missing @lynx-js/preact-devtools, is a production build, has not finished setupReactLynx(), or you picked the wrong --session.
  • saw N frames but no operation_v2: the hook is loaded but its refresh handler is buggy. Upgrade @lynx-js/preact-devtools to a build that contains PRs #2 and #5.
  • tree is empty: every node was unmounted between commits -- rare, rerun with DEBUG (below) to see the raw envelopes.

For deep debugging, set DEBUG=devtool-mcp-server:reactlynx to log every PreactDevtools frame (type + payload size) on stderr while leaving stdout (the tree / JSON) clean:

DEBUG='devtool-mcp-server:reactlynx' node /scripts/index.mjs reactlynx tree
15. ReactLynx Component Inspect

Inspect a single ReactLynx component (props / state / hooks / context / signals) by sending the Preact DevTools inspect envelope and reading back inspect-result.

node /scripts/index.mjs reactlynx component  [options]
  • `: either a label @cN produced by reactlynx tree / reactlynx find`, or a numeric vnode id.
  • With @cN, the CLI does an extra init+refresh+tree round-trip first to resolve the label. Pass --show-shells if (and only if) the label was generated with shells visible.
  • With a numeric id (e.g. 3856353762), the snapshot is skipped -- one round-trip total.
  • -c, --client , -s, --session : (Optional) standard targeting flags.
  • --show-shells: When resolving @cN, count synthetic Fragment / Root / Anonymous wrappers the same way reactlynx tree --show-shells does.
  • --json: Print the raw InspectData payload as JSON. Default output is a compact ASCII summary.

Example output:

@c5 (id=3856353783) [fn] TUXIntroViewListCell key=1. HMR
  source: src/TUXIntroViewListCell.tsx:42:3
  props:
    {
      "title": "1. HMR",
      "icon": { "type": "vnode", "name": "TUXIcon" }
    }
16. ReactLynx Component Find

Find every component whose name matches a substring or regex. Output is ordered identically to reactlynx tree (pre-order DFS) so the @cN labels round-trip with the other subcommands.

node /scripts/index.mjs reactlynx find  [options]
  • `: substring (default, case-insensitive) or JavaScript regex with --regex`.
  • -c, --client , -s, --session : (Optional) standard targeting flags.
  • --regex: Treat ` as a JavaScript regular expression (e.g. --regex '^Toast(List)?$'`).
  • --show-shells: Include synthetic Fragment / Root / Anonymous wrappers.
  • --limit : Maximum number of matches to print. Default 50.
  • --json: Emit [{ label, id, name, type, key, ancestors: [{label, name}] }, ...] for scripted post-processing.

Example output:

@c8 [fn] TUXCenterToastActivator
  in @c1 TUXApp > @c2 Provider > @c3 App
@c10 [fn] TUXTopToastActivator
  in @c1 TUXApp > @c2 Provider > @c3 App

reactlynx find is the recommended way to discover labels for follow-up reactlynx component @cN calls when the tree is too large to scan visually.

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.