dsh-testhud

DSH PLUGIN会话与消息

仓库 yijiezhong/dsh-testhud · npm dsh-testhud

会话与消息 未标注验证等级 安全审查:未标注 可信度:未标注 可安装插件
安装这个插件

为 DeepSeek Harness 中的自动化测试提供置顶点击穿透进度 HUD,实时显示测试步骤与结果,并提示何时可安全收回鼠标键盘控制权。

一句话选型结论

按资料字段整理

dsh-testhud 是会话与消息类的 DSH 可安装插件,未做沙盒验证,暂无安全审查结论,列出 5 项功能,有可直接复制的安装命令。验证通过不等于安全:插件会读写文件、执行命令或联网,装前先到仓库确认它做了什么;涉及密钥或系统权限的,建议先在隔离环境试装。

分类会话与消息 收录类型可安装插件 验证等级未标注验证等级 安全审查未标注
验证等级 UNKNOWN 未标注验证等级
GitHub 星标 0 复刻 0 · 未关闭 issue 0
最近更新 2026-10-09 创建于 2026-09-16
README 20.9 KB 正文体量,越大说明说明书写得越细

安装

可安装插件
在 DSH 里执行,装完用 dsh plugin list 确认已挂上;标了 L4 / L5 的命令已在沙盒里真实跑通
dsh plugin --profile web add dsh-testhud
  1. 1
    确认版本与运行环境

    仓库没有标注兼容版本与 Node.js 要求,先确认你的 DSH 版本能装,再继续。

  2. 2
    执行安装命令

    在 DSH 里执行上面的命令;多包仓库要注意区分具体子包名,别装错包。

  3. 3
    确认已挂载

    用 dsh plugin list 查看列表里是否出现这个插件,出现即挂载成功。

  4. 4
    试跑并检查权限

    加载后跑一个最小用例,确认它能正常工作;同时看它申请了哪些文件、命令或网络权限。

兼容 DSH 版本未标注版本不匹配时安装会报错
Node.js 要求未标注来自仓库 package.json 的 engines 字段
前置依赖无需要同时安装的同级依赖
npm 包名dsh-testhud可用 npm view 查看包信息

能做什么

5 项功能
字段来自项目仓库与公开索引,中文说明由本站标注

dsh-testhud:DeepSeek Harness 的自动化测试悬浮进度面板

  • 置顶点击穿透进度面板
  • 逐步显示预期与实际结果
  • 颜色提示可否接管键鼠
  • test_hud 工具驱动面板
  • 可拖拽、折叠与展开

上游标签

cordis-plugindeepseek-harnessdsh-pluginmacosswifttesting

验证等级与安全审查

未标注验证等级
自动化流程结论,不是人工审核
验证等级未标注验证等级上游未给出验证结论,安装前请自行确认
安全审查未标注静态分析结论,未标注不代表已通过审查
仓库健康度未标注按仓库活跃度与最近更新时间给出
可信度未标注综合仓库活跃度与验证结果

选择建议

装之前先看这几条
按条目字段给出的判断,不替你决定用不用

值得选的地方

  • 有可直接复制的安装命令,不用自己翻文档找入口。
  • 列出了 5 项功能,能直接看出它解决什么问题。

先想清楚的地方

  • 安全审查还没结论,装之前先看仓库改了什么、要什么权限。
  • 没有声明 Node.js 版本要求,版本不匹配可能装不上。
  • 验证通过不等于安全:插件会读写文件、执行命令或联网,装前先到仓库确认它做了什么。

更适合

  • 需要在会话与消息场景里给 DSH 补能力的人。
  • 能接受在本地装依赖、愿意自己确认权限的人。

不太适合

  • 只使用 DSH 官方内置能力、不接受第三方插件的人。

同类对比

6 个同类
同分类里挑最接近的几条,字段以各自详情页为准
插件验证等级安全审查星标兼容版本安装命令
dsh-testhud当前 未做沙盒验证 未标注 0 未标注 有
dsh-desktop L3 · 安装规范通过 低风险 3.0 万 未标注 无
openpets L4 · 沙盒安装通过 低风险 1,274 未标注 有
deeptide L4 · 沙盒安装通过 低风险 1,104 0.1.1-rc.2 有
jingyun-dsh L3 · 安装规范通过 低风险 1,004 未标注 有
study-mate 未做沙盒验证 未标注 856 未标注 无

仓库档案

会话与消息
字段来自项目仓库与公开索引,中文说明由本站标注
作者 / 维护方yijiezhong仓库 dsh-testhud · 默认分支 master
分类会话与消息client
收录类型可安装插件声明了 dsh.bundle、可用 dsh plugin add 安装的条目
开发语言Swift仓库主语言
许可证MIT商用或二次分发前请确认条款原文
星标 / 复刻 / issue0 / 0 / 0收录时的数值,非实时
创建 / 更新2026-09-16 · 2026-10-09最后推送 2026-10-09
本站收录2026-10-09首次进入本站目录的时间

README 全文

20.9 KB
作者原文,中文版优先;只做安全转义,不改内容

dsh-testhud


An always-on-top, click-through progress panel for automated tests in DeepSeek Harness (dsh), drawn over the app under test — plus the test_hud tool that drives it from any session.

Why it exists

When an agent drives a GUI, compares screenshots or renders a batch for a few minutes, the human just sits there: they cannot tell which step it is on, what the step expects, whether it already failed, or — the question that actually matters — whether it is safe to touch the mouse and keyboard again.

This panel answers exactly that, on screen, without stealing focus:

  • What is being tested — title, target, start time and elapsed seconds.
  • Every step, with expectation and actual result — one line each, ✓ / ✗ / ⏳ / •.
  • A permanent line about control, at the very top — the panel's own strings are Chinese; this one reads 正在进行:先别动鼠标键盘,以免打断测试 while running and ✓ 已结束,可以收回鼠标键盘的控制权了 when done. It is the heaviest text on the panel and the only line carrying a background: white on swatch red #FF3B30 while it is unsafe to touch anything, black on swatch green #34C759 once you may take over. The text colour is picked by state, not by contrast — see the swatch section below.
  • It never gets in the way: click-through (the mouse passes straight through), always on top, not in the Dock and not in ⌘Tab, and it picks the emptiest corner of the screen so it covers as little of the app under test as possible.
  • Move it by hand: grab the top colour band and drag. The band is one of only two places that take the mouse (it is the drag handle); everything else stays click-through, and the content area takes the mouse only when content overflows — see "Size and overflow". The cursor turns into an open hand over either place and a closed hand while you hold the button, then back on release — the cursor shape itself is the "you can drag here" hint.
  • Three traffic lights at the band's left end, the macOS three: red closes the panel, yellow collapses it down to just the band (click again to restore), green expands it to the usable-area ceiling — full height and full width (click again to go back to fitting the content; height alone often has no room left, since with enough content the natural height already equals the ceiling). Their colours are pinned to the swatch — red #FF3B30, yellow #FFCC00, green #34C759 — each with a 1.0 pt white stroke: the red dot and the red band are now the same swatch colour, so the stroke is the dot's only remaining cue.

Install

dsh plugin --profile  add github:yijiezhong/dsh-testhud   # straight from GitHub
dsh plugin --profile  add link:/path/to/dsh-testhud       # from a local checkout
dsh plugin --profile  add dsh-testhud                     # from npm (published as 0.1.1)

The Desktop app installs the same way (plugin settings); its plugin manager mounts a new bundle live — the row is composed immediately and the host is not restarted. A CLI-launched profile composes its bundle list at boot, so restart once unless your profile reloads patches live.

The package must actually be listed in the profile's dsh.profile.bundles (dsh plugin add does that for you); check that the row really entered the composition with dsh --profile --dump-config — it prints a # == dsh-testhud layer marker. Every session in that profile then has the test_hud tool and the short prompt convention about reporting long tests.

@deepseek-ai/dsh-tools is declared as a peer dependency: dsh resolves it to the running installation's copy (so the plugin always uses the host's own defineTool) and refuses the whole bundle when the running version falls outside the declared range, instead of half-loading it. The copy in node_modules is only a devDependency, for tests that run outside the host.

Uninstall:

dsh plugin --profile web remove dsh-testhud

The agent tool

action What it does Parameters
start Opens a run and launches the panel title (required), target, anchor
step Reports one check name (required), expect, actual, state = ok/fail/run/info
note Adds one line at the bottom text
done Writes the conclusion and ends the run failed (boolean), conclusion
stop Closes the panel immediately —

The panel sizes itself to its content in both directions (see "Size and overflow"), scrolls only the step list while the header stays fixed, and disappears 12 seconds after done — long enough to read the verdict.

The rule

If a verification is running, the panel must be up. Never "just run the commands" without it: during a series of runs, start again after a done and before the next action. Whoever is waiting must be able to see what is being tested and whether it is safe to take back the keyboard.

Clean up afterwards too: done at the end, then quit the app you launched for the test (gracefully, not kill -9) and bring the browser / DSH window back to the front. Do not leave the app under test sitting on screen.

The CLI

Same logic, same progress file, for shell scripts and CI:

testhud start "Movable toolbar layout" "Movable main window" [anchor]
testhud step  "toolbar is centred" "centre == window centre" "962pt, centred" ok
testhud note  "left to the user to decide"
testhud done  ok "3 of 3 checks passed"
testhud stop
testhud status

Configuration

Optional row config in your profile's cordis.patch.yml overrides the plugin row:

- id: testhud
config:
announceToAgent: true     # inject the short "report long tests on screen" convention into every session
defaultAnchor: auto       # auto | center | left | right
topInset: 155             # how far the top anchors drop below the screen top, in points

Where the panel goes is decided in this order:

  1. Do not cover the thing under test. The panel scores three positions against the frontmost app's windows and takes the one that overlaps least. This outranks everything below.
  2. Centre of the screen, when that blocks nothing.
  3. Otherwise the side — left before right.

Vertically it always sits high: the top edge sits topInset points below the screen top (155 by default), the bottom edge stops above the status bar / Dock (Look.bottomInset, 44 pt). Horizontally it stays off the edges (Look.sideInset, 28 pt) so it cannot sit on a sidebar or a scrollbar. Anchors are auto | center | left | right; the old top-left / top-right names still map to left / right.

topInset exists because the panel usually floats over a browser: the top ~150 pt of the screen are the tab strip, the address bar and the bookmarks bar, and a panel there would cover them. The default (155) starts the panel just below that chrome — level with the page's own header. 0 degrades to "clear the menu bar, then keep a 14 pt screen margin". The value is measured from the screen top (positioning uses the full frame, not visibleFrame), so what you pass is what you get. DSH_TESTHUD_TOP_INSET overrides it for the CLI.

Size and overflow

Both dimensions follow the content (HUD.layout()):

  • Width is the widest line at its natural (unwrapped) width plus the left and right insets (Look.inset, 16 pt), clamped to a floor of 460 pt (Look.minWidth) and a ceiling of the screen's usable width minus 28 pt on each side (Look.sideInset).
  • Height follows the content, and is exactly the content height while it fits; the ceiling is the span from the panel's top edge (topInset below the screen top, 155 by default) down to the bottom of the usable area minus 44 pt (Look.bottomInset) — no longer 62% of the screen height. Yellow collapses the panel to just the band; green expands it to that ceiling and to the full usable width.

The height has a ceiling, so with enough content the upper part is pushed outside the visible area. The panel's content area then carries a transparent drag hit layer (the ScrollHandle window plus its ScrollGrip view): press and pull downwards to bring the upper content back (natural scroll direction), and on release it eases back to the bottom over 0.28 s ease-out — "the last line returns to the bottom of the window". The hit layer only exists when content is actually cut off (its height is 0 otherwise), so a panel whose content fits stays fully click-through. The cursor shows an open hand over it and a closed hand while held, reverting on release. Observe it at ~/.dsh/dsh-testhud/scroll.json (scrollY / maxY / atBottom / panning / bouncing / cursor — the last one because screenshots do not contain the mouse pointer, so the cursor can only be verified this way).

Colours come from the Apple swatch only

Every colour on the panel must exist in the Apple swatch — the 22 colours on page 1 of the swatch (Apple色板/1Apple配色色卡.key, on this machine under $HOME/PARA/8.Code/AIDoc/设计规范/): 9 neutrals + 3 blues + 10 functional. The single source of truth in code is ApplePalette in hud/testhud.swift, all built in sRGB (calibrated* constructors shift the values).

Chameleon V2 (2026-10-09): the panel's ground is fully transparent — no fill, no backdrop snapshot; only text and a hairline border remain. Whatever is underneath stays visible, and the panel's own text is kept legible on any backdrop by three things (stroke + shadow + colour):

Part Light appearance Dark appearance
Panel ground translucent (alphaFloor 0.50) same
Border (1.0 pt, Look.panelBorderWidth) black #000000 white #FFFFFF
Body (title / step name / conclusion / expect / actual — one colour) picked adaptively, see below same
Text shadow off by default (textShadowBlur = 0) same
~~Text stroke~~ off by default (strokeWidthPercent = 0) same
Step marks ✓ #34C759 / ✗ #FF3B30 / ⏳ #FF9500 / • same as body same

The body colour is picked adaptively (Theme.pickTextColor, 2026-10-09) — the backdrop is classified into four cases, and within a case only one pairwise contrast comparison is made:

Backdrop Picked
itself coloured (site blue, warm orange, deep green…) whichever of black/white contrasts more (a coloured candidate tends to blur into a same-hue backdrop)
neutral but mid-luminance (pure mid grey) black/white (blue only reaches 2.5:1 on mid grey)
neutral, bright the better-contrasting of Apple blue #0071E3 and indigo #5856D6
neutral, dark the better-contrasting of bright blue #2997FF and mint #00C7BE

Across eight measured backdrops (white-with-black-text / black-with-white-text / pure white / pure black / mid grey / site blue / warm orange / deep green) it picks indigo / mint / indigo / mint / black / black / black / white, each confirmed legible by eye. Hierarchy no longer rides on grey levels: it is all font weight (one size, four weights).

The shadow takes "the backdrop's pole" (white in the light scheme, black in the dark one): it blends into the backdrop, and its job is to push the backdrop's own strokes out from under the panel's letters. The stroke is off by default (strokeWidthPercent = 0) — three variants were compared side by side: a stroke makes 18 pt glyphs look fat and grubby, whereas a pure shadow stays clean and reads just as well. The capability is kept (set a negative value to enable it).

The band ignores the light/dark split and follows the state: running = red #FF3B30 + white text, done = green #34C759 + black text; the band's opacity is 0.75. The three traffic lights are swatch values too (red #FF3B30, yellow #FFCC00, green #34C759) with a 1.0 pt white stroke. The band is the only opaque piece left.

The step marks are ✓ / ✗ / ⏳ / • and not ✅ / ❌: colour emoji ignore foregroundColor and paint colours of their own, outside the swatch, so the glyph had to change. By the same token, emoji the caller (an agent) writes into a step name, expect or actual are not governed by ApplePalette.

Only one thing is still computed: which appearance to use. It reads the median luminance of the sampled rectangle (not the mean — dense text lifts the mean, which made a dark backdrop with white text look "light" and produced black panel text). The threshold 0.60 is empirically calibrated: what ScreenCaptureKit returns has been tone-mapped (measured: pure white 1.000 comes back as 0.886, the dark grey #1D1D1F at 0.106 comes back as 0.373), so comparing against the textbook 0.5 inverts the decision. The backdrop is sampled every 0.7 s — the rectangle the panel is about to cover, and only that rectangle, plus immediately whenever the frontmost app changes or the panel resizes or changes content.

Two earlier palettes remain in the source unused (banner() / tinted() / textColor(), plus the "translucent ground + backdrop snapshot" route); ask the user before reviving them.

Visual design

The layout follows CRAP deliberately; keep these rules when you edit it:

  • Contrast — colour carries two jobs: status (the band and the step marks) and the body colour (swatch blue, which is what separates the panel's text from a black/white backdrop — see the table above). Hierarchy rides on four font weights, never on a second size — every line is Look.base (18 pt).
  • Repetition — one left edge for all content (Look.inset, 16 pt), and only three spacing values: 14 pt between groups, 10 pt between steps, 2–4 pt inside a step.
  • Alignment — the banner spans the full panel width and its text indents back to the content edge; a step's expect/actual lines use a real headIndent, not spaces (spaces never line up in a proportional font).
  • Proximity — header (title / target / timer), steps, and the conclusion are three groups: tight inside, loose between.

Every line is the same size — Look.base (18 pt) in hud/testhud.swift — and the hierarchy comes from weight alone (heavy for the control line, bold for the title and status, semibold for steps, regular for the expect/actual detail). The browser's DSH body text is --dsh-content-font-size (14 px by default, 12–17 settable); the panel sits above it because light text on a translucent dark panel reads smaller than black text on a page. Change base and the whole panel resizes with it. The other layout numbers: 16 pt padding (Look.inset), 14 pt corner radius (Look.cornerRadius), 1.0 pt border.

Requirements

  • A dsh host that provides @deepseek-ai/dsh-tools — declared as a peer (~0.2.0-rc.2 at the time of writing), so defineTool is the host's own copy and a runtime outside the declared range is refused rather than half-loaded. The package has no other runtime dependencies.
  • macOS 14+ for the panel itself (AppKit + ScreenCaptureKit's SCShareableContent / SCScreenshotManager). The progress file and the tool work anywhere; on older systems the panel cannot be drawn and the tool reports that.
  • Xcode Command Line Tools are not required: the package ships a universal prebuilt binary (hud/testhud.macos-universal, arm64 + x86_64), so it works as installed. Only when that prebuilt is missing or cannot be copied does it fall back to compiling hud/testhud.swift with swiftc into ~/.dsh/dsh-testhud/bin/testhud (~3–4 s here) — that path needs xcode-select --install.

Development

Inspect, don't guess

bin/testhud-inspect.py is the observation tool for the panel's pixels. It reads the geometry the panel itself exports on every layout (~/.dsh/dsh-testhud/panel-frame.json), crops exactly that rectangle, and reports the panel's internal texture plus every OCR line inside it that does not belong to the panel's own content.

Use it instead of reasoning about panel coordinates from a screenshot: the panel's position and size are dynamic, and inferring them from OCR output mistakes content from outside the panel for text bleeding through. Contrast is computed from colour clusters rather than extreme pixels, and anything measuring under 1.5:1 is reported as an out-of-frame artifact rather than a contrast figure.

When several rounds in a row report "nothing changed", suspect the instrument before changing the subject again. A pixel-identical result across rounds, or several genuinely different implementations all "failing" the same way, are signs that the instrument is broken — not the thing being measured.

Test on a backdrop that contains text

Sample a backdrop with real text under it — a source file, a terminal full of output, a chat transcript. A solid area (blank page, empty terminal) cannot show the failure this panel exists to avoid: its own text fighting the text underneath, same size and similar colour, two layers of type in one place. A clean backdrop proves nothing about it.

# a throwaway profile, so your real one is untouched
dsh --profile hudtest --from-default-profile headless --dump-config > /dev/null
dsh plugin --profile hudtest add link:"$PWD"
dsh --profile hudtest --dump-config | grep -A2 testhud        # the row is composed
dsh --profile hudtest "call test_hud: start, step, done"      # a real session must see and call the tool
rm -rf ~/.dsh/profiles/hudtest                                # clean up

node_modules/@deepseek-ai/dsh-tools is only needed for standalone node lib/index.js smoke tests; inside a dsh process the host resolves it. It is not part of the published package.

How it works

lib/index.js      Cordis host plugin: registers the test_hud tool + a system-prompt section
lib/hud.js        progress file (~/.dsh/test-progress.json) and the panel process (build / start / stop)
hud/testhud.swift the panel itself: borderless NSPanel at .screenSaver level, ignoresMouseEvents, polls the file every 0.4s
(plus two small transparent helper windows that cover one region each — the band handle and the
content drag hit layer: the panel is click-through as a whole, and ignoresMouseEvents is
per-window, so one window cannot be "click-through here, solid there")
bin/testhud.js    CLI over the same core

The progress file schema is deliberately plain JSON, so anything can write it:

{ "title": "…", "target": "…", "status": "running|done|failed", "startedAt": 1789518613.07,
"steps": [{ "name": "…", "expect": "…", "actual": "…", "state": "ok|fail|run|info" }], "note": "…" }

Limitations

  • One panel per machine. The progress file is a single well-known path, so two concurrent test runs share one panel — the last writer wins.
  • The panel is click-through by design, with two exceptions: the top colour band (the drag handle — without it there would be no way to move the panel by hand) and, while content overflows, the content drag hit layer. A mouse landing on either grips the panel instead of the app underneath; stop / done make it go away.
  • The band's left 78 points are reserved for the three dots; the band text starts after them, so a long status line cannot run into the dots.
  • Dragging leaves the panel wherever you put it — layout() only keeps the top edge fixed when the height changes, it never snaps back to a candidate position — until the panel process restarts. The drag is clamped to the visible area of the screen the mouse is on: otherwise the panel can be dropped into the dead space between two displays, where nothing is visible and it can never be clicked again.
  • On a screen already covered by full-screen windows, every corner overlaps something; auto then falls back to the top-left corner. Pass an explicit anchor to keep the panel away from the area you are testing.
  • In the worst case the panel's text competes with the backdrop's text: over dense text (a terminal full of output, say) the two layers sit on top of each other. The answer is a translucent ground plus an adaptive body colour: the ground pushes the backdrop back one layer, and the body colour is picked for the backdrop (see "Colours"). To go fully transparent instead (text has to fend for itself): set Look.transparentPanel to true — only in that mode is the text shadow (textShadowBlur) worth turning on.
  • The panel's own strings are bilingual (the control band, 测试对象: / Target:, 期待: / Expect:, 实际: / Actual:, 结论: / Conclusion:): English when the system's preferred language starts with en, otherwise Chinese; DSH_TESTHUD_LANG=en forces it (used for screenshots and tests). A run's title and step text are whatever the caller wrote.

License

MIT

常见问题

7 问
答案由本站依据条目字段整理,不引用上游原文
dsh-testhud 怎么安装?

在 DSH 里执行 `dsh plugin --profile web add dsh-testhud` 即可。对应的 npm 包名是 `dsh-testhud`。

dsh-testhud 的验证等级是什么意思?

未标注验证等级。上游未给出验证结论,安装前请自行确认

dsh-testhud 安全吗?

未标注。

dsh-testhud 装之前要先确认什么?

先看它会读写哪些文件、执行哪些命令、连接哪些网络地址;验证等级只说明装得上、跑得起来,不等于安全。涉及密钥或系统权限的,建议先在隔离环境试装。

dsh-testhud 用的是什么许可证?

上游标注为 MIT。商用或二次分发前请到仓库确认许可证原文。

dsh-testhud 有哪些功能?

置顶点击穿透进度面板、逐步显示预期与实际结果、颜色提示可否接管键鼠、test_hud 工具驱动面板、可拖拽、折叠与展开。

这条记录的数据可靠吗?

本站按仓库名去重后合并整理,字段以作者仓库与 npm 元数据为准;安装命令、仓库地址与 README 保持原文,带 L4 / L5 标记的安装命令已在隔离沙盒里真实跑通。

会话与消息
按星标排序,可作替代方案

dsh-desktop

dsh-desktop

为 DeepSeek Harness (DSH) 插件生态打造的现代化桌面端解决方案。万物皆「插件」,桌面本身也是「插件」。

L3 · 安装规范通过 3.0 万 星

openpets

openpets

L4 · 沙盒安装通过 1,274 星

deeptide

deeptide

L4 · 沙盒安装通过 1,104 星

jingyun-dsh

jingyun-dsh

井云 DSH 客户端插件,为 DeepSeek Harness 注入会员登录、订阅支付、算力管控与应用市场,让智能体和技能快速变成可交易商品

L3 · 安装规范通过 1,004 星

study-mate

study-mate

StudyMate 是 DSH 的「学习模式」预设与技能包,为数学、计算机科目定制学习路线、讲解课件与练习评估,跨科目共享记忆。

未标注验证等级 856 星

yijiezhong 的其它插件

1 个

插件的元信息来自作者仓库;分类、验证等级与安全结论的中文说明为中文整理,最近核验 —。