mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-29 18:46:59 +00:00
The renderer is a Chromium page, and apps/desktop already carries a whole
CDP toolkit for it — scripts/eval.mjs, scripts/perf/lib/cdp.mjs with its
shared SELECTORS map, and the diag-*/probe-* family. None of it can
attach to `hgui` or `npm run dev`, because neither passes
--remote-debugging-port. The only launcher that opens one is
`npm run perf:serve`, which is a separate isolated instance rather than
the app you're looking at.
Add HERMES_DESKTOP_CDP_PORT. When set, the shell opens a CDP port on
loopback so that existing tooling can read the live DOM: computed
styles, geometry, which rule actually won.
Three independent gates, all required, resolved by a pure function in
electron/dev-cdp.ts so the policy is testable without an Electron app:
1. not packaged — a shipped build never opens the port, and this is
checked first so no env combination can talk it into doing so;
2. HERMES_DESKTOP_DEV_SERVER present — an unpackaged `electron .`
against dist/ is how the packaged app gets smoke tested, so it
behaves like the packaged app here;
3. the port explicitly requested and a valid integer.
Default `npm run dev` is unchanged and silent: no port, no nag. An
opt-in that gets refused always logs why, so nobody loses an hour
wondering what isn't listening.
The address is pinned to 127.0.0.1 rather than left to Chromium's
default, and is deliberately not configurable — there's no reason to
expose a renderer debugger off-host and offering the knob invites
someone to try.
scripts/eval.mjs hardcoded :9222 and threw a raw ECONNREFUSED stack when
nothing was there. It now honours the same variable and explains itself.
45 lines
1.7 KiB
JavaScript
45 lines
1.7 KiB
JavaScript
// Simple eval helper — runs an expression and returns the result.value.
|
|
//
|
|
// node scripts/eval.mjs "document.title"
|
|
// HERMES_DESKTOP_CDP_PORT=9333 node scripts/eval.mjs "document.title"
|
|
//
|
|
// Needs a renderer with a debugging port: launch `hgui` / `npm run dev` with
|
|
// HERMES_DESKTOP_CDP_PORT set (see electron/dev-cdp.ts).
|
|
const port = Number(process.env.HERMES_DESKTOP_CDP_PORT || 9222)
|
|
let targets
|
|
|
|
try {
|
|
targets = await (await fetch(`http://127.0.0.1:${port}/json`)).json()
|
|
} catch {
|
|
console.error(
|
|
`no renderer debugging port on 127.0.0.1:${port}. ` +
|
|
'Relaunch the app with HERMES_DESKTOP_CDP_PORT set, or point this script at the right port.'
|
|
)
|
|
process.exit(1)
|
|
}
|
|
|
|
const t = targets.find((t) => t.url.includes('5174')) ?? targets.find((t) => t.type === 'page')
|
|
|
|
if (!t) {
|
|
console.error(`no page target on 127.0.0.1:${port} (found ${targets.length} target(s))`)
|
|
process.exit(1)
|
|
}
|
|
|
|
const ws = new WebSocket(t.webSocketDebuggerUrl)
|
|
let id = 0
|
|
const pending = new Map()
|
|
ws.addEventListener('message', (ev) => {
|
|
const m = JSON.parse(ev.data)
|
|
if (pending.has(m.id)) { pending.get(m.id)(m); pending.delete(m.id) }
|
|
})
|
|
await new Promise((r) => ws.addEventListener('open', r))
|
|
const send = (method, params) => new Promise((res) => { const i = ++id; pending.set(i, res); ws.send(JSON.stringify({ id: i, method, params })) })
|
|
|
|
const expr = process.argv[2] || '1+1'
|
|
const r = await send('Runtime.evaluate', { expression: expr, returnByValue: true, awaitPromise: true })
|
|
if (r.result.exceptionDetails) {
|
|
console.error('EXCEPTION:', r.result.exceptionDetails.exception?.description)
|
|
} else {
|
|
console.log(JSON.stringify(r.result.result.value, null, 2))
|
|
}
|
|
ws.close()
|