Skip to content
dsh.fish
Agent preset

dsh-browser-pilot

Browser automation tools for the DeepSeek Harness (DSH) agent - a self-contained Cordis agent-preset plugin (Playwright).

Source
momo-gen
stars
1 stars
License
MIT
Updated
Updated 5 days ago

Readme

# dsh-browser-pilot

> Browser automation for the [DeepSeek Harness](https://github.com/deepseek-ai/DeepSeek-Harness) (DSH) agent โ€”
> a self-contained Cordis **agent-preset plugin** that gives the agent safe, guard-railed control of a
> real web browser (navigate, click, type, screenshot, extract) via [Playwright](https://playwright.dev/).

[![license](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
[![node](https://img.shields.io/badge/node-%3E%3D18-green.svg)](package.json)
[![playwright](https://img.shields.io/badge/playwright-1.48%2B-2EAD33.svg)](package.json)

๐ŸŒ [ไธญๆ–‡ๆ–‡ๆกฃ](README.zh.md) ยท English

It is designed to be **published and shared**: clone this repository into your DSH user preset root,
install one dependency, and your next session gains a full set of `browser_*` tools on top of the
standard coding agent.

> The agent can *operate* the browser, but only through explicit safety rails โ€” URL scheme
> allow-listing, output-path sandboxing, and no host-side code execution. See
> [Security model](#security-model) and [`SECURITY.md`](SECURITY.md).

## Demo

A DSH agent driving the browser end-to-end โ€” `browser_navigate` โ†’ `browser_type` โ†’ `browser_click`:

![Browser Pilot demo](docs/demo.gif)

The result of that interaction (the agent filled the input, clicked, and captured the page):

![Browser Pilot screenshot](docs/demo.png)

## Features

- **14 model tools** exposing the full browser surface: `browser_navigate`, `browser_snapshot`,
  `browser_text`, `browser_html`, `browser_click`, `browser_type`, `browser_press`,
  `browser_select`, `browser_screenshot`, `browser_pdf`, `browser_wait`, `browser_evaluate`,
  `browser_status`, `browser_close`.
- **Cross-browser**: Chromium, Firefox, and WebKit (Chromium by default).
- **Safe by default**: `javascript:`/`data:`/`file:`/`chrome:`/`about:config` navigation is
  rejected; screenshots and PDFs are confined to the session workspace; arbitrary page JavaScript
  (`browser_evaluate`) is off until you opt in.
- **Zero harness-internal dependencies**: the plugin imports only `playwright` and Node built-ins,
  so it loads from a relative path inside the preset without needing the harness's own
  `@deepseek-ai/*` packages.
- **Lifecycle-correct**: the browser is a lazy singleton owned by the plugin and is closed when the
  preset unmounts.

## Tech stack

| Layer | Choice | Notes |
| --- | --- | --- |
| Language | TypeScript 5 (strict) โ†’ ES2022 ESM | type-safe, compiled with `tsc` |
| Runtime | Node.js โ‰ฅ 18 | `"type": "module"` |
| Engine | Playwright (Chromium / Firefox / WebKit) | the only runtime dependency |
| Host integration | Cordis plugin (`apply(ctx, config)`), registered via `ctx.tools.register` | no `isolate` realm needed โ€” publishes no service |
| Distribution | DSH agent preset (a directory with `agent.cordis.yml` + `preset.yml`) | referenced by relative path `./dist/index.js` |
| Tests | `node:test` + `node:assert` (built-in) | unit (guards) + integration (real Chromium) |
| Build | `tsc`, no bundler | output into `dist/` (built, not committed) |
| CI | GitHub Actions | build + test + audit |
| License | MIT | |

## Quick start

### 1. Install

Clone this repository into your DSH user preset root (the directory name becomes the preset id):

```powershell
git clone https://github.com/<you>/dsh-browser-pilot `
  "$env:DSH_HOME/.agent-presets/browser-pilot"
cd "$env:DSH_HOME/.agent-presets/browser-pilot"
npm install
npm run build
npm run install-browsers   # downloads Chromium once (shared cache)
```

`$env:DSH_HOME` defaults to `~/.dsh` (on Windows: `C:\Users\<you>\.dsh`).

> **ๅ›ฝๅ†…็”จๆˆทๅปบ่ฎฎ็”จ้•œๅƒ (China users: use a mirror)** โ€” downloading the browser via the npmmirror
> CDN is an order of magnitude faster than the official CDN (verified). Set this before
> `npm run install-browsers`:
>
> ```powershell
> $env:PLAYWRIGHT_DOWNLOAD_HOST='https://cdn.npmmirror.com/binaries/playwright'
> ```

### 2. Start a session on the preset

Create a new DSH session and pick the **`browser-pilot`** preset (or set it as your default in the
preset picker). The agent now has the `browser_*` tools.

### 3. Try it

Ask the agent, for example:

> Open https://example.com, tell me the page title, then take a screenshot.

The agent will call `browser_navigate`, `browser_snapshot`, and `browser_screenshot` in sequence.

## Tool reference

| Tool | Purpose |
| --- | --- |
| `browser_navigate(url, waitUntil?)` | Open a URL (scheme-guarded). Returns URL + title. |
| `browser_snapshot(maxChars?)` | URL + title + visible body text (truncated). |
| `browser_text(selector)` | `innerText` of the first element matching a CSS selector. |
| `browser_html()` | Full page HTML (truncated). |
| `browser_click(selector, timeout?)` | Click the first matching element. |
| `browser_type(selector, text)` | Fill an input/textarea (replaces current value). |
| `browser_press(selector, key)` | Press a key (`Enter`, `Tab`, `Escape`, โ€ฆ) on an element. |
| `browser_select(selector, value)` | Select a `<select>` option. |
| `browser_screenshot(filename?, fullPage?)` | Save a PNG/JPG/WebP into the workspace; returns the path. |
| `browser_pdf(filename?)` | Save the page as PDF (headless Chromium). |
| `browser_wait(ms)` | Wait a number of milliseconds. |
| `browser_evaluate(expression)` | Run a JS expression **in the page** (opt-in). |
| `browser_status()` | Whether the browser is running, plus URL + title. |
| `browser_close()` | Close the browser; a later call relaunches it. |

## Configuration

Configuration lives in the preset row in `agent.cordis.yml`:

```yaml
- id: tool-browser
  name: ./dist/index.js
  config:
    browser: chromium        # chromium | firefox | webkit
    headless: true           # set false for a visible window
    timeout: 30000           # per-action timeout in ms
    allowEvaluate: false     # enable browser_evaluate (runs JS in the page)
    allowFile: false         # allow file:// navigation (reads local files)
    allowedSchemes:          # extra schemes beyond http/https
      - http:
      - https:
```

All keys are optional and default to the safe values shown above.

## Security model

The plugin is "arbitrary browser operation" with guard rails, not bare-metal access. Three
invariants, all covered by unit tests:

1. **Scheme allow-list** โ€” `browser_navigate` rejects `javascript:`, `data:`, `file:` (unless opted
   in), `chrome:`, `vbscript:`, and every `about:` URL except the inert `about:blank`. A bare host
   is treated as `https://`.
2. **Output-path sandbox** โ€” `browser_screenshot`/`browser_pdf` resolve the filename against the
   session workspace and reject `..` traversal, absolute escape, NUL bytes, and disallowed
   extensions.
3. **No host execution** โ€” the plugin never spawns a shell or evaluates code in the Node host.
   `browser_evaluate` runs only in the page context and only when `allowEvaluate: true`.

Full threat model and residual risks: [`SECURITY.md`](SECURITY.md).

## Development

```powershell
npm install
npm run build          # compile src/ โ†’ dist/
npm test               # unit + integration tests (needs `npm run install-browsers` first)
npm run typecheck      # strict type check only
npm run audit          # dependency vulnerability scan
```

The integration tests spin up a local HTTP server and drive a real headless Chromium against it โ€”
no external network required.

## Repository layout

```
โ”œโ”€โ”€ agent.cordis.yml   # full preset composition (standard + this plugin row)
โ”œโ”€โ”€ preset.yml         # preset display metadata
โ”œโ”€โ”€ src/               # the plugin (guard.ts, browser.ts, index.ts)
โ”œโ”€โ”€ test/              # unit + integration tests
โ”œโ”€โ”€ dist/              # compiled plugin (loaded via ./dist/index.js; built, not committed)
โ”œโ”€โ”€ .github/           # CI workflow
โ”œโ”€โ”€ package.json       # build/test scripts; playwright dependency
โ”œโ”€โ”€ SECURITY.md        # threat model and disclosure
โ”œโ”€โ”€ CONTRIBUTING.md    # contribution guide
โ”œโ”€โ”€ CHANGELOG.md       # release history
โ”œโ”€โ”€ README.zh.md       # ไธญๆ–‡ๆ–‡ๆกฃ
โ””โ”€โ”€ LICENSE            # MIT
```

## License

[MIT](LICENSE)

Install

# Copy the composition to $DSH_HOME/.agent-presets/dsh-browser-pilot/agent.cordis.yml

Profile: web

Source