Astral-Yang/dsh-bark-push ↗★ 1
dsh-bark-push
Push notifications for DeepSeek Harness: reply summaries, approval requests, and user questions via Bark plus Gotify, ntfy, PushDeer, Server酱, PushPlus, extra Bark servers, and generic webhooks, with per-workspace and per-session mute.
安装
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:Astral-Yang/dsh-bark-push说明文档
阅读完整 README ↗2.2 实际使用的事件、服务与 API
| 需求 | 使用的 DSH 机制 | 位置/说明 |
|---|---|---|
| Agent 回复完成 | ctx.on('session/event', ...) 的 assistant/message、turn/end | turn/end.data.reason.kind === 'completed' 才推送;取该回合最后一条 message.content 中的 text 块 |
| 会话销毁清理 | session/disposed | 清理回合缓存、标题缓存 |
| 审批请求 | session/event 的 approval/asked | 事件带 id、toolName、reason、callId;按 id 去重 |
| 用户选择 | ctx.on('user-questions/request', (request, next) => ...) waterfall | 只观察并 next(),不 claim;request.wait.callId 可作为去重键 |
| Workspace 身份 | ctx.workspaceRegistry.list()/get()/resolveByPath() | 稳定 WorkspaceId;成员关系优先,cwd realpath 兜底 |
| Conversation 身份 | session.header.id / session.id | SessionId,作为会话静音键 |
| 会话标题 | ctx.sessionTitle.get(session),以及 session/title 事件缓存 | 回复标题、审批/选择正文上下文 |
| 配置 | Loader config(cordis.patch.yml / bundle patch) | 所有字段有 JS 默认值;不依赖 schemastery |
| 可变状态 | $DSH_HOME/bark-push/state.json | DSH 没有“插件自定义可变状态”的通用服务;JSON 文件是兼容性最好的做法 |
| 配置/静音 HTTP API | ctx.connection.fetch.register(...) | /api/bark-push/*,自动复用浏览器 Cookie 认证、Host/Origin 检查和 owner Peer 限制 |
| 公共跳转地址 | ctx.webApp.getAdvertisedUrl(),回退 ctx.webServer.getOrigin() | 兼容反向代理下的 publicUrl |
| 客户端设置页 | 客户端 settings.section Slot | 内嵌 /api/bark-push/ui?embed=1 |
| 工作区/会话右键菜单 | 客户端 `ctx.contextMenus.register({ target: 'workspace' | 'session' })` |
| 会话行铃铛 | sidebar.workspaces.session.row.action Slot | 有会话行时显示 🔔/🔕 |
| 会话跳转 | 客户端 ctx.uiWorkspace.openSession(sessionId) | 读取 ?barkSession= 后调用 |
4. 配置
4.1 Settings 页面
Settings → 推送通知 采用“分区 + 状态优先”的布局(不再是嵌套卡片):
- 默认渠道 · Bark:Bark Server、Device Key(掩码列表 / 追加 / 清空);分组、级别与铃声、标题与长度、网络重试、跳转调试等低使用率项收进可折叠的**「高级选项」**(默认折叠)。
- 通知规则:总开关、回复 / 批准 / 选择 / 子代理五个开关,用卡片式开关呈现,每个都有一句说明。
- 渠道:每个额外渠道是一行“投递通道”:左侧状态点(绿色=启用 / 空心=停用)、名称与类型标签、启用开关、参数(展开才编辑)、测试、删除;支持 Gotify / ntfy / PushDeer / Server酱 / PushPlus / 额外 Bark / 自定义 Webhook,可逐个添加。
- 静音管理:工作区 / 会话两层静音。
页面只显示 Device Key 与渠道密钥的掩码(例如 TEST••••90),完整值不会出现在页面、JSON API 或日志中。每个分区底部都有「保存全部更改」按钮,保存后就地显示「已保存 HH:MM:SS」,不依赖 toast、也不受滚动位置影响。
4.2 配置字段
| 字段 | 默认 | 说明 |
|---|---|---|
enabled | true | 总开关 |
server | https://api.day.app | Bark Server 根地址;可带子路径,末尾 /push 会被归一化 |
deviceKeys | [] | 一个或多个 Device Key;最多 20 个 |
channels | [] | 额外推送渠道数组;见 4.6。每个元素为 { id, type, label, enabled, config },最多 20 个 |
group | DSH | Bark 通知分组 |
icon | '' | 图标 URL,可选 |
soundReply | '' | 回复通知铃声,可选;留空用 Bark/系统默认 |
soundApproval | '' | 审批通知铃声,可选 |
soundQuestion | '' | 选择通知铃声,可选 |
levelReply | active | 回复通知级别 |
levelApproval | timeSensitive | 审批通知级别 |
levelQuestion | active | 选择通知级别 |
notifyOnReply | true | Agent 回复 |
notifyOnApproval | true | 需要批准 |
notifyOnQuestion | true | 等待选择 |
includeSubagents | false | 是否推送子代理会话;默认跳过 |
titleMode | session | 回复标题来源:session 会话标题、session-summary 会话标题 + 摘要、summary 回复摘要 |
titlePrefix | '' | 回复标题前缀;留空则只用所选标题 |
maxTitleLength | 64 | 标题最大字符数(8–200) |
maxBodyLength | 1200 | 正文最大字符数(32–4000) |
timeoutMs | 8000 | 单次请求超时(1000–30000) |
maxRetries | 2 | 0–5 次重试 |
retryDelayMs | 500 | 指数退避基础间隔(50–10000) |
linkToSession | true | 生成 ?barkSession= 点击链接 |
publicBaseUrl | '' | 覆盖 advertised URL;留空时自动使用 ctx.webApp.getAdvertisedUrl() |
trace | false | 保留字段;默认不输出消息内容 |
stateFile | 由 DSH_HOME 推导 | 仅 Loader 配置:覆盖 state.json 路径;管理页不暴露 |
4.3 优先级
配置有两层:
- Loader 配置:bundle patch 或 profile
cordis.patch.yml,作为启动默认值。 - Settings 页面写入的覆盖值:
$DSH_HOME/bark-push/state.json的config字段。
启动时以 Loader 配置为基线,叠加 state 文件覆盖值。UI 保存只写 state 文件,不会改写 profile 的 YAML,也不需要重启。设置页的“恢复默认”保留 Device Key,避免误删凭据;需要清空时用“清空密钥”。
4.4 敏感信息
- Device Key 优先通过 Settings 页面填写,写入
state.json(0600)。 - 额外渠道的 Token / Key / Webhook 地址等敏感字段同样只写入
state.json(0600),API 与页面只回传“已设置”。 - 如果写在
cordis.patch.yml,该文件通常对整个 profile 可读;这是部署方的选择。 - 日志只输出掩码,例如
TEST••••90;错误消息中的 Key 会被替换为••••。 - 消息正文不会写入日志。
4.5 Bark 级别说明
| 级别 | 显示名称 | 设备行为 |
|---|---|---|
active | 主动通知 | 默认级别,收到通知时会亮屏提醒。 |
timeSensitive | 时效性通知 | 优先级较高,可在允许时效性通知的专注模式下显示。 |
passive | 静默通知 | 仅显示在通知中心,不主动亮屏提醒。 |
critical | 紧急通知 | 最高优先级,可突破静音模式和专注模式,并发出提示音。需要在 Bark App 里授权「重要警告」;没有授权时会降级成普通通知,推送铃声音量由 volume 控制。需要 iOS 15 及以上。 |
当前默认:
- 回复:
active/ 无自定义铃声 - 审批:
timeSensitive/ 无自定义铃声 - 选择:
active/ 无自定义铃声
旧版本的 levelNormal / levelImportant / soundNormal / soundImportant 仍作为迁移回退读取,但管理页只编辑新的三组独立字段。
4.6 更多推送渠道
Bark 是内置的第一渠道(仍用上面的 server / deviceKeys 配置)。除此之外,可以在设置页「更多推送渠道」中添加任意数量的额外渠道,每条通知会同时投递到 Bark 和所有已启用且已填写完整的渠道。每个渠道独立开关、独立超时与重试;某个渠道失败只影响它自己,不会阻断其他渠道或 DSH 本身。
支持的渠道类型:
类型 type | 名称 | 必要参数 | 可选参数 |
|---|---|---|---|
gotify | Gotify(自建) | server、token | priority(0–10,默认 5) |
ntfy | ntfy | topic | server(默认 https://ntfy.sh)、token(Bearer) |
pushdeer | PushDeer | pushKey | server(默认 https://api2.pushdeer.com) |
serverchan | Server酱³ | sendKey | — |
pushplus | PushPlus | token | — |
bark | 额外 Bark 服务器 | deviceKey | server(默认 https://api.day.app)、group、level |
webhook | 自定义 Webhook | url | method(POST/PUT/GET)、contentType、headers、bodyTemplate |
自定义 Webhook 模板占位符:{{title}}、{{body}}、{{kind}}、{{url}}。默认请求体为 {"title":"{{title}}","body":"{{body}}","kind":"{{kind}}","url":"{{url}}"};headers 接受 JSON 对象字符串(如 {"Authorization":"Bearer …"})。返回 2xx 视为成功。
密钥与隐私:所有 Token、Key、Webhook 地址等敏感字段只保存在 state.json(0600),管理页与 /api 返回中只显示“已设置”,不会回传明文。编辑时敏感字段留空表示保持原值;要清除请删除该渠道或重新填写。
逐渠道测试:每个渠道卡片上的「测试」按钮会先保存当前配置,再只对该渠道发一条测试通知,结果就地显示在该渠道卡片内,便于逐个确认参数是否正确。Bark 卡片里的「测试推送」只测试内置的 Bark(默认渠道),按设备逐条列出成功/失败,不会把额外渠道一起发一遍;要测某个额外渠道就点它卡片上的「测试」。
保存反馈:Bark 卡与「更多推送渠道」卡各自的「保存配置」按钮在保存后会就地显示「已保存 HH:MM:SS」或「保存失败:…」,无需滚动或依赖 toast 也能确认结果;渠道有增删改未保存时会提示「有未保存的更改」。此外所有操作仍会触发宿主浮层 toast。
反馈与布局:管理页以 iframe 嵌入 Settings,宿主会把 iframe 撑到内容全高,因此页面内的「固定底部 toast」会落在整页最底部而不可见。所以所有操作提示改由客户端半通过 shell.overlay(DSH 官方的框架级浮层座位,位于顶层文档、盖在所有列之上)渲染,滚到哪都可见;测试结果则就近显示在触发它的卡片里。页面顶部只保留一条轻量状态条(启用状态 / 设备数 / 渠道数 / 上次结果)。
Loader / profile 也可以用 YAML 预置渠道,例如:
channels:
- id: ch_gotify_home
type: gotify
label: 家里的 Gotify
enabled: true
config:
server: https://gotify.example.com
token: Axxxxxxxx
priority: "5"
- id: ch_hook_ci
type: webhook
enabled: true
config:
url: https://example.com/dsh-hook
method: POST
contentType: application/json
4.2 配置字段
| 字段 | 默认 | 说明 |
|---|---|---|
enabled | true | 总开关 |
server | https://api.day.app | Bark Server 根地址;可带子路径,末尾 /push 会被归一化 |
deviceKeys | [] | 一个或多个 Device Key;最多 20 个 |
channels | [] | 额外推送渠道数组;见 4.6。每个元素为 { id, type, label, enabled, config },最多 20 个 |
group | DSH | Bark 通知分组 |
icon | '' | 图标 URL,可选 |
soundReply | '' | 回复通知铃声,可选;留空用 Bark/系统默认 |
soundApproval | '' | 审批通知铃声,可选 |
soundQuestion | '' | 选择通知铃声,可选 |
levelReply | active | 回复通知级别 |
levelApproval | timeSensitive | 审批通知级别 |
levelQuestion | active | 选择通知级别 |
notifyOnReply | true | Agent 回复 |
notifyOnApproval | true | 需要批准 |
notifyOnQuestion | true | 等待选择 |
includeSubagents | false | 是否推送子代理会话;默认跳过 |
titleMode | session | 回复标题来源:session 会话标题、session-summary 会话标题 + 摘要、summary 回复摘要 |
titlePrefix | '' | 回复标题前缀;留空则只用所选标题 |
maxTitleLength | 64 | 标题最大字符数(8–200) |
maxBodyLength | 1200 | 正文最大字符数(32–4000) |
timeoutMs | 8000 | 单次请求超时(1000–30000) |
maxRetries | 2 | 0–5 次重试 |
retryDelayMs | 500 | 指数退避基础间隔(50–10000) |
linkToSession | true | 生成 ?barkSession= 点击链接 |
publicBaseUrl | '' | 覆盖 advertised URL;留空时自动使用 ctx.webApp.getAdvertisedUrl() |
trace | false | 保留字段;默认不输出消息内容 |
stateFile | 由 DSH_HOME 推导 | 仅 Loader 配置:覆盖 state.json 路径;管理页不暴露 |
5. Bark 配置示例
官方服务器
server: https://api.day.app
deviceKeys:
- YOUR_BARK_DEVICE_KEY
group: DSH
soundReply: bell
soundApproval: alarm
soundQuestion: bell
levelReply: active
levelApproval: timeSensitive
levelQuestion: active
自建服务器
server: https://bark.example.com
deviceKeys:
- YOUR_BARK_DEVICE_KEY
带子路径的自建服务器
server: https://example.com/bark