被动 Node 和 Electron 运行时观察¶
REA 可以附加到已在运行的 Node.js 或 Electron V8 Inspector 目标,并保留脚本加载和执行上下文元数据。list_javascript_runtime_targets 和 observe_javascript_runtime MCP 工具具有等价的 rea list-javascript-runtime-targets 和 rea observe-javascript-runtime 命令。成功调用返回确定性证据。
每次请求提供回环 Inspector 端点;对于观察,还提供目标 ID。此接口独立于浏览器 CDP、Electron 文件页面检查和 Process Capture:
rea list-javascript-runtime-targets http://127.0.0.1:9229 \
--json
rea observe-javascript-runtime http://127.0.0.1:9229 TARGET_ID \
--runtime-kind node --json
启动由调用方拥有的 Node 目标¶
使用绑定到回环的 Inspector 运行所选应用程序:
在列出目标和观察所选 ID 时保持其运行。使用空闲端口,并在两个 REA 调用中使用相同的字面端点。完成后通过其正常生命周期停止应用程序;REA 会断开连接,但不拥有或终止它。必须已安装 Node.js。
对于此被动工作流,请使用 --inspect。--inspect-brk 会在应用程序启动前暂停,REA 从不恢复它,也不发送 Runtime.runIfWaitingForDebugger。在请求应用程序运行时观察之前,请使用单独的调用方拥有的调试器恢复已暂停的目标。
对于打包的 Electron 应用,在启动 electron-main 目标之前,请阅读 inspect_electron_fuses。当 EnableNodeCliInspectArguments 被禁用或移除时,Electron 会忽略 --inspect 和 --inspect-brk。启动后缺少主进程目标本身并不能表明该 fuse 的状态。
调用方直接提供字面回环 HTTP 端点。选择端点会暴露它服务的所有目标及其本地脚本位置或渲染器来源。目标必须与请求的确切目标 ID 匹配,并暴露该端点报告的同端口 WebSocket。被明确标记为 attached 的目标会被拒绝,而不是替换另一个调试器。Node 的 /json/list 省略附加状态,因此 REA 将其保留为 null(未知),报告该限制,并允许观察,除非端点明确报告 attached: true。本地路径在符号链接解析后进行规范化。
JavaScript 运行时和浏览器目标结果中的 attached 字段可为空:仅当发现过程提供了布尔值时,才报告 true 和 false;null 表示端点省略或无法报告该状态。HTTP /json/list 发现过程独立解析目标行。格式错误的可选附加元数据会变为 null,并在 limitations 中附带行和字段诊断;可用的同级字段仍然可用。目标身份格式错误的行会被排除并附带诊断,但套接字 authority 仍会在连接前得到验证。CDP TargetInfo worker 记录需要 attached 布尔值;REA 会将缺少或格式错误该值的工作器记录作为无效协议值排除。
list_javascript_runtime_targets 在一个内联数组中返回所有可用目标。
附加拒绝会识别 attached: true,并要求调用方断开另一个调试器或选择另一个目标。声明的角色不匹配会指出 runtime_kind 和目标协议类型;请更正该角色,或省略它以保留未知角色。所提供的运行时证据中仅涉及角色的不一致,归因于 parameters.runtime_kind,与目标 ID 的不一致分开处理。部分捕获警告会统计保留的不同脚本记录;observed_total 保留去重之前的原始脚本事件计数。
对于 MCP 后续调用,将相同的字面回环端点和所选目标 ID 传递给 observe_javascript_runtime。REA 会重新发现目标,并在观察之前对照实时端点验证该 ID。
文件位置发现¶
Node 的 /json/list 会报告一个尽力而为的路径名,并以 file:// 为前缀,不进行 URI 编码。在 POSIX 上,REA 按字面意思解释无歧义的路径,包括文件名中的 # 和 %。Node 还会将反斜杠和双引号替换为下划线。这种转换无法可靠地逆转:下划线可能原本就是原始文件名的一部分。
Windows 路径、有歧义的下划线路径以及无法验证的本地发现路径,仍可通过其端点和确切目标 ID 成为合格目标。它们的目标位置保留报告的值:
{
"kind": "unresolved",
"reported_url": "file://C:_tools_entry.js",
"reason": "unverifiable-file-location"
}
该位置并不声称文件存在,也不授权读取其内容。列出的操作仍然仅限 HTTP。观察过程独立地从 Debugger.scriptParsed 文件 URL 解析已加载脚本的位置,保留对本地文件和编码分隔符的现有检查。不支持的协议方案、远程文件主机以及裸 file:// 仍被排除在外。这些 Node 发现规则不适用于页面目标或其他运行时产品。
对账过程会保留未解析的 target_location 对象,并为该目标报告 runtime-location-unresolved,置信度为未知。它不会从报告的路径名推导静态匹配;经过验证的已加载脚本位置仍可用于独立匹配。
被动协议边界¶
提供者恰好发送两条协议命令:
Runtime.enableDebugger.enable
它从不发送 Runtime.evaluate、读取脚本源代码、安装断点、发送暂停/恢复命令、调用 Runtime.runIfWaitingForDebugger、启动目标、对 JavaScript 进行插桩,或调用 Electron API。启用 Debugger 可能会使目标代码中的 debugger 语句暂停执行。REA 不发送 Debugger.setSkipAllPauses,也不恢复这些暂停;被动观察并不能保证目标执行不中断。关闭调用只会关闭 REA 的 WebSocket。
每次 WebSocket 握手和命令响应都有各自 20 秒的截止期限,且该期限独立于调用方选择的观察窗口。停滞的握手或命令会报告 provider_timeout,并保留已收到的观察结果;调用方取消仍会报告取消。
直接观察结果包括:
Debugger.scriptParsed,确认在观察到的执行上下文中解析了某个有界脚本位置;Debugger.scriptFailedToParse,仅作为有界无效脚本计数保留在scripts.parse_failed_total中。格式良好的解析失败事件不同于畸形协议数据,不会使已加载的脚本覆盖率不可用。较旧的 Evidence 可能省略此计数;Runtime.executionContextCreated、Runtime.executionContextDestroyed和Runtime.executionContextsCleared,在捕获窗口内建立上下文生命周期。如果创建或销毁事件的上下文 ID 缺失或不是安全整数,则不会添加上下文记录;仅作为unknowns中报告的计数保留。
Inspector 协议不直接暴露 require/import 调用方边、EventEmitter 发射或监听器调用、Electron IPC 消息或处理程序,或脚本卸载事件。这些事实仍然是明确的未知项。scriptParsed 证明脚本存在,而非导入模块、功能执行、初始化顺序或因果关系。
对于已授权的文件脚本,location.file_path 是经过验证的文件系统标识,可选的脚本项 reported_url 保留确切的 Inspector URL。脚本标识包含该报告的 URL,因此同一文件的查询和片段变体仍然是独立的观察结果。较旧的 Evidence 可能省略 reported_url,但仍可读取。
Node 和 Electron 角色¶
调用方声明一个角色:node、electron-main、electron-preload 或 electron-renderer。Node 和 Electron-main 声明要求协议目标类型为 node;preload 和 renderer 声明要求 page。Inspector 不验证操作系统 PID,也不区分 Electron 角色,因此 Evidence 将角色权威记录为 caller-declared-unverified。
如果最终的脚本位置授权失败,收集到的脚本和上下文事实仍可在带类型的失败中获取,并明确标注未验证的位置。描述符清理状态及其重试所有者独立于该捕获。
因此,Electron 主进程、preload 和 renderer 行为只能作为独立的 Inspector 目标来观察。提供者不会推断两个目标属于同一个 Electron 应用程序。
捕获与确定性¶
捕获在 8 MiB 的聚合预算内保留有效的脚本和执行上下文元数据,包括对 UTF-16 字符串、记录和集合开销以及预计 URL 字段的保守估计。每条 CDP 消息还有 16 MiB 的传输限制。超过该限制的消息以 payload_limit 失败;当达到聚合预算时,后续元数据事件被丢弃,部分结果报告 events_dropped、truncated: true 和 retained_metadata_budget_exceeded。重复的上下文转换会更新当前上下文记录,而不是累积重复对象。脚本在捕获后经过验证,按稳定元数据去重,并按规范排序。墙钟时间戳和协议脚本 ID 被排除在持久结果之外,因此相同的输入和捕获的元数据会产生相同的 Evidence ID。
Inspector 附加本质上是不完整的。启用 Debugger 会报告已知和未收集的脚本,但附加之前已收集的脚本可能缺失。观察窗口中的缺失永远不能证明脚本或行为不会发生。
取消会在当前文件系统操作结束后停止新的目标文件授权。取消诊断保留已检查的目标前缀;未检查的目标保持未知。观察取消保留其原始原因和任何已完成的 Evidence。最终化等待 REA 的有界套接字关闭(优雅和强制确认最多两秒)。关闭失败会保留其确切的传输所有者,并阻止替换连接,直到清理成功;CLI 最终化和 MCP 关闭也会重试保留的清理。关闭 REA 的连接不会停止调用方拥有的运行时。
静态关联¶
将生成的观察 Evidence 和 analyze_javascript_application Evidence 记录传递给 reconcile_javascript_runtime。该关联接受此提供者以及被动的 Web 和 Electron 页面捕获。请求中提供的精确文件或 URL 映射可以将脚本存在与 JavaScript Application Graph 资产关联起来。由于此提供者从不读取源字节,匹配通常使用唯一的授权位置,并且比捕获字节身份更弱。内置的 node: 脚本仍然是仅运行时节点,除非未来的显式静态权威对它们建模。
本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 rea2/rea