DeepSeek Harness Plugin Hub

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

探索

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

社区

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

相关链接

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

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

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

dsh-work-done-bell

Work Done Bell

当 DeepSeek Harness 会话确实完成所有工作时响起 Windows 系统提示音,并在右下角显示通知——处于空闲状态、没有正在运行的后台任务,也没有正在运行的子代理。

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

npx -y @deepseek-ai/dsh plugin --profile web add github:FunctionHookTJU/dsh-work-done-bell#788a7740ccc7610f91dfa298847cfdd13377358b
README兼容性版本

兼容性与来源证明

Work Done Bell 以 dsh-work-done-bell 发布,当前版本为 0.1.0。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

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

版本

0.1.0stable
2026/9/22

相关插件

正在加载相关插件…

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

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

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

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

认领这个 Plugin →
报告问题

相关插件

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

Acp App@deepseek-ai/dsh-acp-appdsh ACP 配置文件包:基于 dsh-base 的仅限自动化的 JSON-RPC stdio 和进程生命周期管理Ab Publishdsh-ab-publish浏览器自动化发布工具,可登录任意网站并发布内容,整合为一个可发布的插件包Ab Wechat Scrapedsh-ab-wechat-scrape--- description: "树外 wechat_scrape 工具:获取微信公众号文章,过滤推广区块,并将每篇文章保存为 Markdown 文件,供此机器的 dsh 配置文件维护者使用。" kind: "package-reference" ---Remote Web Ui@linxin666/dsh-remote-web-ui通过扫码配对访问 dsh Web GUI,共享一个官方界面:设置按钮旁的二维码可将手机和 PC 配对到同一个 Web GUI(手机采用竖屏触控适配层,PC 使用完整桌面界面),通过一次性令牌和 r

README

dsh-work-done-bell

English | 简体中文

A DeepSeek Harness plugin that rings a Windows system sound when a session has actually finished, and shows a bottom-right toast naming the session that finished. A persistent bottom-right switch turns both off, and that preference is stored in a real settings namespace, so it survives a restart.

Why "idle" is not "done"

agent/status -> idle means only that the agent's driver has nothing scheduled. Work routinely outlives it:

  • a run_in_background job keeps running and its settlement opens another turn, and
  • a delegated subagent keeps running while its parent sits idle.

Chiming on raw idle therefore rings two or three times per task. This plugin waits for quiescence: idle and no running/stopping job owned by the session and no running agent owned by it. A 90-second deadline bounds that wait, so a long build cannot swallow the notification; once the deadline has rung, the later true quiescence stays silent for the same episode.

What it sounds like

The reason comes from the durable session log (turn/end), not from a guess:

turn/end reasonSoundToast
completedAsterisk (default notification)yes
blocked (a plugin rejected the step)Asteriskyes
max-tokens (output ceiling hit)Asteriskyes
errorHand (critical stop)yes
aborted — including your own Esc/Stopsilentno
interrupted (crash-orphaned turn)silentno

Simultaneous completions within 2.5 s collapse into one sound, so five sessions finishing together do not stack five players.

Install

Clone the repository, then install it from the directory you cloned into:

git clone https://github.com/FunctionHookTJU/dsh-work-done-bell
dsh plugin --profile web add file:/absolute/path/to/dsh-work-done-bell

then add the package name to the profile's bundle list, in <DSH_HOME>/profiles/web/package.json:

{
  "dsh": {
    "profile": {
      "bundles": ["@deepseek-ai/dsh-base", "...", "dsh-work-done-bell"]
    }
  }
}

(dsh plugin add reconciles that list itself when the installed package declares dsh.bundle. Restart DSH afterwards; nothing else in the composition needs editing.)

Use file:, not link:. The plugin resolves @deepseek-ai/schemastery by walking up from its own directory into the profile's node_modules. A link: install keeps the real path outside the profile and the import fails at load.

Uninstall

dsh plugin --profile web remove dsh-work-done-bell

Remove it from dsh.profile.bundles (which dsh plugin remove also reconciles), then restart. The work-done-bell namespace in settings.yaml is inert once the plugin is gone and can be deleted by hand.

The switch

Bottom-right, always visible: 完成提示已开 / 完成提示已关. It writes work-done-bell.enabled through the settings service, and both halves read it — the host half stops the sound, the browser half stops the toast. The state lives in <DSH_HOME>/settings.yaml, so it survives a restart.

Introspection

There is no model-facing tool, on purpose: @deepseek-ai/dsh-tools is not present in the profile, and a plugin may only import what the profile already carries (ESM resolution ignores NODE_PATH). The state route carries the same information instead:

curl "http://127.0.0.1:3080/dsh-work-done-bell/state?verbose=1"

That returns tracked statuses, the last turn/end reason per session, open quiescence episodes with their deadlines, the last sound exit code, and any error the plugin swallowed. Without ?verbose=1 it returns only what the browser half needs.

Requirements and known limits

  • Windows only for the sound: it plays through [System.Media.SystemSounds], executed via the composed shell service. On other platforms the plugin loads and toasts, but stays silent. Porting it means changing the command in play() to afplay / paplay.
  • The sound command carries a resolved sandbox policy. A confining shell service refuses a command that arrives without one, and the deployment default may be a mode the host cannot enforce at all — on the machine this was built on, workspace-write fails because the Windows ACL runner wants a temp root outside the workspace while the workspace is the user profile, so nothing runs confined and an unpolicied command is simply refused. The policy is therefore resolved per chime for the session being announced (sandboxPolicy.resolve({ session })), which is that session's own authority, never a widening of it. On such a host a session confined to workspace-write stays silent; ?verbose=1 reports the reason in lastError and the resolved mode in lastPolicy.
  • The toast requires an open page; the sound does not.
  • The browser half polls the host every second over /dsh-work-done-bell/state. There is no push channel: the sanctioned direction of package communication is browser -> host.
  • Toasts label the session by a short id, not its title.

Development

Four suites, all runnable with no harness running:

npm test                           # all four
node test/state-machine.test.mjs   # the decision table, on a manual clock
node test/integration.test.mjs     # the plugin inside a REAL cordis app
node test/client-bundle.test.mjs   # the browser bundle's contract
node test/docs-parity.test.mjs     # the two readmes' shared skeleton

integration.test.mjs is the one that matters most: it boots a real @deepseek-ai/cordis application with stub services and asserts that apply runs, that ctx.inject fires, and that both HTTP routes register. An earlier version of this plugin read ctx.get('webServer') once at apply time and called jobs.onJobsChanged unguarded; it looked healthy while registering nothing in production, because a host-composition row mounts during boot, before its services exist.

The suites need @deepseek-ai/cordis, @deepseek-ai/cordis-plugin-timer, @deepseek-ai/schemastery and @deepseek-ai/cosmokit resolvable from the repository. A checkout links them from the harness installation; node_modules is gitignored, so these links stay local:

$repo  = (Get-Location).Path   # this checkout
$dsh   = "$env:APPDATA\npm\node_modules\@deepseek-ai\dsh\node_modules\@deepseek-ai"
$web   = "$env:USERPROFILE\.dsh\profiles\web\node_modules\@deepseek-ai"
New-Item -ItemType Directory -Force -Path "$repo\node_modules\@deepseek-ai" | Out-Null
foreach ($p in 'cordis','cordis-plugin-timer') {
  New-Item -ItemType Junction -Path "$repo\node_modules\@deepseek-ai\$p" -Target "$dsh\$p"
}
foreach ($p in 'schemastery','cosmokit') {
  New-Item -ItemType Junction -Path "$repo\node_modules\@deepseek-ai\$p" -Target "$web\$p"
}

docs-parity.test.mjs guards the two readmes against drift: the same heading skeleton, the same code blocks, the same tables, the same inline technical terms. It cannot judge the prose, but it fails the moment one language grows a section the other lacks.

Layout

lib/index.js      host half  — quiescence state machine, sound, HTTP route
client/client.js  client half — shell.overlay toast stack and switch
cordis.patch.yml  the composition row this package contributes
test/             decision table, real-cordis integration, client + readme contracts

License

MIT