DeepSeek Harness Plugin Hub

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

探索

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

社区

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

相关链接

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

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

Plugin Mac Notify — DeepSeek Harness 插件(DSH Plugin)
← Plugins
P

dsh-plugin-mac-notify

Plugin Mac Notify

当 DSH 会话结束或需要您处理时,macOS 通知中心会发出提醒——通知横幅会显示最后一条回复、播放系统提醒声音,点击后可返回 DSH 页面

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

npx -y @deepseek-ai/dsh plugin --profile web add github:AK-blank/dsh-plugin-mac-notify#a9ef9439a1e8f7957a402c742bc639919ab1d1c8
README兼容性版本

兼容性与来源证明

Plugin Mac Notify 以 dsh-plugin-mac-notify 发布,当前版本为 1.0.0。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

DSH 兼容范围
*
运行环境
any
发布来源
github
Registry 更新时间
2026/10/3

版本

1.0.0stable
2026/10/3

相关插件

正在加载相关插件…

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

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

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

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

认领这个 Plugin →
报告问题
DeepSeek Harness Plugin Hub
ProfilesPlugins分类动态文档登录管理 Profiles
ProfilesPlugins分类动态文档登录

相关插件

继续浏览 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-plugin-mac-notify

macOS Notification Center alerts for DSH (DeepSeek Harness) sessions — so an unattended run can call you back to the machine.

┌──────────────────────────────────────────────┐
│ DSH · 任务完成                                │
│ browser_dsh                                  │
│ 插件已经写好并装好了,自检 57 项全过。        │
└──────────────────────────────────────────────┘
        ↑ click → the browser tab already showing DSH comes to the front

Host-only bundle: it subscribes to Host events and shells out to a notifier. There is no browser half, so nothing renders in the page and no page refresh is involved.

What it notifies

Host eventWhenBanner
agent/status → idlethe turn ended (a running → idle transition)DSH · 任务完成, body = the last assistant text
user-questions/requestthe agent called ask_user_question and is blockedDSH · 需要你的回答, body = header · question · options
approval/requestthe agent is waiting on an approval decisionDSH · 需要你的批准, body = the reason or the tool name
agent/errora step or turn erroredDSH · 执行出错; the closing banner then reads 任务结束(有报错)

Subagent children stay silent (includeSubagents: false by default), identical banners inside 5 s collapse into one, and consecutive non-urgent banners respect a pacing gap — while a question or approval always gets through.

Requirements

  • macOS. On any other platform the plugin activates, logs a debug line, and sends nothing.
  • Optional, for click-to-open: terminal-notifier (brew install terminal-notifier). Without it the plugin falls back to the osascript banner every macOS ships — same text, same sound, no click action.

On recent macOS an ad-hoc signed notifier is refused until you allow it once: System Settings → Notifications → terminal-notifier → Allow Notifications (style Banners, Play notification sound on). Until then terminal-notifier -diagnose reports authorization: not requested yet and sending returns Notifications are not allowed for this application.

Install

dsh plugin --profile web add /path/to/dsh-plugin-mac-notify   # local directory
dsh plugin --profile web add github:<owner>/dsh-plugin-mac-notify

The package declares dsh.bundle.patch, so the profile records it in dsh.profile.bundles, the layer applies on the next reconcile, and the plugin appears in the GUI's Plugins page with an enable switch and an uninstall action. No dependencies, no install scripts, no build step.

Upgrading needs a restart

DSH caches host-side module code for the life of the process: replacing the package, re-installing it, or toggling the row off and on re-runs the previous generation. Restart dsh web (or dsh tui) after an upgrade. Browser halves are the opposite — those need only a page refresh.

DSH has no plugin auto-update: upgrading means dsh plugin remove followed by dsh plugin add.

Configuration

The bundle row carries no config, so the defaults apply. Override them in the profile's own cordis.patch.yml (applied after every bundle layer):

- id: mac-notify
  name: 'dsh-plugin-mac-notify'
  config:
    sound: Ping
    notifyOnApproval: false
    url: 'http://127.0.0.1:3080'
KeyDefaultMeaning
enabledtruemaster switch
notifyOnFinishtrueturn finished
notifyOnQuestiontruewaiting for an answer
notifyOnApprovaltruewaiting for a decision
notifyOnErrortruea step or turn errored
includeSubagentsfalsealso notify for subagent children
sound'default''default' = your system alert sound (read from com.apple.sound.beep.sound); a name from /System/Library/Sounds (Ping, Glass, Hero, …); 'off' = silent
onClick'focus''focus' = surface the existing DSH tab, else open the URL; 'open' = always open; 'none' = no click action
notifier'auto''auto' prefers terminal-notifier, 'osascript' forces the built-in banner
url''click target; empty means auto-detect (see below)
language'auto''auto' follows LANG/system locale, or pin 'zh' / 'en'
titlePrefix'DSH'banner title prefix
minIntervalMs1500pacing gap between non-urgent banners
bodyMaxChars200banner body budget

How the click target is resolved

url, else the port this Host actually serves the Web UI on (ctx.get('webServer').port), else DSH_WEB_URL from the environment — so a non-default port needs no configuration.

A click runs lib/click.mjs, which asks every running browser (Chrome, Edge, Brave, Vivaldi, Chromium, Safari — found with pgrep, so no browser is launched just to answer) whether one of its windows holds a tab whose URL starts with that target. The first match becomes the active tab and its window is raised. Only when no running browser has it does the helper fall back to /usr/bin/open <url>.

Reading another app's tabs needs macOS Automation permission, which the system grants per browser on first use (click Allow on the “terminal-notifier wants to control …” prompt). A denial is not fatal: the helper falls through to open, so you land on the DSH page in a new tab instead of the existing one.

Troubleshooting

Both switches are environment variables read at delivery time — set them on the process that launches DSH:

DSH_MAC_NOTIFY_DRY_RUN=1 dsh web     # decide everything, spawn nothing
DSH_MAC_NOTIFY_LOG=/tmp/dsh-notify.jsonl dsh web

The JSONL trace records one line per deliver, skip (with reason: disabled / duplicate / paced), failure, and sound-failed, including the resolved backend and click mode.

  • No banner at all → check DSH_MAC_NOTIFY_LOG; on macOS also terminal-notifier -diagnose.
  • Banner but no sound → the plugin puts your system alert sound on the banner, so the usual causes are the system output volume, or Play notification sound being off for the notifier in System Settings.
  • Click does nothing → the click action only exists on the terminal-notifier backend; osascript banners have none. Check echo $DSH_MAC_NOTIFY_LOG for click: "focus" vs "none".
  • Click opens a new tab → Automation permission for that browser was denied, or no running browser has the page (the helper then calls open).

Self-test

node selftest.mjs      # 57 assertions, no notification, no sound, no browser

The suite drives the same lib/index.js the Harness loads, with exec, exists and the clock stubbed: it covers the packaging contract (manifest, patch, locale, icon, the zero-dependency compatibility rule), the pure functions (config normalisation, copy, argv builders, parsers), the registration contract (which events apply subscribes), and event-driven behaviour (what each Host event actually sends, pacing, dedupe, subagent filtering, sound policy, backend fallback, dry-run and trace). It also proves through a real /bin/sh that a quoted click command round-trips.

Layout

lib/index.js     Cordis plugin: apply + the injectable runtime
lib/click.mjs    click handler: focus an existing tab, else open the URL
cordis.patch.yml bundle patch (one insert row)
locale/*.json    display title/description for the Plugins page
icon.svg         package icon
selftest.mjs     offline assertions

Security notes

  • Notification text reaches the notifier as argv, never interpolated into AppleScript source, so a transcript line cannot become executed script.
  • The click command is built from process.execPath, the package's own helper path, and the resolved URL, each single-quoted for the shell that runs it.
  • The plugin reads agent/session state through ctx.get(...), so a missing or restricted service degrades it to "no workspace in the subtitle" instead of an error, and every listener is wrapped so a notification failure can never break Host dispatch.

Why every listener is global

Agent events are dispatched with a scope carrier, and Cordis keeps a listener only when hook.global || !filter || filter(carrier, hook.ctx). A listener registered through a scope-tagged context therefore receives that one agent's events and nothing else — and a row activated from inside an agent's scope, which is exactly what installing through a plugin-manager tool call does, gets that tag. Subscribing with { global: true } takes the listener out of the filter, so one plugin covers every agent in the process.

This is not theoretical: an earlier build registered plain listeners and notified for the installing session only. selftest.mjs asserts the flag on every registration so it cannot regress.

Community catalog

The ready-to-PR entry for awesome-dsh-plugin (the source behind awesome-dsh-plugin.com and dsh-market) lives in contrib/AK-blank__dsh-plugin-mac-notify.yml. To submit it, fork the list, copy that file to data/plugins/AK-blank__dsh-plugin-mac-notify.yml and open a PR — the list's CI requires the repository to be at least one day old, and the dsh-plugin topic (which this repo carries) is what makes dsh-plugin-radar pick it up in the meantime.

scripts/submit-catalog.mjs does the same thing without a local clone: it syncs a fork of the list with upstream main, adds that one file on its own branch, and opens the pull request. It is idempotent (a second run reports the pull request it already opened), refuses to run before the repository's age floor (exit code 3), and never force-pushes or touches an existing pull request.

node scripts/submit-catalog.mjs --dry-run   # validate the entry, write nothing
node scripts/submit-catalog.mjs             # fork, branch, commit, open the PR

License

MIT

Unofficial plugin. Not affiliated with, endorsed by, or supported by DeepSeek. “DeepSeek Harness” is a trademark of DeepSeek; this project uses the abbreviated “DSH” designation for the ecosystem, as the project's brand guidelines recommend.