mcpField
I
inspecting-hermes-desktop-dom

inspecting-hermes-desktop-dom

github.com/nousresearch开发258.1k215 次安装今天更新
代码仓库

关于 inspecting-hermes-desktop-dom

用于开发 Hermes 桌面应用的技能,通过 Chrome DevTools Protocol 检查运行中的 DOM。开发者可查看渲染元素、计算样式、几何信息和控制台输出,而非仅依据源文件推断。

主要功能

  1. 01读取实时渲染器 DOM
  2. 02检查计算样式和几何信息
  3. 03定位匹配及生效的 CSS 规则
  4. 04读取渲染器控制台输出
  5. 05使用稳定的 data-slot 选择器

适用场景

  1. 01验证运行中应用的界面改动
  2. 02查明样式未生效的原因
  3. 03编辑组件前定位选择器
  4. 04检查用户反馈的渲染器错误

安装

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

$npx skills add https://github.com/nousresearch/hermes-agent --skill inspecting-hermes-desktop-dom

安装后在 Claude Code 中输入/inspecting-hermes-desktop-dom确认已加载。

详细介绍

检查实时 Hermes 桌面 DOM

概述

开发 apps/desktop 时,如果用户正在运行同一个应用 (hgui / npm run dev),你可以读取他们正在查看的窗口中的实时渲染 DOM, 包括计算后的样式、几何信息、实际生效的 CSS 规则、控制台输出,而不必根据 .tsx 推测后得出错误结论。

开发服务器运行时会自动在 127.0.0.1:9222 上开放 Chrome DevTools Protocol 端口。 渲染器是 Chromium 页面,因此 DevTools 能读取的内容,脚本也都能读取。

这不能替代亲自查看。 CDP 可以回答事实问题(“计算后的内边距是多少”、 “这个元素有没有渲染”、“哪个选择器匹配”),但无法判断结果看起来是否美观。 色彩平衡、间距观感,以及“这是不是很丑”,仍需用户亲自查看或查看截图。用 CDP 回答事实问题;审美判断交给用户。

适用场景

  • 验证 UI 变更是否确实在运行中的应用里生效
  • “为什么这个元素仍然是 X?”——修改前先找出实际生效的规则
  • 为即将修改的组件找到稳定的选择器
  • 检查真实节点上的设计令牌计算值
  • 查看用户提到但无法复制出来的渲染器控制台错误

不要用于: 性能分析或堆内存相关工作(node-inspect-debugger、 debugging-hermes-desktop),或任何真正的问题是“这样看起来对吗”的场景。

端口

任何开发服务器运行时,都会在 127.0.0.1:9222 上开放端口。只有以下两种情况会关闭 端口(apps/desktop/electron/dev-cdp.ts):

  • 打包构建——始终关闭,且任何环境变量值都无法覆盖此设置;
  • 未设置 HERMES_DESKTOP_DEV_SERVER——使用未打包的 electron . 加载 dist/ 来对打包应用进行冒烟测试,因此其行为与打包应用一致。

HERMES_DESKTOP_CDP_PORT 可以更改端口(=9333),也可以禁用端口(=off)。

开始其他操作前先检查:

curl -s --max-time 3 http://127.0.0.1:${HERMES_DESKTOP_CDP_PORT:-9222}/json/version

无输出 → 没有端口。不要擅自猜测其他端口。

绝不要为了获取端口而重启用户的应用。 这会破坏他们的会话和状态。 请改为启动你自己的隔离实例(见下文)。

读取 DOM

apps/desktop/scripts/eval.mjs 是用于单行操作的脚本:

cd apps/desktop
node scripts/eval.mjs "document.querySelectorAll('[data-slot]').length"

对于多步骤操作,请使用共享客户端——它支持目标发现和可处理 Promise 的求值:

import { CDP, SELECTORS } from './scripts/perf/lib/cdp.mjs'

const cdp = await CDP.connect({ port: 9222, match: '5174' })
const out = await cdp.eval(`JSON.stringify({
  radius: getComputedStyle(document.documentElement).getPropertyValue('--radius-scalar').trim(),
  composer: !!document.querySelector('[data-slot="composer-rich-input"]')
})`)
cdp.close()

scripts/perf/lib/cdp.mjs 中的 SELECTORS 保存了稳定的 data-slot 钩子 (composer、thread viewport、assistant message、turn pair、profile rail)。优先使用它们, 不要自行编造 querySelector——组件移动时,这些钩子会作为一个整体同步更新。

最适合用来回答的问题:哪条规则生效了?

因为样式“没有生效”就修改所有调用位置,是最常见的浪费。先读取真实节点:

const el = document.querySelector('[data-slot="aui_assistant-message-root"] a')
JSON.stringify({
  ownClasses: el.className,
  weight: getComputedStyle(el).fontWeight,
  parents: (() => {
    const out = []
    let n = el
    while ((n = n.parentElement) && out.length < 6) out.push(n.className)
    return out
  })()
})

如果节点本身没有 class 值,说明该值是继承的——逐个检查调用位置无法修复问题, 你需要检查祖先节点规则。插件样式表(例如 @tailwindcss/typography 中的 prose a { font-weight: 500 })通常会覆盖工具类;应在共享类上覆盖,而不是在每个使用位置分别覆盖。

你自己的隔离实例

没有端口,或必须避免干扰用户窗口时:

cd apps/desktop
HERMES_HOME=$HOME/.hermes/cache/scratch/cdp-probe-home \
HERMES_DESKTOP_DEV_SERVER=http://127.0.0.1:5174 \
HERMES_DESKTOP_CDP_PORT=9333 \
  npx electron . --user-data-dir=$HOME/.hermes/cache/scratch/cdp-probe-userdata

单独的 --user-data-dir 可以绕过 Electron 的单实例锁,因此不会与正在运行的 hgui 冲突;单独的 HERMES_HOME 则可使其与真实会话隔离。出于同样原因,请选择 9222 以外的端口。在后台运行,完成后将其终止。

如果还需要性能测试框架,npm run perf:serve 也会执行相同操作,并预先设置临时的 HERMES_HOME。

注意事项

  • 绝不要为了“腾出”资源而终止用户的开发服务器或应用。 在服务运行期间将其终止会清空 Chromium 的套接字池,随后出现的 ERR_NETWORK_CHANGED 会被归咎于你刚刚做的更改。
  • 临时的 HERMES_HOME 没有后端。 应用会针对 hermes:api 记录 ECONNREFUSED,并可能自行退出。渲染器仍会挂载,DOM 也可读取——请尽快读取,不要把自行退出的探测应用误认为端口故障。Chromium 绑定端口时会记录 DevTools listening on ws://127.0.0.1:<port>/…;这行日志证明端口已打开。
  • 轮询,不要只探测一次。 应用刚启动时,需要一两秒端口才会响应。
  • 绝不要转储整个 DOM。 桌面应用会渲染数百个节点,outerHTML 会淹没上下文。在求值表达式中将结果精简为一个小型 JSON 对象。
  • 将 match 传给 CDP.connect。 不传的话,你可能会连接到宠物浮层、快速输入窗口或 devtools 目标,而不是主窗口。
  • cdp.eval 会返回值;原始的 Runtime.evaluate 会多嵌套一层(.result.result.value)。请使用封装器。
  • 在此仓库中,vite dev 下的 import.meta.env.DEV 为 true。 apps/desktop/scripts/profile-typing-lag.md 中声称并非如此的说明已过时。

评论

支持 Markdown