dsh-web-search-ddg
aooyoo
Zero-token DuckDuckGo search provider for the DeepSeek Harness (DSH) web seam — local headless browser, no API key, no m…
PROJECT TOPICS
PROJECT README
Browser automation for the 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.
🌏 中文文档 · 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 and
SECURITY.md.
A DSH agent driving the browser end-to-end — browser_navigate → browser_type → browser_click:

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

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.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.playwright and Node built-ins,
so it loads from a relative path inside the preset without needing the harness's own
@deepseek-ai/* packages.| 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 |
Clone this repository into your DSH user preset root (the directory name becomes the preset id):
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:$env:PLAYWRIGHT_DOWNLOAD_HOST='https://cdn.npmmirror.com/binaries/playwright'
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.
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 | 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 lives in the preset row in agent.cordis.yml:
- 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.
The plugin is "arbitrary browser operation" with guard rails, not bare-metal access. Three invariants, all covered by unit tests:
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://.browser_screenshot/browser_pdf resolve the filename against the
session workspace and reject .. traversal, absolute escape, NUL bytes, and disallowed
extensions.browser_evaluate runs only in the page context and only when allowEvaluate: true.Full threat model and residual risks: SECURITY.md.
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.
├── 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
CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。