mcpField
L
lynx-devtool

lynx-devtool

github.com/lynx-community开发286.3k 次安装1 天前更新
代码仓库

关于 lynx-devtool

lynx-devtool 是用于检查和操控已连接 Android、iOS 和 Desktop 设备上 Lynx 应用的技能与命令行工具,提供快照交互、DevTools 调试命令和 JavaScript 连接器 API。

主要功能

  1. 01通过界面快照检查和操控界面
  2. 02截取带元素标注的屏幕图像
  3. 03发送 CDP 和应用级命令
  4. 04执行 JavaScript 并读取控制台日志
  5. 05连接 Lynx 客户端和会话
  6. 06使用 JavaScript 连接器 API

适用场景

  1. 01点击、填写、滚动并读取应用界面元素
  2. 02使用 CDP 和 JavaScript 调试 Lynx 视图
  3. 03截取带标注的界面图像以检查 UI

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/lynx-community/skills --skill lynx-devtool

安装后在 Claude Code 中输入/lynx-devtool确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

bin.mjs
package.json
examples/
app.md
cdp.md
evaluating-javascript.md
get-sources.md
getting-console-logs.md
inspecting-the-dom.md
main-thread-logs-and-properties.md
open.md
programmatic-debugging.md
programmatic-touch-click-and-double-click.md
redirect-with-development-url.md
take-screenshot.md
touch-using-dom-coordinates.md
touch-using-lynx-geometry.md
touch-using-screenshot-coordinates.md
references/app/
App.CallStaticVoidMethod.md
App.closePage.md
App.openPage.md
index.md
references/cdp/css/
CSS.getBackgroundColors.md
CSS.getComputedStyleForNode.md
CSS.getInlineStylesForNode.md
CSS.getMatchedStylesForNode.md
CSS.getMediaQueries.md
CSS.getStyleSheetText.md
index.md
references/cdp/debugger/
Debugger.getPossibleBreakpoints.md
Debugger.getScriptSource.md

详细介绍

Agent Lynx DevTool Skill

此 Skill 可让你通过 agent-lynx CLI,与连接设备(Android、iOS、Desktop)上运行的 Lynx 应用交互。

用法

使用 agent-lynx CLI。发布的软件包名为 agent-lynx。 软件包 @lynx-js/skill-lynx-devtool 是此 Skill 的说明和资源的权威来源。agent-lynx 依赖该软件包,并直接读取其中的内容以执行 skills list/get。兼容性启动器也保留了历史上的单次调用方式 npx -y @lynx-js/skill-lynx-devtool。

程序化 API 从 agent-lynx/connector 导出。此入口会重新导出 @lynx-js/devtool-connector、@lynx-js/devtool-connector/transport 和 @lynx-js/devtool-connector/streams 中的所有内容,并提供仅供守护进程使用的 createDefaultTransports() 和 createDefaultConnector() 辅助函数。这些辅助函数使用一个 DaemonTransport,使彼此独立的脚本共享由守护进程管理的设备连接。只有在有意测试非守护进程路径时,才使用显式传入的传输构造 Connector。

在线 CLI 命令默认也仅使用守护进程。--no-daemon 是一个显式的退出选项,会在本次调用中以直接的 Android、iOS 和 Desktop 传输取代守护进程。ADB_SERVER_HOST 和 ADB_SERVER_PORT 仅用于配置此直接模式。守护进程模式会忽略它们,并在 stderr 中发出警告。

agent-lynx CLI 通常已在 PATH 中。如果 command -v agent-lynx 执行失败,请改用 npx:

npx --yes agent-lynx <command>

此发布的 Skill 不包含本地 CLI 入口脚本。请使用:

agent-lynx <command>

注意: 大多数命令的输出为 JSON。你可以使用 jq 或 Node.js 处理数据。

发现内置 Skills

已安装的 @lynx-js/skill-lynx-devtool 依赖项提供了 lynx-devtool Skill。使用以下命令发现它或加载其完整说明:

agent-lynx skills list
agent-lynx skills get lynx-devtool

skills list 会直接从该软件包的 SKILL.md YAML frontmatter 中读取每个 Skill 的名称和描述。skills get 会返回所选 Markdown 正文,并在 references/、assets/ 和 examples/ 目录存在时递归列出其中的常规文件。不包含符号链接和构建输出。稳定名称为 lynx-devtool。

快照工作流
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

快照引用会在 CLI 调用之间保存在守护进程内存中。请勿对 snapshot、tap、long-press、fill、clear、scroll、get text、get style、wait 或 screenshot 传入 --no-daemon。wait 使用守护进程的 SSE 命令路由;其他快照命令使用 POST /command/<action>。

screenshot --annotate 会刷新并缓存快照引用,然后在一张 JPEG 中直接绘制编号标签。标签 [N] 对应引用 @eN,因此 Agent 可以查看图像并立即使用匹配的引用。图像只标注可见引用中精简的一部分可操作元素:直接操作目标、可编辑字段、显式测试目标和滚动容器。通用布局和文本引用仍会保留在缓存快照中,不会让图像显得杂乱。与视口大小相同的滚动容器会使用角标,而不是边框。使用 --json 时,结果还会附带本次 ActionCore 调用所用的完整最新快照,因此使用者可以对照图像和引用,无需再次刷新。像素映射会使用屏幕串流帧的逻辑尺寸元数据,与可能带有内边距的快照视口分别处理;如果缺少该元数据,命令会失败,而不会猜测。请勿将 --annotate 与 --fullscreen 组合使用;请改用未标注的 screenshot --fullscreen 或旧版 take-screenshot --fullscreen 命令。请参阅标注截图参考。

程序化导入 connector 需要项目依赖项:

npm install agent-lynx

此项目本地安装仅适用于 connector 工作流;通过 PATH 中的 agent-lynx CLI 或 npx 仅使用 CLI 时无需安装。

作为库使用

如果你想直接通过 JavaScript 驱动 Lynx DevTool,而不是通过 CLI 执行命令,请从 agent-lynx/connector 导入。

import { Connector, createDefaultConnector } from "agent-lynx/connector";

const connector = createDefaultConnector();
const clients = await connector.listClients();

console.log(clients);

如需了解更完整的编程工作流,请参阅库使用参考和编程调试示例。

如果你有意使用自定义的非守护进程传输方式,也可以手动构造连接器:

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(),
]);
全局选项
  • -h, --help:显示命令帮助。
  • --no-daemon:绕过共享守护进程,在此次调用中使用直接设备传输。如果守护进程可能持有与同一 DebugRouter 目标的连接,请先停止守护进程。

**注意:**每个子命令都支持 --help 标志(例如 agent-lynx cdp --help)。使用此标志可查看可用参数的完整列表及其说明。

命令
1. 列出客户端

列出所有可用的 Lynx 客户端(已启用 DevTool 的应用)。

agent-lynx list-clients
2. 等待客户端

等待客户端可用。

agent-lynx wait-for-client --client-name com.lynx.uiapp
  • --client-name <name>:等待指定的包或应用名称(可选)。匹配 AppProcessName、bundleId、bundleName 或 App。如果匹配到多个客户端,则返回所有匹配的客户端。如果省略,则返回第一个可用的客户端。输出始终为 JSON 数组。
  • --timeout <seconds>:等待的最长秒数。默认为 30。
  • --interval <seconds>:两次发现尝试之间的间隔秒数。默认为 1。
3. 列出会话

列出所有活动调试会话。会话对应一个特定的 Lynx 视图或上下文。

agent-lynx list-sessions
# Optional: Filter by client ID
agent-lynx list-sessions --client <clientId>
4. 发送 CDP 命令

向特定会话发送 Chrome DevTools Protocol(CDP)命令。

请注意,Lynx 仅支持部分标准 CDP 命令。 LynxView 注意:如果目标会话是 LynxView,则在发送 CDP 命令前必须阅读支持的 CDP 方法。 WebView 注意:如果目标会话是 WebView(例如 type: "web" 或 HTTP/HTTPS URL),请参阅标准 Chrome DevTools Protocol 文档,了解 CDP 方法名称、参数和启用前提。本地 references/cdp 页面侧重于 LynxView 支持和 Lynx 专属扩展,在 WebView 目标上可能返回 method not found。

agent-lynx cdp -m <method> [options] [params]
  • -m, --method <method>:CDP 方法名称(例如 DOM.getDocument、Page.reload)。
  • -c, --client <clientId>:(可选)客户端 ID。若省略,则使用第一个可用的客户端。
  • -s, --session <sessionId>:(可选)会话 ID。若省略,则使用最新的会话(即会话 ID 最大的会话)。
  • --thread <thread>:(可选)目标 VM 线程,可以是 background 或 main。默认为 background。
  • [params]:(可选)命令参数的 JSON 字符串。

使用 --thread main 时,仅支持 Debugger.*、Runtime.*、HeapProfiler.* 和 Profiler.* 方法。

示例:

# Get the document root
agent-lynx cdp -m DOM.getDocument
5. 评估 JavaScript

评估 JavaScript 表达式。在后台 VM 上,当前应用的 lynx 和 nativeLynx 对象可用作局部变量。针对主 VM 的表达式将原样发送。

agent-lynx evaluate 'JSON.stringify(lynx.__globalProps)'
agent-lynx evaluate '2 + 2' --thread main
agent-lynx evaluate 'lynx' --no-return-by-value
  • <expression>:要评估的 JavaScript 表达式。
  • -c, --client <clientId>:(可选)客户端 ID。
  • -s, --session <sessionId>:(可选)会话 ID。
  • --thread <thread>:(可选)目标 VM 线程,可选值为 background 或 main。默认为 background。只有后台表达式会经过包装,以便使用 lynx 和 nativeLynx;主线程表达式将原样发送。
  • 默认情况下,该命令按值请求结果。支持 returnByValue 的引擎会将普通类 JSON 对象序列化到 result.value 中;当前 Android Lynx 运行时可能会忽略对象值的该选项,仍返回 objectId。如果需要 JSON 输出,请使用 JSON.stringify(lynx.__globalProps)。使用 --no-return-by-value 可主动接收 objectId,以便后续发送 Runtime.getProperties 或 Runtime.callFunctionOn 请求。--return-by-value 仍可作为默认行为的显式形式使用。
  • --silent、--context-id、--throw-on-side-effect、--generate-preview、--object-group、--await-promise、--include-command-line-api:可选的评估参数。引擎支持情况各不相同。
6. 发送 App 命令

发送 App 级命令。

agent-lynx app -m <method> [options] [params]
  • -m, --method <method>:App 方法名(例如,App.openPage)。
  • -c, --client <clientId>:(可选)客户端 ID。
  • [params]:(可选)参数的 JSON 字符串。

发送 App 命令前,必须阅读支持的 App 方法。

7. 打开 URL

在 Lynx 应用中打开指定 URL。

agent-lynx open <url> [options]
  • <url>:要打开的 URL。
  • -c, --client <clientId>:(可选)客户端 ID。

示例:

agent-lynx open "lynx://example/page"
8. 获取控制台日志

捕获设备上的控制台日志。

agent-lynx get-console [options]
  • -c, --client <clientId>:(可选)客户端 ID。
  • -s, --session <sessionId>:(可选)会话 ID。
  • --offset <number>:跳过 N 条消息。
  • --limit <number>:限制消息数量。
  • --include-stack-traces:为非错误消息包含堆栈跟踪。
  • --level <levels>:筛选日志级别(例如,error,warning)。
  • --thread <thread...>:目标 VM 线程,可指定 background 或 main。若省略,默认收集两个线程的日志。
9. 获取源代码

列出所有已解析的脚本。这有助于查找可用于其他命令(例如,Debugger.getScriptSource)的脚本 ID。该命令会自动获取所有当前已加载的脚本。

agent-lynx get-sources [options]
  • -c, --client <clientId>:(可选)客户端 ID。
  • -s, --session <sessionId>:(可选)会话 ID。
10. 检查器

打印连接器守护进程为客户端/会话对提供的 DevTool 检查器 URL。在浏览器中打开打印出的 URL,即可将图形检查器连接到 CLI 所针对的同一会话。

agent-lynx inspect [options]
  • -c, --client <clientId>:(可选)客户端 ID。
  • -s, --session <sessionId>:(可选)会话 ID。
  • --port <port>:(可选)守护进程端口。默认为 21783。
11. Agent 截图

通过 ActionCore 截图,并可选择直接在生成的 JPEG 中绘制新鲜的快照引用。

agent-lynx screenshot [options]
  • -c, --client <clientId>:(可选)客户端 ID。
  • -s, --session <sessionId>:(可选)会话 ID。
  • --annotate:(可选)刷新引用并绘制 [N] 标签,其中 [N] 对应 @eN。
  • --fullscreen:(可选)截取全屏,而非 LynxView。不能与 --annotate 同时使用。
  • -o, --output <path>:(可选)JPEG 输出路径。
  • --json:(可选)返回路径、图像尺寸、完整的新鲜快照以及标注元数据。

此命令需要持久守护进程。有关单图输出约定和目标限制,请参阅标注截图参考。

12. 旧版截图

使用 Agent-Lynx 之前的命令直接截取当前页面。

agent-lynx take-screenshot [options]
  • -c, --client <clientId>: (可选)客户端 ID。
  • -s, --session <sessionId>: (可选)会话 ID。
  • --fullscreen: (可选)以 fullscreen 模式截取屏幕截图。如果未提供,则默认为 lynxview 模式。
  • -o, --output <path>: (可选)输出文件路径。
13. 截取内容截图

截取第一个匹配 CSS 选择器的节点的全部可滚动内容。

agent-lynx take-content-screenshot --selector <selector> [options]
  • --selector <selector>:scroll-view 或兼容 list 的 CSS 选择器。必填。
  • --format <jpeg|png>: (可选)图像格式。默认为 jpeg。
  • --scale <number>: (可选)大于 0 的输出缩放比例。默认为 1。
  • -c, --client <clientId>: (可选)客户端 ID。
  • -s, --session <sessionId>: (可选)会话 ID。
  • -o, --output <path>: (可选)输出文件路径。

takeContentScreenshot 的官方定义适用于 scroll-view。此命令接受任何 CSS 选择器,因此也可用于在 list 上提供相同方法的运行时;不支持的节点会返回 UI 方法失败。

有关行为和示例,请参阅内容截图参考。

14. 全局开关

管理 DevTool 全局开关。

# List all supported keys and their current values
agent-lynx global-switch list [options]

# Get one key
agent-lynx global-switch get --key <globalKey> [options]

# Set one key
agent-lynx global-switch set --key <globalKey> --status <on|off> [options]
  • -c, --client <clientId>: (可选)客户端 ID。

global-switch list 选项:

  • --fail-fast:读取键失败时立即中止。

global-switch get 选项:

  • --key <globalKey>:全局开关键。(必填)

global-switch set 选项:

  • --key <globalKey>:全局开关键。(必填)
  • --status <on|off>:目标开关状态。(必填)

完整键列表和示例请参阅全局开关参考。

15. 获取堆快照

从当前 Lynx 会话中获取 QuickJS 堆快照,并将其保存为 .heapsnapshot 文件。

agent-lynx take-heap-snapshot [options]
  • -c, --client <clientId>: (可选)客户端 ID。
  • -s, --session <sessionId>: (可选)会话 ID。
  • --thread <thread>: (可选)目标 VM 线程,可选值为 background 或 main。默认为 background。
  • -o, --output <path>: (可选)输出文件路径。默认为操作系统临时目录。
16. 查询全局内存使用情况

通过全局 Memory.* CDP 域查询 Lynx 全局内存使用情况。使用通用的 cdp 命令,并将请求发送到会话 ID 为 -1 的全局 DevTool 处理程序。

# Get global Lynx memory usage across live instances
agent-lynx cdp -s -1 -m Memory.getAllMemoryUsage
agent-lynx cdp -s -1 -m Memory.getAllMemoryUsage '{"timeoutMs":50000}'
  • -c, --client <clientId>:客户端 ID(可选)。
  • -s, --session <sessionId>:CDP 会话 ID。除非有特定于平台的原因需要覆盖,否则请使用 -1 指定全局 DevTool 处理程序。
  • params.timeoutMs(可选):以毫秒为单位的非负超时时间。最大值为 300000。

该命令会打印原始的 Memory.getAllMemoryUsage JSON。不要期望 CLI 输出中包含衍生的 summary、topMemoryItems 或 topInstances 包装字段。

当 DevTool MCP 服务可用时,对于相同的原始负载,优先使用 Memory_getAllMemoryUsage MCP 工具,而不是通过 shell 调用 CLI。

Agent 端报告规范:

  1. 用户要求保存快照,或结果太大而不适合直接显示时,将完整原始 JSON 保存到文件。
  2. 使用二进制单位(KiB、MiB、GiB),保留两位小数。将 ratioToApp 和贡献率显示为百分比,保留两位小数。
  3. 首先报告以下固定摘要:
    • collectionStatus
    • Lynx 实例数:${completedInstanceCount}/${expectedInstanceCount}
    • totalBytes
    • appBytes
    • ratioToApp
    • elementNodeCount
    • viewBytes
    • mainThreadRuntimeBytes
    • backgroundThreadRuntimeBytes
  4. 然后报告“内存贡献排名前 5”,使用各 instances[] 条目中的细粒度候选项:
    • instances[i].backgroundThreadRuntimeBytes
    • instances[i].mainThreadRuntimeBytes
    • instances[i].elementBytes
    • 各 instances[i].viewDetail[category].sizeBytes
    • 如果 instances[i].viewBytes 大于 viewDetail[*].sizeBytes 之和,则将差值列为 other view memory。
  5. 按字节数降序排列排名前 5 的贡献项。每行包含排名、项目类型/类别、大小、占 totalBytes 的百分比、占 instance.totalBytes 的百分比、instanceId 和 URL。
  6. 然后报告“实例”,按 instance.totalBytes 降序排列。每个实例包含 instanceId、URL、totalBytes、mainThreadRuntimeBytes、backgroundThreadRuntimeBytes、viewBytes、elementBytes,以及简洁的 viewDetail 摘要,例如 image=12 / 4.15 MiB。
  7. 不要编造缺失的字段。如果 viewDetail 为空或某个类别的字节数为 0,请如实说明。当前 CDP 负载不会公开嵌套的子 LynxView 对象树。

Memory.getAllMemoryUsage 与 Runtime.getHeapUsage 不同:它会返回所有仍在运行且已注册的 Lynx 实例的全局 Lynx 归属内存快照,其中包括元素、视图、主线程运行时、后台运行时、应用占用量和各实例明细。当前 CDP 负载不会公开单独的嵌套子 LynxView 内存树;viewDetail 按 UI 视图类别或标签聚合。完整的响应结构请参阅 Memory CDP Methods。

17. 录制

通过 TestBench(基于 CDP)录制 Lynx 页面交互。录制所有操作(模板加载、触摸事件、JS 模块调用、数据更新),并生成 JSON 回放文件。

# Start recording (BEFORE opening the target page)
agent-lynx recorder start [options]

# Stop recording and save the replay file
agent-lynx recorder end [options]
  • -c, --client <clientId>:start 和 end 的客户端 ID(可选)。
  • -o, --output <path>:end 的输出文件或目录路径(可选)。默认为 ~/.lynx-devtool/files/lynxrecorder/recording-<clientId>-<timestamp>.json。

工作流:

  1. 运行 recorder start。如果该命令启用了 enable_debug_mode,请重启应用,然后再次运行 recorder start。
  2. 用户打开 Lynx 页面并进行交互。
  3. 运行 recorder end --output <file.json> 停止录制并保存。
  4. 向用户报告绝对文件路径。

**重要:**要生成可回放文件,请在运行 recorder start 后打开或重新加载目标页面,以便录制内容包含 loadTemplate。

更多详情请参阅 Recording Reference。

18. 性能跟踪录制

录制压缩后的 Lynx 性能跟踪,并将其保存为 .pftrace 文件。 请在构建或打开目标页面之前开始跟踪,以便捕获该页面的首帧。

# Discover the client first; keep the same ID throughout the workflow.
agent-lynx list-clients

# Start before opening the target page.
agent-lynx trace start --client <clientId>

# Open and interact with the page, then stop and capture the stream handle.
agent-lynx trace end --client <clientId>

# Download the handle returned by trace end.
agent-lynx trace read-data --client <clientId> --stream <handle> -o ./my-trace.pftrace

# Inspect the downloaded file locally without a device or daemon.
agent-lynx trace event-summary ./my-trace.pftrace
agent-lynx trace query ./my-trace.pftrace \
  --sql "SELECT name, COUNT(*) AS count FROM slice GROUP BY name"
  • -c, --client <clientId>:(可选)客户端 ID。如果连接了多个客户端,请列出它们并明确选择一个。
  • trace start --no-systrace:禁用 systrace;默认启用。
  • trace start --include-categories <categories> / --exclude-categories <categories>:包含或排除以逗号分隔的跟踪类别。
  • trace start --enable-memory-trace:启用内存数据采集。
  • trace start --no-force-gc:禁用自动垃圾回收;默认启用。
  • trace start --enable-auto-heap-snapshot:为 shared-group VM 自动捕获堆快照。添加 --shared-group-id <id> 可选择一个 VM。
  • trace start --js-profile-interval <interval>:JS 采样间隔。启用性能分析且提供的间隔为 0 或 -1 时,默认为 100;否则默认为 -1。
  • trace start --js-profile-type <quickjs|v8>:为所选 JS 运行时启用性能分析。省略此选项时,性能分析处于禁用状态。
  • trace end --timeout <seconds>:等待 Tracing.tracingComplete 的时长。默认为 30。
  • trace read-data --stream <handle>:由 trace end 返回的数字流句柄。
  • trace read-data -o, --output <path>:输出路径。默认保存到操作系统临时目录下带时间戳的 .pftrace 文件。
  • trace read-data --timeout <seconds>:下载总超时时长。默认为 30。
  • trace event-summary <trace>:打印每个 Perfetto slice.name 及其出现次数,并按次数降序排列。添加 --json 可输出结构化数据,添加 -o, --output <path> 可将其写入文件。
  • trace query <trace> --sql <query>:运行内联 Perfetto SQL 并输出 JSON。
  • trace query <trace> --sql-file <path>:运行文件中的 SQL。--sql 和 --sql-file 必须且只能使用其中一个;--max-rows 默认为 1000。

trace query 和 trace event-summary 是本地离线命令。它们不会连接设备、启动守护进程或创建连接器传输。其 JSON 包含跟踪文件的绝对路径、字节长度和 SHA-256,以便 Agent 证明其检查的是哪个文件。SQL bigint 值会以十进制字符串表示,blob 则表示为 { "base64": "..." } 对象。

在 Android 上,首次运行 trace start 可能会启用 enable_debug_mode 并提示重启应用。请重启应用,然后在打开页面之前再次运行 trace start。不支持跟踪的运行时需要 Android local_test 构建版本或 iOS Lynx Profile 构建版本。完整工作流和故障排除请参阅性能跟踪参考。

19. ReactLynx 组件树

打印运行中 ReactLynx 页面的组件树,解码数据来自 @lynx-js/preact-devtools。CLI 调用连接器守护进程的 ReactLynx ActionCore;守护进程负责管理 Lynx.onVMEvent 流、init+refresh 握手、operation_v2 解码和各会话的组件缓存。CLI 只负责渲染返回的树。

agent-lynx reactlynx tree [options]
  • -c, --client <clientId>: (可选)客户端 ID。
  • -s, --session <sessionId>: (可选)会话 ID。
  • --depth <n>: (可选)要打印的最大树深度。默认:不设上限。
  • --show-shells:包括 ReactLynx 插入的合成 Fragment / Root / Anonymous 包装节点。默认隐藏。
  • --json:输出 { labels, roots, nodes },而不是 ASCII;当脚本需要读取树时使用此选项。

输出使用 @cN [type] Name 引用(遵循 agent-react-devtools 的惯例)。标签按可见根节点的先序 DFS 顺序分配。reactlynx tree 始终会捕获新一代树,并缓存其输出的确切标签视图,包括 --depth;后续的 component @cN 和 update-* @cN 调用会在独立的 CLI 调用之间复用该视图。紧凑视图和 --show-shells 标签视图会分别缓存。

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

要求:

  • ReactLynx 命令需要连接器守护进程;不要与 --no-daemon 一起使用。
  • 页面必须是运行 @lynx-js/preact-devtools 的开发构建(生产包会移除 setupReactLynx())。初始化成功后,设备控制台会记录 [PREACT DEVTOOLS] Devtools initialized successfully。
  • @lynx-js/preact-devtools 必须包含 document.body 和 preactDevtoolsCtx.Node 修复(针对 lynx-family/preact-devtools 的 PR #2 + PR #5)。缺少这些修复时,refresh 通道会返回 0 个 operation_v2 帧,CLI 会打印“过时的 preact-devtools”诊断信息。

如果返回的树为空,CLI 会以代码 1 退出,并在 stderr 上输出以下三种针对性诊断之一:

  • saw 0 frames:PreactDevtools 通道没有任何响应。App 很可能缺少 @lynx-js/preact-devtools、是生产构建、尚未完成 setupReactLynx(),或选择了错误的 --session。
  • saw N frames but no operation_v2:钩子已加载,但其 refresh 处理程序存在缺陷。请将 @lynx-js/preact-devtools 升级到包含 PR #2 和 PR #5 的构建。
  • tree is empty:所有节点都在提交之间卸载了——这种情况很少见;请使用 DEBUG(如下)重新运行,以查看原始信封。

如需深入调试,请设置 DEBUG=devtool-mcp-server:reactlynx,在 stderr 上记录每个 PreactDevtools 帧(类型 + 负载大小),同时保持 stdout(树 / JSON)干净:

DEBUG='devtool-mcp-server:reactlynx' agent-lynx reactlynx tree
# 2026-05-25T... devtool-mcp-server:reactlynx frame 1: type=operation_v2 dataSize=54
# 2026-05-25T... devtool-mcp-server:reactlynx frame 2: type=operation_v2 dataSize=756
# 2026-05-25T... devtool-mcp-server:reactlynx frame 3: type=root-order dataSize=1
# 2026-05-25T... devtool-mcp-server:reactlynx frame 4: type=root-order-page dataSize=object
20. ReactLynx 组件检查

通过发送 Preact DevTools inspect 信封并读取 inspect-result,检查单个 ReactLynx 组件(props / state / hooks / context / signals)。

agent-lynx reactlynx component <ref> [options]
  • <ref>:可以是由 reactlynx tree / reactlynx find 生成的标签 @cN,也可以是数字 vnode ID。
    • 使用 @cN 时,守护进程会根据最新的匹配标签视图解析该标签。如果缓存未命中,则会捕获一次树。仅当生成标签时显示了 shell,才传入 --show-shells。
    • 使用数字 ID(例如 3856353762)时,会绕过组件缓存。
  • -c, --client <clientId>、-s, --session <sessionId>:(可选)标准定位标志。
  • --show-shells:解析 @cN 时,以与 reactlynx tree --show-shells 相同的方式计入合成 Fragment / Root / Anonymous 包装器。
  • --refresh:在解析 @cN 前捕获一棵新的完整树。对数字 ID 无效。
  • --json:以 JSON 格式打印原始 InspectData 负载。默认输出为精简的 ASCII 摘要。

示例输出:

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

复杂值会通过上游的 serialize.ts 标记,例如 { "type": "function", "name": "..." }、{ "type": "vnode", "name": "..." }、{ "type": "signal", "value": ... }、{ "type": "map", "entries": [...] } 等。完整架构请参阅 serialize.ts。

如果 App 未能回复 inspect-result,守护进程会清除该会话的 ReactLynx 缓存,CLI 以代码 1 退出。重试前请运行 reactlynx tree。同一 DEBUG=devtool-mcp-server:reactlynx 命名空间会跟踪每一帧。

21. ReactLynx 组件查找

查找名称与子字符串或正则表达式匹配的所有组件。输出顺序与 reactlynx tree 完全相同(前序 DFS),因此 @cN 标签可与其他子命令配合使用。

agent-lynx reactlynx find <pattern> [options]
  • <pattern>:子字符串(默认,不区分大小写);使用 --regex 时则为 JavaScript 正则表达式。
  • -c, --client <clientId>、-s, --session <sessionId>:(可选)标准定位标志。
  • --regex:将 <pattern> 视为 JavaScript 正则表达式(例如 --regex '^Toast(List)?$')。
  • --show-shells:包含合成 Fragment / Root / Anonymous 包装器。
  • --refresh:搜索前捕获新一代组件。不使用此选项时,find 会复用守护进程缓存(缓存未命中时会捕获一次)。
  • --limit <n>:最多打印的匹配项数量。默认为 50。
  • --json:输出 [{ label, id, name, type, key, ancestors: [{label, name}] }, ...],用于脚本后处理。

示例输出:

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

当组件树过大、不便于目视扫描时,建议使用 reactlynx find 查找标签,以便后续调用 reactlynx component @cN。成功查找后,会将完整深度的标签视图发布为所选 shell 模式的最新视图。

22. ReactLynx 元素/组件关联

解析最新的守护进程缓存 DOM Snapshot 与守护进程缓存 ReactLynx 组件树之间的一项精确关联:

# Snapshot element -> nearest surfaced ReactLynx component
agent-lynx snapshot
agent-lynx reactlynx link @e7

# ReactLynx component -> first host element in the latest Snapshot
agent-lynx reactlynx tree
agent-lynx reactlynx link @c8

该命令也接受数字形式的 Preact VNode id,可替代 @cN,并支持 --json、--show-shells 和 --refresh。默认情况下,它会为所选 shell 模式复用最新的组件代次和精确标签视图;如果组件缓存未命中,则会捕获一个代次。--refresh 会先显式替换组件代次,再解析关联。

这是通过 Lynx nodeId / ReactLynx uniqueId 进行的精确身份查找;绝不会回退到按坐标、文本或树位置匹配。它使用现有的 App 端 element-picked 和 highlight 协议,因此 App 必须包含兼容的 @lynx-js/preact-devtools 开发构建。JSON 会返回完整的 Snapshot ref、组件标签/id/类型/名称/key,以及组件缓存代次。

该命令特意不会刷新 DOM Snapshot:刷新会悄然使用户尝试关联的 @eN refs 失效。先运行 agent-lynx snapshot,如果守护进程报告 ref 缺失或已过期,再显式重新运行该命令。组件到元素的查找会返回 Preact DevTools 暴露的第一个宿主元素;元素到组件的查找会返回最近的已展示组件。因此,对于渲染多个宿主元素的组件,这两个方向不保证构成双射。

23. ReactLynx 组件更新

修改一个字段,并等待应用端适配器在更新后确认 inspect-result:

agent-lynx reactlynx update-prop <ref> <path> <value> [options]
agent-lynx reactlynx update-state <ref> <path> <value> [options]
agent-lynx reactlynx update-context <ref> <path> <value> [options]
  • <ref> 遵循与 reactlynx component 相同的缓存 @cN 或数字 vnode-id 规则。
  • <path> 从所选的 props/state/context 对象开始,例如 count、user.name 或 items.0.title。不要在前面加上 root.、props.、state. 或 context.。
  • <value> 会解析为 JSON。对于字符串 JSON,请在 shell 中为其加引号;或者传入 --raw,将参数作为原始字符串发送。
  • --show-shells 会选择包含 shell 的标签视图;--refresh 会在解析 @cN 前捕获新树。
  • --json 会输出原始的更新后 InspectData 确认结果。

守护进程会串行执行同一客户端/会话的 ReactLynx 操作,因此广播的 Preact VM 事件不会在并发命令之间串扰。不同会话可以并行执行。缓存基于代次,而非实时订阅:tree 和显式的 --refresh 会替换缓存,find 默认会复用缓存,而缓存的 inspect/update 失败则会清除缓存。

评论

支持 Markdown