voyager
Nagi-ovo
Enhancement suite for Gemini, AI Studio, Claude & ChatGPT — plus a prompt manager for any web UI, DeepSeek Harness included. / 面向 Gemini、AI Studio、Claude 与 ChatGPT 的增强套件;提示词管理器可用于任意 Web UI,含 DeepSeek Harness。
PROJECT TOPICS
INSTALL REFERENCE
dsh plugin --profile web add github:yang040709/dsh-win-toast-notify
该命令指向仓库当前默认分支;尚无绑定当前 commit 的完整验证结果。
PROJECT README
A dynamic Cordis plugin for DeepSeek Harness (DSH): pop a native Windows toast notification every time an agent task completes — built for DSH running under WSL2.
DSH 动态 Cordis 插件:每次 agent 任务完成后,在 Windows 上弹出原生 Toast 通知。专为 WSL2 下的 DeepSeek Harness 设计,Windows 侧零依赖。
agent/status event and notifies on idle (no driver remains scheduled or active).agent/error is emitted, with the error message; the completion toast then reports the outcome (任务结束(有错误)) and switches to the IM sound.agents service, so background delegation doesn't spam you.powershell.exe + WinRT, invoked through WSL interop.powershell.exe at startup; outside WSL the plugin simply stays silent. DeepSeek Harness (WSL2, Node.js) Windows
┌──────────────────────────────────────┐ ┌─────────────────────────────┐
│ Dynamic Host plugin │ │ 通知中心 (Action Center) │
│ │ │ │
│ ctx.on('agent/status') │ │ ┌────────────────────────┐ │
│ └─ status === 'idle' ? │ │ │ <会话标题> │ │
│ └─ root agent only │ │ │ 任务已完成 · 第3轮 │ │
│ + stats (turn/tools/ │ │ │ · 耗时2分35秒 │ │
│ duration/model) │ │ │ · 工具调用12次 │ │
│ │ │ │ │ [打开 DSH] ──click─▶ 浏览器│ │
│ ▼ │ │ └────────────────────────┘ │
│ │ │ ▲ │
│ subprocess.spawn( │ │ │ Show($toast) │
│ powershell.exe │ interop │ │ │
│ -EncodedCommand <UTF-16LE b64> │───────────▶│ powershell.exe │
│ ) │ │ WinRT ToastNotification │
└──────────────────────────────────────┘ └─────────────────────────────┘
agent/status with { agent, status } on every idle ⇄ running transition. idle = the task is done. The running edge opens a per-agent stats window (start time, tool-call snapshot).agents.roots()), so subagent/workflow completions stay quiet. While the task runs it gathers stats from DSH events: tools/result (per-agent tool-call count), agent/turn-stopping (turn number), and agent/error (outcome + immediate error toast).Windows.UI.Notifications types, wraps the session title (from the sessionTitle service) and the stats line (XML-escaped) in a ToastGeneric toast XML with a protocol-activation launch/button pointing at the DSH web UI, then calls Show().-EncodedCommand expects — note the builtin btoa is UTF-8, so the plugin ships a tiny byte-level base64 encoder) and spawned via DSH's subprocess service: powershell.exe -NoProfile -NonInteractive -EncodedCommand ....| Component | Requirement |
|---|---|
| Harness | DeepSeek Harness (DSH) with dynamic-plugin support (cordis_define / plugin panel) |
| OS | WSL2 with interop enabled (the default; check echo $WSL_INTEROP) |
| Windows | Windows 10 / 11 — anything with the toast notification center |
| Windows installs | none (uses Windows PowerShell 5.1 + WinRT) |
Two ways to install: a dynamic plugin for the current process (Options A/B), or a persistent mount in an agent preset that survives DSH restarts (Option C, recommended).
This plugin is a dynamic Cordis plugin for a running DSH process. Paste host.js as the Host code and activate it.
winntf).host.js (everything after the comment block, starting at return {) into the Host code field. Leave Client empty.cordis_define:
plugin: { kind: "new", idPrefix: "winntf" }
name: win-task-notify
code: { host: <content of host.js after the comments> }
→ then cordis_run with the returned pluginId + packageId
The plugin is Host-only, so it activates without any Client approval step. On startup it logs which powershell.exe it resolved:
[win-task-notify] powershell.exe resolved to /mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe
win-task-notify.mjs is the same plugin as a proper ESM module for composition rows. Mount it through your profile's user patch layer — no agent preset involved, one host-level instance for the whole process, loaded automatically on every boot:
Copy the file into your profile directory:
${DSH_HOME:-~/.dsh}/profiles/<profile>/plugins/win-task-notify.mjs
Append one insert block to the profile's cordis.patch.yml (relative row names resolve against the profile directory):
# 宿主级插件:消费 subprocess/agents/sessionTitle,不发布服务 → 无需 isolate realm
- insert:
- id: plugin-win-task-notify
name: ./plugins/win-task-notify.mjs
Validate the composed tree offline, then restart DSH:
dsh --profile <profile> --dump-config # the row must appear at the root
The profile patch layer is also hot-reloaded on long-lived surfaces, so a restart may not even be needed.
Alternative: mount the same file inside an agent preset (${DSH_HOME}/.agent-presets/<preset-id>/plugins/ + a row in its agent.cordis.yml) — one instance per session. To change what a shipped preset does, copy the preset first (never edit the shipped install) and edit the copy.
Note: dynamic plugins (Options A/B) live only in the current process; after a DSH restart they are gone, while the profile patch row loads again automatically.
The quickest check is to simply finish a task — the toast fires at the end of the turn that activates it. To test the notification channel independently of DSH:
chmod +x scripts/test-toast.sh
./scripts/test-toast.sh "DSH 通知测试" "来自 WSL 的测试通知"
If a toast appears, the channel works and DSH will notify you on every task completion.
The event logic of both variants (host.js and win-task-notify.mjs) is covered by a dependency-free Node test suite that mocks the DSH services:
npm test # node --test test/plugin.test.mjs
npm run check # syntax check for both JS files + the shell script
DeepSeek Harness); body = 任务已完成 · 第 N 轮 · 耗时 X 分 Y 秒 · 工具调用 N 次 · <model> — each segment appears only when known.agent/error (deduplicated to one per agent per 30 s). If the task ends in error, the completion toast says 任务结束(有错误) and uses the IM sound instead of the default.http://127.0.0.1:3080 via protocol activation — edit DSH_URL in host.js if your DSH web UI listens on another port.$appId in the script.idle, so you get one toast per round (with that round's own stats) — intentional, but easy to throttle if you prefer.It's done, <tags> and &-signs all toast correctly.powershell.exe spawn is aborted after 15 s, so a hung WSL interop call cannot leak a managed child forever. Per-agent state is cleaned up on agent/disposed.agent/turn-stopping no longer reuses the previous run's number.| Symptom | Check |
|---|---|
| No toast, but script exits 0 | Windows notification settings: allow Windows PowerShell to show notifications; also check Focus Assist / Do Not Disturb |
powershell.exe: not found |
WSL interop disabled (WSL_INTEROP empty) or /mnt/c not mounted — fix via /etc/wsl.conf (interop=true) |
| Plugin logs "unavailable" | You are not on WSL2; this plugin targets WSL2 → Windows specifically |
Test script (or a raw powershell.exe call) hangs |
WSL interop can keep waiting on an inherited stdin — use the current scripts/test-toast.sh (it redirects </dev/null), or call powershell with stdin closed |
| Toast worked after hot-reload but not after a DSH restart | v1.3.1 fix: the plugin now declares inject for subprocess/agents/sessionTitle, so it waits for those services on cold boot instead of applying too early and staying silent |
| Toast shows wrong encoding | Ensure the script goes through the UTF-16LE base64 path; don't replace it with plain UTF-8 btoa |
MIT © 2026 yang040709
一个 DeepSeek Harness (DSH) 动态 Cordis 插件:每次 agent 任务完成后,在你的 Windows 桌面弹出原生 Toast 通知。专为 WSL2 下运行 DSH 的场景设计。
agent/status 事件,idle(任务结束、驱动静默)时触发通知,每轮任务恰好一次agent/error 触发时立刻弹独立通知(含错误信息,30 秒去重),任务结束时正文显示"任务结束(有错误)"并改用 IM 提示音agents.roots() 过滤子代理/工作流子任务,后台委托不会刷屏powershell.exe,非 WSL 环境静默降级DSH(WSL2 内)监听 agent/status → 根 agent 进入 idle → 构造 PowerShell WinRT 脚本 → 编码为 UTF-16LE base64(-EncodedCommand 要求的格式)→ 通过 subprocess 服务 spawn powershell.exe → WSL 互操作转发到 Windows → Toast 弹出。
两种方式:动态插件(仅当前进程有效)或 profile 补丁层持久化挂载(宿主级,随 DSH 重启自动生效,不依赖预设,推荐)。
cordis_define 工具)winntf),把 host.js 中注释块之后的函数体粘贴到 Host 代码框(Client 留空)持久化挂载(profile 补丁层,重启后依然自动生效):
把 win-task-notify.mjs 复制到你的 profile 目录:
${DSH_HOME:-~/.dsh}/profiles/<profile>/plugins/win-task-notify.mjs
在该 profile 的 cordis.patch.yml 中追加(相对路径相对 profile 目录解析):
# 宿主级插件:消费 subprocess/agents/sessionTitle,不发布服务 → 无需 isolate realm
- insert:
- id: plugin-win-task-notify
name: ./plugins/win-task-notify.mjs
用 dsh --profile <profile> --dump-config 校验组合树(该行必须出现在根级),然后重启 DSH(profile 补丁层在长驻进程上支持热重载,可能无需重启)。
备选:agent preset 挂载(每个会话一份实例)——同文件放进 ${DSH_HOME}/.agent-presets/<preset-id>/plugins/ 并在该 preset 的 agent.cordis.yml 末尾加同名行;修改内置 preset 前请先复制副本再改副本。
chmod +x scripts/test-toast.sh
./scripts/test-toast.sh "DSH 通知测试" "来自 WSL 的测试通知"
CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。当前命中: windows-notifications。