by youbaiyun
Browser extension for the DeepSeek Harness desktop app. The model reads the page you are on as text with numbered controls and acts on it — click, type, scroll, navigate, manage tabs — and, when you switch image recognition on, looks at an image you point at. It asks before acting, keeps passwords in the page, and talks to your own desktop; the one
# Add to your Claude Code skills
git clone https://github.com/youbaiyun/dsh-browser-crossplatformGuides for using ai agents skills like dsh-browser-crossplatform.
See how dsh-browser-crossplatform compares with popular alternatives.
dsh-browser-crossplatform is an open-source ai agents skill for AI coding assistants such as Claude Code, Codex CLI, and ChatGPT, built by youbaiyun. Browser extension for the DeepSeek Harness desktop app. The model reads the page you are on as text with numbered controls and acts on it — click, type, scroll, navigate, manage tabs — and, when you switch image recognition on, looks at an image you point at. It asks before acting, keeps passwords in the page, and talks to your own desktop; the one. It has 67 GitHub stars.
dsh-browser-crossplatform's catalog security scan is still queued. You can run an instant dependency and prompt-injection check now with the "Scan for vulnerabilities" button above.
Clone the repository with "git clone https://github.com/youbaiyun/dsh-browser-crossplatform" and add it to your Claude Code skills directory (see the Installation section above).
dsh-browser-crossplatform is primarily written in TypeScript. It is open-source under youbaiyun on GitHub, so you can review or fork the full source.
Yes. SkillsLLM lists many other AI Agents skills you can browse and compare side by side. Open the AI Agents category from the badge at the top of this page, or use the Related Skills and comparison links further down to weigh dsh-browser-crossplatform against similar tools.
No comments yet. Be the first to share your thoughts!
⚠️ Third-Party Software Notice
This skill is third-party open-source software developed and hosted independently on GitHub. SkillsLLM is an informational directory and does not control or maintain the underlying repository.
Any security checks, ratings, or warnings displayed by SkillsLLM are automated and limited in scope. They do not constitute a security certification or guarantee that the software is safe, error-free, or free from malicious code, vulnerabilities, compromised dependencies, or prompt-injection risks.
Review the source code, permissions, dependencies, and configuration before installing or running any third-party skill. Use is at your own risk. To the maximum extent permitted by applicable law, SkillsLLM is not liable for losses arising from third-party software.
The deep catalog scan for this skill is still queued. Run an instant dependency check now instead.
See comparison
中文版见 README.zh.md
An MV3 extension + bridge plugin that lets the dsh desktop app read and operate a browser tab: pages are handed to the model as text (numbered actionable controls), and when image viewing is needed there is a separate optional channel, off by default. This is a derivative rewrite of Lum1104/dsh-browser, restructured around two priorities — high compatibility and trimming bloat — while balancing stability with efficiency.
You can find this bridge plugin in the plugin marketplace under dsh-plugin, the marketplace's conventional topic tag.
What sets it apart from similar projects: cross-platform (Windows / macOS / Linux, zero platform branches in the source) · the root package has zero dsh dependencies (the bridge declares all of dsh as peerDependencies) · image viewing is optional and off by default · one unified version number across the whole repository · and benchmarks and CI that compare the extension against a local Playwright baseline in pairs.
Three routes — pick any one:
| What you want | Where to get it |
|---|---|
| The extension in the browser (side panel) | Browser extension store ([Chrome] (not yet listed) / [Firefox] (not yet listed)) |
| The bridge plugin (lets dsh talk to the extension) | This repository — github.com/youbaiyun/dsh-browser-crossplatform. One command, see below |
| Offline packages (to load yourself / upload to the store) | The two zips under Releases |
# From the npm registry (published: dsh-browser-crossplatform@0.38.5):
dsh plugin --profile desktop add dsh-browser-crossplatform # the CLI dsh web uses --profile web
# Or straight from this repository, with no registry involved:
git clone https://github.com/youbaiyun/dsh-browser-crossplatform
dsh plugin --profile desktop add link:<clone>/packages/bridge
Step-by-step foolproof instructions (including "how to confirm it is installed") are in docs/INSTALL.md.
The extension itself is installed from the browser extension store (or load the unpacked build yourself following the build section below); the package above is the bridge plugin, and its settings page lives inside dsh, titled 「dsh 浏览器扩展(全端)的桌面端一半」.
0.38.5)packages/protocol zero-dependency wire protocol (frame validation, capability/authority split)
packages/bridge dsh bridge plugin (WebSocket server + browser_* tools, runs inside dsh)
extension the Chrome/Firefox MV3 extension itself
| Target | Minimum version | Where this number comes from |
|---|---|---|
| Operating system | Windows / macOS / Linux — all supported (CI is Linux, so it is verified the most thoroughly) | The platform-specific code is confined to one place, packages/bridge/src/browser-launch.ts, which has to know where each platform keeps its browsers and profiles; build/benchmark tooling adds the Windows .cmd shim. Everything else is platform-neutral. CI's ubuntu-latest is Linux, and the full chain runs on it for every commit |
| dsh desktop | Node ≥ 20 | engines.node in the root, bridge and extension manifests (the protocol package declares none, because it is a private workspace package with no scripts to run) |
| Desktop Chrome / Chromium / Edge | 116 | minimum_chrome_version in extension/manifest.json |
| Desktop Firefox | 140.0 | gecko.strict_min_version in extension/manifest.firefox.json |
| Panel UI | Chrome uses side_panel, Firefox uses sidebar_action |
Both point at the same control/index.html |
| Build/test (development) | Node 22 + pnpm 11 | .github/workflows/check.yml |
| Phone / tablet | ❌ Not supported | See below |
The bridge has only ws and @deepseek-ai/schemastery as runtime dependencies, and both are platform-independent; the extension bundles its two panel-only dependencies (marked, dompurify) into the build.
CI builds both browser targets and runs the full test suite (including end-to-end cases that actually launch Chromium);
Windows has been verified locally; macOS is not covered by CI, but it is POSIX like Linux and the platform-specific surface is that one module.
The loopback shortcut is bound to named extension ids. The bridge normally authenticates with a bearer token, but a loopback upgrade from the extension itself skips it so discovery stays zero-config. That exemption is not "any chrome-extension:// origin" — every other extension on the machine has one of those too — but an exact match against extensionId, a comma-separated list whose default names two ids: kdhkdgfcinfkmogifamoapmheihhcjfk, which this repository's manifest key produces, and agpipnjijkpomaannkijkilggoffdiaf, which the Chrome Web Store assigned. Both are needed because the store refuses a manifest carrying key, so a development load and a store install present different origins. Add your own id to the list for a build of your own, or set extensionId: '' in the plugin config to require the token on every connection, including loopback.
Why phones and tablets are not supported: Chrome / Edge for Android does not support third-party extensions;
Firefox for Android has no side panel UI; and the bridge is loopback-only where it matters — the
token-free path and the privileged gateway methods (host.pickDirectory, host.openPath, settings.*,
credentials.*) are both gated on a loopback remote (packages/bridge/src/server.ts), and a phone would be
connecting to 127.0.0.1 on a different machine. A non-loopback remote with a valid token can still use the
ordinary session methods that dsh web --host exists to serve; what it cannot do is reach the privileged ones.
| Dimension | Original | This version |
|---|---|---|
| Version | Root 0.2.1 / extension 0.3.1 / bridge 0.0.7, each drifting independently | Unified 0.38.5 — root package, protocol, bridge, extension and both manifests all agree |
| Node | ^22.19 || >=24 |
>=20 |
| TypeScript | Split between extension 5.6 and bridge 6.0 | One toolchain; the extension's declared range is ^5.6, the bridge's and the protocol's ^5.7, and the lockfile resolves a single installed version |
| Dependencies | 35 @deepseek-ai/* (RC) in the root package, node_modules at 600 MB |
0 dsh dependencies in the root package (its tests and typecheck are pure Node + a bundled tsc); the bridge ships with only ws + @deepseek-ai/schemastery and declares all of dsh as peerDependencies (at runtime it probes the host via ctx.get(), and bundles nothing); the extension has two panel-only runtime dependencies (marked + dompurify), both bundled into the panel build |
| Bridge hard-deps | React peer + 3 web-side dsh-client-ui-*/locale peers + a dsh.client injection block |
All removed (the extension panel is self-contained and injects no UI into dsh's web client) |
| Bridge protocol | Its own protocol.ts (12.7 KB), with a separate copy in the extension |
Shared @dsh-browser/protocol, inlined into both artifacts by the bundler |
| Bridge redundancy | Plus a web-side client.js (7.2 KB) |
Deleted |
| Injection | the manifest's global content_scripts inject into every iframe on every site |
Same global content_scripts declaration (the extension cannot know in advance which tab you will point it at), but bounded at the other end: only the tab you bound is read or operated, and chrome.scripting re-injects on demand into tabs that predate the install. See docs/TRUST-MODEL.md ("broad injection, narrow authority") |
| Browser minimums | Chrome 116 / Firefox 140 | Same requirements as upstream, not relaxed (Chrome 116 / Firefox 140) |
| Build | 3 vite configs + shared + build.mjs (5 files) | The same shape, deliberately: one build.mjs sequences the three targets, and vite.shared.ts holds what they share. What changed is that the config list lives in one script instead of being documented in three places |
| Test runner | vitest + jsdom | vitest (jsdom environment for the extension panel, node environment for the bridge) |
textOnly: true). Pages are rendered into structured text: title/URL/body (readability-lite) + a numbered interactive inventory (including ARIA role controls) + form fields (including masked/checked/required), with support for delta diffs and region partial snapshots.type=password, autocomplete=credit-card|cc-*, id/name/aria-label matching password|passwd|credit|card|cvv|cvc|secret|pwd) are always masked as ••••; the accessible name never uses the input's current value (only the value of submit/button/reset inputs counts as a name), and unit tests enforce this.browser_snapshot / click / type / press / scroll / navigate / open_tab / list_tabs / follow_tab / close_tab / back / forward / reload / get_text / wait / launch / describe_image. Full parameter list: delta/region/replace/amount/selector/ms/active/tabId/index/text/key/direction/url, plus frame on the 7 frame-scoped tools. browser_describe_image answers only while recognition is on; browser_launch is the one tool that runs on the desktop side, because it is the only one that can work with no browser running.browser_launch, and before every tool): tool execution lives in the extension, so with the browser closed there is nothing