DeepSeek Harness Plugin Hub

发布与管理完整 Harness Profiles,发现适合你的插件。

探索

插件目录环境预设文档中心动态

社区

发布插件联系我们报告问题

相关链接

Plugin Hub GitHubDeepSeek Harness 官方项目系统状态隐私说明
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

独立、非官方社区项目,与 DeepSeek 官方无隶属、授权或背书关系。

Cua Preview — DeepSeek Harness 插件(DSH Plugin)
DeepSeek Harness Plugin Hub
ProfilesPlugins分类动态文档登录管理 Profiles
ProfilesPlugins分类动态文档登录
← Plugins

dsh-cua-preview

Cua Preview

DSH 插件:浏览器自动化,其点击和提交操作需经过 DSH 批准,并将当前屏幕捕获为截图供用户在操作执行前审核。

插件会安装到这里;不确定时保持 web。

npx -y @deepseek-ai/dsh plugin --profile web add dsh-cua-preview@0.1.0
README兼容性版本

兼容性与来源证明

Cua Preview 以 dsh-cua-preview 发布,当前版本为 0.1.0。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

DSH 兼容范围
*
运行环境
web
发布来源
npm
Registry 更新时间
2026/9/23

版本

0.1.0stable
2026/9/23

相关插件

正在加载相关插件…

最新版
0.1.0
DSH
*
HMR
重启进程
Tree shaking
未声明可安全裁剪
解包体积
129.8 kB
文件数
13
Surface
web
许可证
MIT
发布源
npm
GitHub
★ 0
周下载
0
最近提交
2026/9/23
查看源码 ↗
README Badge

点击下方 Badge 复制 Markdown,粘贴到 README 即可。

这是你的 Plugin?认领权益 · 优先安全扫描

验证 package.json 声明的 GitHub 仓库,即可管理这个公开页面。认领后,Hub 会优先安排当前版本的安全扫描,并在通过后公开展示结果。

认领这个 Plugin →
报告问题

相关插件

继续浏览 security-access 分类下经过校验的插件。

Doctor@linxin666/dsh-doctorDSH 配置档案的事务性救援模式,配备受监督的启动器、隔离的恢复容器、确定性修复、健康监控以及本地 Web 恢复控制台DSCODE@toddzheng024/dscode-bundle完整的 DeepSeek 编码代理,支持持久化 shell、Ultra 协作和自动权限审查。Plugin Subscriptionsdsh-plugin-subscriptions将 ChatGPT (Codex)、Claude、Grok (X Premium)、GitHub Copilot 和 Google Antigravity 订阅用作 DeepSeek Harness LLM 提供商,并通过网页设置页面使用 OAuth 登录Auto Reviewdsh-auto-review针对 DeepSeek Harness 审批请求的第二模型 AI 自动审查:只读审查子代理在审批应答链上决定允许或拒绝,并采用故障关闭回退机制和完整的会话日志审计。

README

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.