Bundle
dsh-auto-chrome-tool
A DeepSeek Harness tool plugin that controls the user's existing Chrome session through a secure MV3 extension bridge.
- Source
- changyinliangbaikai
- License
- MIT
- Updated
- Updated yesterday
Readme
<div align="right">
**English** | [简体中文](./README.zh-CN.md)
</div>
# dsh-b2us-chrome-tool
Secure, local Chrome automation for [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) (DSH).
`dsh-b2us-chrome-tool` connects DSH to the Chrome session you already use through a Manifest V3 extension and an authenticated loopback bridge. It exposes bounded tab, semantic DOM, interaction, screenshot, verified-locator, and network-observation capabilities as DSH tools while keeping raw page data inside an isolated Browser Worker.
> [!IMPORTANT]
> This project is intended for local development and trusted environments. It does not read Chrome's password store, select password-manager suggestions, or return password-field values to an Agent.
> [!NOTE]
> `dsh-b2us-chrome-tool` is the project and repository name. For compatibility, the installable npm package, Cordis row, runtime routes, and existing data paths still use the technical identifier `dsh-auto-chrome-tool`. Installation and configuration examples therefore use that identifier.
## Harness 0.1.2-rc.1 compatibility
Version `0.4.2` raises every exact DSH peer to `0.1.2-rc.1`; mixed Harness/plugin prerelease versions are unsupported. Harness made the mutable Session event array private in this release, so the plugin now reads history only through the public immutable `snapshotEvents()` and `eventAt()` accessors.
This compatibility change does not rename tools, the Cordis row, HTTP routes, the extension protocol, or durable data directories, and it requires no data migration. Upgrade Harness and this plugin together before restarting the profile.
## Highlights
| Area | What the plugin provides |
| --- | --- |
| Existing Chrome session | Controls user-authorized tabs in the browser profile already in use; no separate automation profile is required. |
| Semantic page access | Returns bounded accessible names, roles, states, and short-lived opaque element references instead of dumping full page source. |
| Source-side search | `page.find` ranks relevant elements in the page runtime before returning results to the model. |
| Verified locators | `page.locator` produces CSS/XPath candidates in the live DOM and proves that each candidate uniquely identifies the intended element. |
| Page interaction | Supports click, exact-name click, non-sensitive text input, select, scroll, wait, and structured extraction. |
| Screenshots and network data | Captures screenshots and bounded Fetch/XHR metadata or bodies as opaque artifacts with redaction, quotas, and expiry. |
| Context isolation | A fresh Browser Worker receives page data and worker-only tools; the parent Agent receives only a bounded typed result. |
| Recoverable delivery | Browser execution and file delivery are reported separately, so a failed artifact copy can be retried without repeating a login, submission, or other browser action. |
| Guided setup | Detects Chrome, prepares the packaged extension only after DSH approval, and adds a bilingual Harness settings page for status, download, and pairing. |
| Defense in depth | Restricts the bridge to loopback, validates extension origins, uses mutual nonce/HMAC authentication, and enforces size, concurrency, timeout, and lifecycle limits. |
## How it works
```text
DeepSeek Harness / parent Agent
├─ status, approved extension setup, task delegation, artifact delivery
└─ fresh Browser Worker session
└─ worker-only tab, page, locator, screenshot, and network tools
└─ authenticated loopback WebSocket bridge
└─ Chrome MV3 service worker
├─ tabs and bounded screenshot capture
├─ frame-aware DOM runtime
└─ opt-in, redacted network runtime
```
The parent Agent cannot directly call the low-level tab, page, or network tools. Page content is treated as untrusted input, low-level results expire after one Worker reasoning step, and deterministic rollover checkpoints exclude page text, network bodies, input text, and element references.
## Security boundaries
- The WebSocket server accepts only `127.0.0.1`, `::1`, or `localhost`.
- Pairing requires a token of at least 16 characters. The token is never placed in extension source, URLs, or WebSocket frames; both sides prove possession with nonce-bound HMAC-SHA-256.
- Only `chrome-extension://<extension-id>` origins may authenticate. Production deployments should set `allowedExtensionIds` to the built extension's fixed ID.
- The plugin exposes neither arbitrary JavaScript evaluation nor arbitrary Chrome DevTools Protocol commands.
- Password, OTP, CVV, token, and secret fields reveal only `sensitive` and `filled` state. Text injection into those fields is rejected.
- Cookie, authorization, API-key, token, session, and similar network values are redacted; authentication endpoints do not retain bodies by default.
- Screenshot and network-body artifacts are quota-bound, time-limited, owned by the originating Worker, and delivered only beneath the initiating Session's working directory.
- Extension preparation requires the native DSH approval path. The plugin never edits Chrome profiles, preferences, cookies, password storage, or extension policy.
- Chrome remains the final authority for loading an unpacked extension and granting local-network access.
See [Security model](./docs/SECURITY.md) for the complete threat model and trust assumptions.
## Requirements
- Node.js `^22.19.0 || >=24.0.0`
- Google Chrome 125 or later
- The exact DSH `0.1.2-rc.1` and Cordis `4.0.2` peer versions declared in [`package.json`](./package.json)
- A bridge token with at least 16 characters, supplied as `authToken` or `DSH_AUTO_CHROME_TOKEN`
## Quick start
### Desktop-bundled installation
When a desktop distribution already includes the plugin, do not run `dsh plugin add` again.
1. Open **Settings → Plugins → Chrome Browser** in Harness.
2. Download the extension ZIP and extract it to a stable directory.
3. Open `chrome://extensions`, enable **Developer mode**, select **Load unpacked**, and choose the extracted directory containing `manifest.json`.
4. Copy the host, port, and pairing token from the Harness settings page into the extension popup, then select **Pair and connect**.
5. If Chrome requests local-network access, allow it. Return to Harness and refresh the status until both the extension and bridge report connected.
The settings page only reads same-origin loopback status and downloads the MV3 bundle packaged with the installed plugin. It does not scan a Chrome profile or silently install an extension. The desktop host must provide `authToken` or `DSH_AUTO_CHROME_TOKEN`; the plugin fails closed when no valid token is configured.
### Standalone development or installation
Install dependencies and run the full repository gate:
```bash
npm ci
npm run check
```
Create a token, build and pack the plugin, then install the tarball into an isolated DSH profile:
```bash
export DSH_AUTO_CHROME_TOKEN="$(openssl rand -hex 32)"
npm run build
npm pack
dsh plugin --profile web add ./dsh-auto-chrome-tool-0.4.2.tgz
dsh --profile web --dump-config
```
The release tarball bundles the `fflate` and `ws` runtime dependencies for offline installation. DSH and Cordis remain host-provided peer dependencies and are not duplicated in the package.
## Configuration
The package-owned [`cordis.patch.yml`](./cordis.patch.yml) contains the complete default configuration. A DSH patch replaces the entire `config` object instead of deep-merging it, so retain every field your deployment needs when overriding the row.
| Setting | Purpose and default |
| --- | --- |
| `host` / `port` | Loopback bridge endpoint; `127.0.0.1:17321`. |
| `authToken` | Shared pairing token; falls back to `DSH_AUTO_CHROME_TOKEN`. |
| `allowedExtensionIds` | Optional extension-ID allowlist; empty allows any valid extension origin that also holds the token. |
| `artifactMaxBytes` / `artifactTtlHours` | Internal artifact quota and retention; 256 MiB and 24 hours. |
| `chromeExecutablePath` | Optional absolute Chrome executable path; standard platform locations and `PATH` are checked when empty. |
| `extensionInstallDir` | Stable prepared-extension directory; defaults to `.dsh-auto-chrome-tool/extension` under the user directory. |
| `openChromeOnInstall` | Opens `chrome://extensions` after an approved preparation step; `true`. |
| `browserWorkerLlmProvider` / `browserWorkerModel` | Optional Worker-specific model route; both values must be set together. |
| `browserWorkerSoftTokenLimit` / `browserWorkerHardTokenLimit` | Fresh-generation rollover thresholds; 96K and 128K tokens. |
| `browserWorkerMaxSteps` / `browserWorkerMaxToolCalls` | Per-task execution ceilings; 32 steps and 40 browser calls. |
| `browserParentMaxDelegationsPerTurn` | Parent-turn delegation ceiling; 8. |
| `browserParentMaxUnsuccessfulDelegationsPerTurn` | Opens the browser-only parent-turn circuit after 2 blocked or failed outcomes. |
Additional observation, extraction, network-preview, timeout, history, concurrency, and message-size limits are documented by the schema and default patch.
## Tool isolation
The parent Agent sees only these browser-facing tools:
- `browser_status`
- `browser_extension_status`
- `browser_extension_install`
- `browser_delegate_task`
- `browser_artifact_deliver`
The fresh Browser Worker receives the low-level `browser_tabs_*`, `browser_page_*`, and `browser_network_*` catalog. A process-local identity guard enforces the same boundary at execution time, so a manually constructed tool call cannot bypass the scoped catalog.
For reusable Selenium or Playwright automation, ask the Worker to capture verified locators. Open Shadow DOM locators include a verified host chain; child-frame locators are explicitly frame-local and require a separately verified frame-switch path.
## Repository layout
```text
src/
browser-worker/ Fresh Worker sessions, isolation, budgets, checkpoints
bridge/ Authenticated WebSocket sessions and lifecycle
client/ Harness settings UI and English/Chinese locale strings
config/ Schemastery configuration and resolution
domain/ Shared JSON and error models
extension/ MV3 background, DOM, and network runtimes
protocol/ Versioned DSH ↔ extension protocol
services/ Browser control, locator, and artifact services
settings/ Same-origin status and extension-download routes
setup/ Chrome discovery, approved preparation, launch guidance
tools/ Capability-focused DSH tool definitions
extension/ Manifest, popup/options UI, and built extension assets
tests/ Unit, integration, packaging, client, and snapshots
docs/ Architecture, security, development, and evidence
```
## Development and verification
```bash
npm run typecheck
npm test
npm run test:coverage
npm run test:snapshot
npm run test:built
npm run build
npm run check
npm pack --dry-run
```
`npm run check` is the required repository-local gate. It covers strict type checking, built Host/Web/extension artifacts, behavioral and lifecycle tests, host-side per-file coverage thresholds, packed-package behavior, and the reviewed keyless tool-catalog snapshot.
Automated extension simulation proves the protocol and bridge only. It does not prove a real Chrome MV3 connection, Chrome permission prompts, desktop packaging, or subjective UI quality. Those acceptance layers must be run and reported separately. See [Development and verification](./docs/DEVELOPMENT.md) and [recorded verification evidence](./docs/VERIFICATION.md).
## Known limitations
- `chrome://` pages, the Chrome Web Store, other extension pages, and closed Shadow Roots cannot be controlled by an ordinary content script.
- Child-frame locators are unique only inside their frame document; the plugin does not invent an iframe selector chain.
- Opaque DOM references are intentionally short-lived and must be refreshed after navigation or relevant semantic changes.
- Opening DevTools can take over a `chrome.debugger` session; network capture reports the detach explicitly.
- Standard Chrome requires manual **Developer mode → Load unpacked** confirmation. The plugin does not bypass Chrome's installation policy.
- The extension requests broad site and debugger permissions because full-page DOM control, screenshots, and opt-in network-body capture require them.
- Browser Worker isolation is an Agent/Session/tool/context boundary inside the DSH process, not an operating-system process boundary.
- DSH `0.1.2-rc.1` is a prerelease dependency; compatibility is intentionally pinned to exact peer versions.
## Documentation
- [Architecture](./docs/ARCHITECTURE.md)
- [Security model](./docs/SECURITY.md)
- [Development and verification](./docs/DEVELOPMENT.md)
- [Browser Worker design](./docs/PAGE_ANALYST_DESIGN.md)
- [Recorded verification evidence](./docs/VERIFICATION.md)
## License
[MIT](./LICENSE)
Install
dsh plugin --profile web add github:changyinliangbaikai/dsh-b2us-chrome-tool
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install dsh-auto-chrome-tool from the hub
- This package builds from source on install. pnpm will ask you to allow its build script — that is permission to run the package’s code on your machine, outside the agent sandbox. Only allow sources you trust.
- This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.