关于 lynx-devtool
lynx-devtool 是用于检查和操控已连接 Android、iOS 和 Desktop 设备上 Lynx 应用的技能与命令行工具,提供快照交互、DevTools 调试命令和 JavaScript 连接器 API。
主要功能
- 01通过界面快照检查和操控界面
- 02截取带元素标注的屏幕图像
- 03发送 CDP 和应用级命令
- 04执行 JavaScript 并读取控制台日志
- 05连接 Lynx 客户端和会话
- 06使用 JavaScript 连接器 API
适用场景
- 01点击、填写、滚动并读取应用界面元素
- 02使用 CDP 和 JavaScript 调试 Lynx 视图
- 03截取带标注的界面图像以检查 UI
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ lynx-community/ skills --skill lynx-devtool安装后在 Claude Code 中输入/lynx-devtool确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
bin.mjspackage.jsonexamples/app.mdcdp.mdevaluating-javascript.mdget-sources.mdgetting-console-logs.mdinspecting-the-dom.mdmain-thread-logs-and-properties.mdopen.mdprogrammatic-debugging.mdprogrammatic-touch-click-and-double-click.mdredirect-with-development-url.mdtake-screenshot.mdtouch-using-dom-coordinates.mdtouch-using-lynx-geometry.mdtouch-using-screenshot-coordinates.mdreferences/app/App.CallStaticVoidMethod.mdApp.closePage.mdApp.openPage.mdindex.mdreferences/cdp/css/CSS.getBackgroundColors.mdCSS.getComputedStyleForNode.mdCSS.getInlineStylesForNode.mdCSS.getMatchedStylesForNode.mdCSS.getMediaQueries.mdCSS.getStyleSheetText.mdindex.mdreferences/cdp/debugger/Debugger.getPossibleBreakpoints.mdDebugger.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 端报告规范:
- 用户要求保存快照,或结果太大而不适合直接显示时,将完整原始 JSON 保存到文件。
- 使用二进制单位(
KiB、MiB、GiB),保留两位小数。将ratioToApp和贡献率显示为百分比,保留两位小数。 - 首先报告以下固定摘要:
collectionStatus- Lynx 实例数:
${completedInstanceCount}/${expectedInstanceCount} totalBytesappBytesratioToAppelementNodeCountviewBytesmainThreadRuntimeBytesbackgroundThreadRuntimeBytes
- 然后报告“内存贡献排名前 5”,使用各
instances[]条目中的细粒度候选项:instances[i].backgroundThreadRuntimeBytesinstances[i].mainThreadRuntimeBytesinstances[i].elementBytes- 各
instances[i].viewDetail[category].sizeBytes - 如果
instances[i].viewBytes大于viewDetail[*].sizeBytes之和,则将差值列为other view memory。
- 按字节数降序排列排名前 5 的贡献项。每行包含排名、项目类型/类别、大小、占
totalBytes的百分比、占instance.totalBytes的百分比、instanceId和 URL。 - 然后报告“实例”,按
instance.totalBytes降序排列。每个实例包含instanceId、URL、totalBytes、mainThreadRuntimeBytes、backgroundThreadRuntimeBytes、viewBytes、elementBytes,以及简洁的viewDetail摘要,例如image=12 / 4.15 MiB。 - 不要编造缺失的字段。如果
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。
工作流:
- 运行
recorder start。如果该命令启用了enable_debug_mode,请重启应用,然后再次运行recorder start。 - 用户打开 Lynx 页面并进行交互。
- 运行
recorder end --output <file.json>停止录制并保存。 - 向用户报告绝对文件路径。
**重要:**要生成可回放文件,请在运行 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-groupVM 自动捕获堆快照。添加--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>:打印每个 Perfettoslice.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 失败则会清除缓存。