前言¶
DSH 跑一個長任務時,人常離開窗口去別處。審批來了要確認權限,提問來了要選答案,任務跑完要看結果——這幾類事件如果只在頁面裏體現,人不在就錯過了。已有做法是靠輔助進程發通知,系統會把橫幅歸屬到那個腳本運行器上,點回去也落不到 DSH 會話。
下面介紹的 tommy00748-tech/dsh-native-notifications 換一種方式:通知由 DSH 頁面自己發出來,操作系統把它歸屬到 DeepSeek Harness,點一下橫幅回到會話,並且可以選或自己寫鈴聲。
這是什麼¶
DSH 插件,目錄頁歸在「客戶端」分類,維護者 tommy00748-tech。解決的問題是:讓 DSH 在需要人介入或跑完一輪時,彈一條歸屬正確、可點擊回到會話的桌面通知,避免人一直盯着窗口或錯過審批。
倉庫顯示 0 星,許可證 MIT,npm 包名 dsh-native-notifications。
觸發哪些事件¶
插件監聽以下 Harness 事件,事件含義和默認開關見 README 的表格:
| Harness event | 橫幅內容 | 默認 |
|---|---|---|
agent/status → idle after a turn(root session) |
任務完成 · 用時 … | on |
approval/request 在 approvalDelayMs 後仍掛着 |
需要你確認權限 · tool · reason | on |
user-questions/request 仍掛着 |
正在等待你的選擇 · question | on |
agent/error |
執行出錯 · message | on |
deepseek-account/model-sign-in-required / session-expired |
需要登錄 / 登錄已過期 | on |
subagent/end、workflow/end |
child agent / workflow finished | off |
橫幅標題用會話名稱,正文示例:
<會話名稱>
任務完成 · 用時 5 分 43 秒,可以回來查看結果了。
幾個防噪邏輯:
- 被自動處理掉的審批(例如 Auto 權限預設裏的 LLM reviewer)不會響,橫幅會延遲,只在請求還在等你時觸發。
- 出錯之後那一輪完成的通知被抑制,一次失敗不會響兩次。
- 目標輪次和後續 turn 很快回到
running,完成通知要在會話空閒超過idleGraceMs後才觸發。 - 隊友、子代理和 workflow 子進程按
onlyRootSessions過濾,多智能體長跑只在 root session 真結束時響一次。
鈴聲配置¶
鈴聲由插件用 Web Audio 合成,沒有音頻文件,也不用系統默認音,系統音會被抑制,不會響兩次。所有預設共用同一套動機,含義可辨:完成是上行的 do-mi-so,”需要你”是兩聲高頻短音,出錯下行。
打開 Settings → General → Notification sound,可選預設:
| preset | 音色 |
|---|---|
| Playful bubbles(默認) | triangle 主體,帶小幅上滑和一個高音閃爍 |
| Soft bell | sine 主體,加一個輕的八度泛音 |
| Bright pluck | 短 triangle 撥絃,沒有滑音 |
| Custom | 自己的音符序列,用 playful 音色播放 |
| Muted | 無聲 |
這一行有 Preview 按鈕。Custom 用文本框輸入,最多八個以空格或逗號分隔的音符,可以是音名(C6 E6 G#6、Bb5)也可以是頻率(1046.5 1318.5):
C6 E6 G6 ← do-mi-so
G6 G6 ← double boop
1046.5 1318.5 ← 同上兩個音符的頻率寫法
偏好存頁面 localStorage 的 dsh-native-notifications:sound,所以是按設備/瀏覽器生效的,下一次橫幅即生效,不需要走 Host 往返。
安裝與啓用¶
安裝命令來自倉庫 README,按 profile 區分 Web 和桌面:
# from GitHub
dsh plugin --profile web add github:tommy00748-tech/dsh-native-notifications
dsh plugin --profile desktop add github:tommy00748-tech/dsh-native-notifications
# from npm(npm 發佈後可用)
dsh plugin --profile web add dsh-native-notifications
# from a local checkout
dsh plugin --profile desktop add link:/absolute/path/to/dsh-native-notifications
裝完在 Settings → Plugins 確認 desktop-notifications 那一行是啓用的,bundle patch 會插入並默認啓用它。沒有構建步驟、沒有依賴、沒有原生模塊:Host 半部分是普通 ESM,Client 半部分是一個純 JS bundle。
要求:
- 有提供 Web UI 的 DSH profile(
desktop或web); - 頁面在安裝時自動加載 Client 半部分(Host graph 重建會同步給已連接的頁面);如果手工拷貝後橫幅一直沒出現,重載一次窗口;
- 操作系統裏要爲 DeepSeek Harness 允許桌面通知(macOS 在 System Settings → Notifications)。Electron 會授予頁面權限,但 OS 層面的允許是獨立的。
配置項¶
所有開關都在那一行的 config 上,默認值連同說明寫在 cordis.patch.yml 裏。注意 patch 會整體替換 config,所以只想改一個字段時要把想保留的字段一併寫回去:
- id: desktop-notifications
config:
notifyComplete: true
notifyQuestion: false # do not ring for questions
idleGraceMs: 2000
onlyRootSessions: true
delivery: client # client | osascript | both
可用字段:notifyComplete、notifyApproval、notifyQuestion、notifyError、notifyAccount、onlyWhenUnfocused、silent、idleGraceMs、errorSuppressMs、approvalDelayMs、onlyRootSessions、notifyOnMount、logPath。
delivery: osascript 是給頁面無法展示 Web 通知的宿主的遺留回退,macOS 下這類橫幅歸屬到 Script Editor,默認關閉。
診斷日誌¶
每次橫幅和每次客戶端上報都會追加到審計日誌,默認 ~/.dsh/dsh-native-notifications.log,可用 logPath 改路徑。日誌樣例:
2026-11-05T08:58:26.102Z mounted :: pid=9027 :: delivery=client :: epoch=... :: platform=darwin
2026-11-05T08:58:26.178Z client :: boot :: permission=granted protocol=dsh-app: path=/ visibility=hidden sound=cute chime=v5-robust
2026-11-05T08:59:47.177Z banner :: 能不能做個DSH原生的通知插件 :: 任務完成 · 用時 5 分 43 秒,可以回來查看結果了。
2026-11-05T08:59:47.186Z client :: shown :: kind=complete permission=granted
2026-11-05T08:59:47.188Z client :: sound :: kind=complete preset=cute
針對”爲什麼沒彈橫幅”,按日誌判斷:
- 沒有
client :: boot→ Client 半部分沒加載,重載窗口; client :: permission :: denied→ 系統/瀏覽器不允許通知;client :: suppressed→onlyWhenUnfocused跳過了已聚焦的窗口;- 有
banner ::但沒有client :: shown→ 頁面沒輪詢到(看poll-failed/unauthorized); - 有
client :: shown但沒有client :: sound→ 鈴聲沒響(音頻仍被鎖,或靜音了)。
想直接發一條通知驗證 osascript 通道:
node scripts/notify-test.mjs "title" "body"
工作原理¶
一個 bundle,兩半:
- Host(
index.js)監聽上面那些事件,維護一個小的環狀緩衝區存橫幅事件。它在ctx.webServer上提供兩個同源路由:/native-notifications/events(長輪詢)和/native-notifications/report(客戶端診斷),和 Host 其他 Web 路由一樣用ctx.connection.requestRejection做門禁,所以只有已認證頁面能讀。 - Client(
client.js,無渲染、始終掛載)長輪詢這兩個路由,通過平臺通知 API(new Notification(...))展示每個事件,點擊時聚焦 DSH 並調用uiWorkspace.openSession(sessionId)。游標和 Host epoch 存在localStorage,所以重載不會重放舊橫幅,Host 重啓從”現在”開始。
長輪詢在 wait + 10s 後中斷並重試,所以 Host 重掛不會卡住客戶端。插件不追加 session 事件、不 import Harness Client 包,只貢獻一個 bundle 行和一個 Settings 行。
兼容性¶
README 標明在 dsh 0.2.1-rc.5 和 0.2.2-rc.1 上測試過。運行時兼容性檢查讀的是頂層 engines.dsh 字段,package.json 裏是 >=0.2.1-rc.5 <0.3.0,Node 要求 >=20。
適用場景與注意¶
適合需要在 DSH 上跑長任務、又不想一直守着窗口的人,以及團隊裏跑多智能體長任務、希望只在 root session 結束時響一次的場景。如果你的宿主頁面無法展示 Web 通知,delivery: osascript 是備選,但要接受橫幅歸屬到 Script Editor。
兩點提醒:通知以當前 DSH 進程的權限發出,OS 層面要爲 DeepSeek Harness 打開通知授權;插件來源是社區維護的 GitHub 倉庫(社區目錄站上也有它的條目,該目錄與 DeepSeek / 幻方無官方從屬關係),裝之前建議先過一遍源碼和 MIT 許可證。
結尾¶
一句話回顧:它把 DSH 的審批、提問、完成、出錯和登錄橫幅歸到 DeepSeek Harness 名下,可選或自定義合成鈴聲,並提供審計日誌方便排查沒響的原因。目錄頁在 https://www.skillhub.cn/plugins/tommy00748-tech/dsh-native-notifications,倉庫在 https://github.com/tommy00748-tech/dsh-native-notifications。