CDP bridge to an already-running Chrome/Edge for DSH: screenshots, pixel assertions, DOM/CSS checks, and page JS evaluation over HTTP + WebSocket, with zero child processes, zero npm dependencies, and zero per-use approval.
Install
# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)
dsh plugin --profile web add github:zaiwenJ/dsh-cdp-browser
Any plugin you install runs third-party code with your own permissions — it can read your files, use your credentials, and reach the network, and tool approvals don’t sandbox it. GitHub-sourced plugins also run build scripts at install time — pnpm blocks those until you allow them, so an install can stop with ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED or ERR_PNPM_IGNORED_BUILDS; dsh prints the exact key to add under allowBuilds in your profile’s pnpm-workspace.yaml, and the install works on the next run. Allowing a build is a trust decision: only install sources you trust, and pin a commit (github:owner/repo#sha).
README
Zero-spawn browser automation + pixel-level visual verification as a DeepSeek
Harness plugin. Drives an already-running Chrome/Edge over CDP using Node
built-ins only: global fetch + global WebSocket (Node ≥ 22) + zlib PNG
decode. No child_process, no npm dependencies, no per-use approval.
Why zero-spawn
Plugins that spawn an engine and pipe its stdio (e.g. modlens) collide with the harness sandbox's pipe ban (EPERM/EINVAL) on every call. Connecting to a browser the user started themselves is plain network I/O — allowed in confined mode. The one manual step (launching the browser) happens outside the harness, so the model never needs approval again for visual checks.
Setup (once)
Install into the profile (done via
dsh plugin --profile web add file:<path>).Start your browser with CDP (the provided
edge-debug.cmddoes this):msedge.exe --remote-debugging-port=9222 --remote-allow-origins=* --user-data-dir=<dir> <url>Restart the Web GUI. The
cdp_*tools appear in the next session.
Tools
| Tool | What it does |
|---|---|
cdp_status |
List tabs/targets of the CDP browser + browser version |
cdp_open |
Open (or reuse) a tab for a url; returns target id |
cdp_eval |
Evaluate JS in a page (awaitPromise, returnByValue) |
cdp_shot |
Navigate + PNG screenshot, saved to an absolute path |
cdp_assert |
Scripted interaction + deterministic checks (pixel / css / dom / js) with a pass/fail report |
cdp_assert check shapes
checks: [
{ type: 'pixel', x: 0.5, y: 0.96, color: '#245edb', tolerance: 16 }, // relative coords 0..1 or absolute px
{ type: 'css', selector: '#taskbar', property: 'background-color', equals: 'rgb(36, 94, 219)' },
{ type: 'css', selector: '.xp-window', property: 'border-radius', matches: '^\\d+px' },
{ type: 'dom', selector: '.xp-desk-icon', text: 'My Computer' },
{ type: 'js', expression: 'window.__XP.selfTest()', equals: { ok: true } },
]
// every check accepts click: '#start-btn' | { selector } | { x, y } and waitMs
Development
node plugins/dsh-cdp-browser/test/e2e.mjs # needs dev server + CDP Edge, starts nothing
Determinism notes (learned from the XP app's first plugin e2e):
- Reload the page per test run. A long-lived tab accumulates state across
scripted sweeps (windows, dialogs, menus) and can wedge
openApp; a freshnavigate+skipBootper suite is deterministic.probe-apps.mjsbisects per-app hangs when an app regresses. - Synthetic clicks toggle state.
el.click()runs the real handlers — clicking a toggle twice flips it twice. One click per assertion. - Gradient surfaces need stop-aware sampling. Sample where a gradient stop
dominates (flat zones or edges), not mid-gradient blends, or use
tolerance-aware
nearColoragainst computed-style values.
The package exposes ./cdp (targets, openTarget, withPage, Cdp,
decodePng, samplePixel, nearColor, runChecks, savePng) for reuse
outside the harness.
Links
More in this category
Tencent/BrowserSkill#dsh-plugin-browserskill★ 7907
BrowserSkill bridge for controlling visible Chrome and Edge Agent Windows from DeepSeek Harness, with native browser tools, accessibility and VOM observations, screenshots, owned multi-session control, and a live Web UI overlay.
omdsh-dev/dsh-browser#packages/browser/bridge-browser★ 746
Chrome sidebar extension that lets DSH operate your browser directly, no vision capabilities required.
liustack/modsearch★ 572
Web search bridge for text-only agents: ask the web or X, get structured JSON evidence (search, fetch, citations).
DDDMUC/dsh-free-search★ 281
Free, keyless web search for DSH: 7 engines (DuckDuckGo/Bing/SearXNG free + Exa/Perplexity/DeepSeek paid), auto-failover, settings-page UI with API key inputs and official links, web_fetch, and an engine test tool.
Tabbit-Browser/dsh-tabbit★ 101
Gives DeepSeek Harness control of the Tabbit Browser: auto-loads the tabbit-browser skill on install, detects official Tabbit and Tabbit Browser releases (>= 1.9.0), checks the tabbit-cli persistent runtime, diagnoses the per-platform DSH sandbox mode needed to call the CLI, and downloads the region-matched official installer via a background job when no qualifying version is present.
wqty123/dsh-browser★ 84
Shared real browser for DSH: a native Electron window the human can watch and take over, driven by the agent over CDP with 20 browser_* tools (open/snapshot/execute/fill/screenshot/download/auth), per-task session isolation, cookie persistence, CAPTCHA detection; self-hosts on plain dsh web without a desktop shell.
Community comments
Comments are public GitHub Discussions. Loading them connects to GitHub and Giscus; a GitHub account is required to post.