DSH Plugins Marketplace

DSH Plugins

Plugins

/

Development & Infrastructure

/

dsh-cua-preview

f

dsh-cua-preview

Manifest valid

DSH plugin: browser automation whose click and submit actions are gated by a DSH approval, with the current screen captured as a screenshot the user reviews before the action runs.

UI (client)hasBundlePatch

dsh-cua-preview

English | 中文

A DeepSeek Harness plugin that drives a browser, with every navigating or acting call gated by a DSH approval — and with the current screen captured as a screenshot the user reviews before the action runs.

The approval architecture follows ZCode's cua-permission-broker as a design borrowing; no ZCode source is copied.

What it does

ToolApprovalReturns
browser_navigateyesthe loaded page, after navigation
browser_act (click / fill / submit)yesthe page after the action
browser_snapshotnothe current URL, title and visible text
browser_screenshotnothe current screen as an image

The read-only pair never raises an approval, because neither can change the page. The gated pair asks first, in one line of the UI's own language, and does nothing at all unless the answer is "allow once".

Install

Requirements: Node ≥ 22.12 (this is what puppeteer-core requires) and a Chrome or Chromium executable. Nothing is downloaded at install time — the plugin drives the Chrome you already have, and reports an actionable error instead of silently fetching one.

A DSH plugin is installed into a profile with dsh plugin, which forwards its arguments to the package manager in that profile's directory:

# By name
dsh plugin --profile demo add dsh-cua-preview

# From a checkout
dsh plugin --profile demo add ./dsh-cua-preview

dsh --profile demo --dump-config   # the layer appears as "# == dsh-cua-preview"
dsh --profile demo                 # boot

The package is a DSH bundle — it ships a configuration layer, and a profile is what boots it. To attach it to an existing profile without a reinstall, use an overlay instead, which is also what the tests do:

- insert:
    - id: cua-preview
      name: 'dsh-cua-preview'
      config:
        artifactsDir: '/tmp/cua-artifacts'   # optional
        headless: true                       # optional, default true
        chromePath: '/usr/bin/google-chrome-stable'  # optional, auto-detected

Configuration

KeyDefaultMeaning
artifactsDir$DSH_HOME/cua-preview/artifactswhere screenshot evidence PNGs are written
headlesstruerun Chrome headless
chromePathauto-detectedexplicit Chrome/Chromium executable

Chrome is looked up through $DSH_CUA_CHROME_PATH and the usual Linux install paths (/usr/bin/google-chrome-stable, /usr/bin/google-chrome, /usr/bin/chromium, /usr/bin/chromium-browser, /snap/bin/chromium), and is launched with the standard container-safe flags.

The browser library choice: Puppeteer

The task allowed Puppeteer or Playwright. Puppeteer was chosen, and specifically puppeteer-core:

  • puppeteer-core downloads nothing — no ~150 MB browser fetch at install time, and no version guess about which Chromium to pair with which library release.
  • It drives the Chrome that is already on the machine, so what the user reviews is the same browser they could open themselves.
  • The plugin's whole dependency on it is one module, src/browser.js; swapping to another library would change that file and nothing else.

The screenshot model, in one paragraph

The approval happens before the action, so two frames exist and each is named for what it is. The post-action frame is what the model receives as its result image, because a model that reads a pre-action frame as "the result" concludes the action failed. The approval-time frame is what the user is shown while deciding; it is carried on a log-only session event of the plugin's own, read by the Client half, and painted in the same row as the result — so during a pending approval the picture is already on screen. result.meta keeps the audit pointer without being painted. On a refusal there is no post-action state, so the one image returned is the approval-time frame. A screen that is genuinely blank (an unloaded, empty tab) emits no frame at all rather than a useless white rectangle.

docs/design.md explains the mechanisms, and why the frame cannot travel inside the approval request.

What the model is told when the user says no

A refusal is a successful tool result, not an error — an error reads as "the call failed, try again", and an error is exactly what once caused a model to retry an action the user had just rejected. The notice leads with the shipped gating path's own sentence, quoted verbatim in both languages, and adds what that sentence does not say: that this is a human decision rather than a failure, and that the expected next move is to stop and ask.

browser_act 未执行:用户在审批中拒绝了这次操作。
the user rejected tool "browser_act" —— 这是人的决定,不是调用失败、页面问题,也不是本插件故障。
操作没有执行,页面保持原样。不要重试这个动作或等价动作;请停下来询问用户要改什么、或者下一步做什么。

The three non-granting outcomes are worded differently, so the model can tell a human "no" from an absent channel: rejected and cancelled are described as the user's decision, while unavailable states explicitly that it was not. The same rule is in the gated tools' descriptions, so it reaches the model before it acts rather than only afterwards.

Repeat prompting is not suppressed: the plugin does not police the model's retries, and a user who changes their mind can still approve a later attempt. Suppressing an identical repeat would end the popup loop mechanically, but it can also block a user who has since said "go ahead", and a tool execution carries no turn identity with which to scope the suppression to one model turn.

Tests

From a source checkout (the test entries are development-only and are not part of the published package, so they are absent after npm install dsh-cua-preview):

npm install
npm test

Three entries, aimed at three different layers:

EntryLayerNeedsChecks
npm run test:clientthe Client half, in isolationNode only79
npm run test:acceptancethe Host half, against the real DSH servicesChrome107
npm run test:real-loadboth halves, inside a real dsh processa dsh CLI + Chrome18

That is 204 checks, 0 failures — all three entries need npm install first. The last entry boots the shipped dsh binary with the plugin patched in on an OS-assigned free port — so it cannot collide with any profile you have running — and runs a probe plugin inside that process which reads the live registries. It reports clearly and exits non-zero if no dsh CLI is available.

CI runs the Client-bundle verifier and the packaging check on every push, because both are reproducible without a browser. The browser suites are not part of that gate — they need a Chrome executable and, for the last entry, a dsh CLI — so they are exposed as a manually triggered job instead.

Local test page

examples/test-page/ is a small page with a field, a button and a form, used by the acceptance checks and handy for trying the plugin by hand:

node examples/test-page/serve.mjs --port 3097 --host 127.0.0.1

Documentation

DocumentContents
docs/design.mdhow it works and why: the two frames, the image channels, the hidden carrier node, the slots this plugin refuses to touch, the locale and refusal rules
CHANGELOG.mdwhat changed

License

MIT. This is an unofficial community work, not affiliated with, authorized, sponsored or endorsed by Z.AI Co., Ltd or DeepSeek. "ZCode" and "DeepSeek Harness" are the trademarks of their respective owners and are used here only to describe where a design came from and what this plugin runs on.

Comments

Loading…

From the same category

awesome-dsh-plugin

by awesome-dsh-plugin

A curated list of plugins for DeepSeek Harness (dsh) · DeepSeek Harness 插件精选列表

Development & Infrastructure

★ 18.3k

CC0-1.0

Python

Oct 10, 2026

Index only — not installable

by 0xsline

DeepSeek Harness (DSH) ecosystem: curated plugins, tools, and infrastructure from dsh-external/hub and the public dsh-plugin topic.

Development & Infrastructure

★ 1.2k

CC0-1.0

Python

Oct 10, 2026

Index only — not installable

by pax-beehive

Open-source CLI, schemas, resolver, and DSH agent tools for DSH Plugin Hub

Development & Infrastructure

★ 450

MIT

TypeScript

Oct 6, 2026

Index only — not installable

by xiajiajun516

DeepSeek Harness (DSH) backup & restore plugin — export, import, migrate and sync your complete DSH configuration, plugins, MCP servers, skills and workspace. One-click migration to another machine.

Development & InfrastructureManifest valid

★ 176

MIT

TypeScript

Oct 8, 2026

dsh plugin --profile web add dsh-config-manager

by yjh051108

推荐组件(非必须):DeepSeek Harness 运行时注入器;已随 dsh-routing-suite 单仓库化保留,本仓库继续维护/发布。

Development & InfrastructureManifest valid

★ 164

TypeScript

Sep 18, 2026

dsh plugin --profile web add @dsh-external/dsh-super-injector

by jigjoy-ai

A CLI that turns a goal into a pull request - and a sandbox for testing concurrent AI coding agents on the Mozaik runtime.

Development & Infrastructure

★ 124

MIT

TypeScript

Oct 2, 2026

Index only — not installable