Back to home

yLong765

dsh-meow-notify

No description

Stars
1
Language
JavaScript
Created
Aug 14, 2026
Updated
Aug 14, 2026

Introduction

meow-notify — DSH 消息推送插件(双端版 v8 · npm 一键安装)

把 DSH(DeepSeek Harness)的关键事件推送到手机(MeoW App),并支持在 Web 设置页的「插件配置」卡片里直接修改配置:

  • agent 一轮运行完成 → 推送「✅ 会话标题」
  • 需要人员介入 / 授权 → 推送「⚠️ 会话标题」(优先级最高,不受节流限制)
  • GUI 配置卡片 → 设置 → 插件 → 插件配置 → 「MeoW 推送」卡片,保存即热生效

推送内容带会话标题 / 工作目录名,多个任务并行时一眼分清是哪个会话。

安装一条命令npm i -g meow-notify && meow-notify install(自动完成部署、平台补丁、配置注册,见第 3 节)。


目录

  1. 工作原理
  2. 前置条件
  3. 安装
  4. 验证安装
  5. 可调节的配置项
  6. 日常使用
  7. 更新插件代码
  8. 禁用与卸载
  9. 常见问题排查
  10. 目录结构与开发

1. 工作原理

┌─────────────┐   session/event    ┌──────────────┐   HTTPS GET    ┌───────────┐
│  DSH 进程    │ ─────────────────▶ │ meow-notify  │ ─────────────▶ │ MeoW 服务器 │
│ (dsh web等) │  turn/end          │ (Cordis插件) │  base/nick/…  │           │
│             │  approval/asked    │              │                └─────┬─────┘
└─────────────┘                    └──────┬───────┘                      │
      ▲                                  │ appendFileSync               ▼
      │  settings 域(GUI 卡片读写)       ▼                        📱 手机收到推送
┌─────┴──────────┐               notify.log(证据日志)
│ settings.yaml  │
└────────────────┘
  • 插件以 Cordis 双端插件形式加载进 DSH 进程:
    • host 端index.js):监听框架级 session/event 事件流,注册 settings namespace。
    • client 端client.js):在浏览器注册「设置 → 插件 → 插件配置」卡片。
  • 这是框架级钩子,不依赖模型自觉——即使 agent 忘了做什么,事件照常触发推送。
  • 通过 $DSH_HOME/cordis.patch.yml(home 级补丁)注册,对所有 profile 生效重启后持久
  • 配置三层合并:schema 默认值 ← patch config(base)← settings.yaml(user,GUI 写入)。GUI 保存只改 user 层,patch 文件保持不动。

推送格式:

事件推送标题推送正文
插件加载meow-notify插件已加载 v8 · <昵称>
任务完成✅ <会话标题或目录名>第 N 轮 · <原因> · <目录名>
需要介入⚠️ <会话标题或目录名><工具名> 等待批准 · <目录名>
子代理会话上述标题加 [子] 前缀同上

会话标签的来源(优先级从高到低):

  1. 会话标题(DSH 根据首条提问自动生成,也可在 Web UI 侧栏手动改名)
  2. 工作目录的最后一段(如 E:\proj\app-serverapp-server
  3. 兜底 ?

2. 前置条件

条件说明
DSH 已安装能运行 dsh web(DeepSeek Harness CLI)
Node.js ≥ 18插件用全局 fetch;DSH 本身跑在 Node 上,一般已满足(开发机为 v24)
MeoW App手机安装 MeoW(鸿蒙消息提醒应用),注册并记下你的接收昵称(nickname)
网络运行 DSH 的电脑能访问 https://api.chuckfang.com

MeoW 昵称是什么? 打开 MeoW App,在"我的"页面看到的用户名/昵称就是 API 路径里的 nickname,推送会发给这个名字对应的设备。


3. 安装

方式 A:npm 一键安装(推荐)

包已发布到 npm,两条命令完成全部安装(自动部署文件、打平台补丁、注册配置):

npm install -g meow-notify
meow-notify install          # 交互式,会询问 MeoW 昵称
# 或非交互:meow-notify install --nickname=你的昵称

install 命令自动完成:

  1. 定位 DSH:解析 @deepseek-ai/dsh-host-apiproxy 的安装位置(支持 $DSH_HOME 自定义)
  2. 部署文件:把插件复制到 $DSH_HOME/profiles/node_modules/meow-notify/
  3. 打平台补丁:把 meow-notify 加入 WEB_SETTINGS_NAMESPACES(DSH 的 Web 设置允许列表,见下方说明)
  4. 注册配置:幂等地把插件条目写入 $DSH_HOME/cordis.patch.yml

然后重启 DSH:

dsh web

卸载meow-notify uninstall(移除 patch 条目和平台补丁,保留插件文件)。

为什么需要平台补丁? DSH 的 host-apiproxy 硬编码了 Web 设置允许列表 WEB_SETTINGS_NAMESPACES,只有列表里的 settings namespace 才会被浏览器端 settings.describe 返回、才能被 GUI 配置卡片读写。当前 DSH 版本(0.1.0-rc.x) 第三方插件无法自行暴露配置(官方注释称此为 "deferred work"),必须把 meow-notify 加入该列表。安装脚本自动完成;DSH 升级后补丁可能丢失, 重新运行 meow-notify install 即可恢复。

没装 npm 或想离线安装? 见方式 B(Windows 一键)或方式 C(手动)。


方式 B:Windows 源码一键安装(install.bat)

适用于下载源码包/离线分发的场景(无需 npm):

  1. 下载并解压源码包(含 install.batinstall.mjsindex.jsclient.js 等文件)
  2. 双击 install.bat,在菜单里输入 1 回车
  3. 按提示输入 MeoW 昵称,回车
  4. 等待自动完成:部署文件 → 平台补丁 → 注册配置
  5. 重启 DSH:dsh web

也支持命令行方式(便于脚本化):

install.bat install --nickname=你的昵称     :: 一键安装
install.bat uninstall                        :: 卸载

注意事项:

  • 需要先安装 Node.js 18+ 和 DSH(dsh web 至少运行过一次)。
  • 若提示文件写入失败,右键 install.bat →「以管理员身份运行」。
  • bat 界面为英文(避免 Windows 编码兼容问题);过程中的中文提示由安装脚本输出。

方式 C:手动安装

共 3 步:放包 → 注册 → 重启。插件以 npm 包形态安装,这样才能同时加载 host 端(推送)和 client 端(GUI 卡片)。

第 1 步:放置插件包

把整个 meow-notify 目录(含 index.jsclient.jspackage.json)放到 profile 的 node_modules 下

  • Windows:C:\Users\<你的用户名>\.dsh\profiles\node_modules\meow-notify\
  • macOS / Linux:~/.dsh/profiles/node_modules/meow-notify/

$DSH_HOME/profiles/node_modules 是 DSH 的 flat fallback 依赖目录,所有 profile 都能从它解析包。目录名必须叫 meow-notify(与 package.json 的 name 一致)。

第 2 步:注册到 DSH 全局配置

编辑 $DSH_HOME/cordis.patch.yml(默认 ~/.dsh/cordis.patch.yml不存在就新建):

# DSH 全局补丁层:对所有 profile 生效,运行中修改会被热加载。
- insert:
    - id: meow-notify
      name: 'meow-notify'        # npm 包名:host 端从 index.js 加载,client 端自动被发现
      config:
        enabled: true
        nickname: "你的MeoW昵称"  # ← 必填:MeoW App 里注册的接收昵称
        base: "https://api.chuckfang.com"
        # turnEndMinIntervalMs: 25000   # 可选:完成推送最小间隔(毫秒)
        # includeChildren: false        # 可选:不通知子代理会话

注意:

  • 顶层必须是 YAML 数组(- insert: 开头)。
  • name 必须是包名 meow-notify(不能是路径),这是 client 端被发现的前提:DSH 会用 require.resolve('meow-notify/package.json') 找到它,读取 dsh.client 声明和 exports["./client"]
  • 如果文件里已有其他条目,把 - id: meow-notify ... 这段追加到数组末尾即可。

第 3 步:给 DSH 打平台补丁(仅首次安装需要)

为什么需要? DSH 的 host-apiproxy 硬编码了一个 Web 设置允许列表 WEB_SETTINGS_NAMESPACES,只有列表里的 settings namespace 才会被浏览器端 settings.describe 返回、才能被 GUI 配置卡片读写。当前 DSH 版本(0.1.0-rc.x) 第三方插件无法自行暴露配置(官方注释称此为 "deferred work"), 必须把 meow-notify 加入这个列表,否则卡片不会显示。

运行插件自带的补丁脚本(自动定位 DSH 安装位置并打补丁,幂等可重复执行):

node setup.mjs

若脚本找不到 DSH 安装位置(npx 缓存/全局安装路径特殊),显式指定:

node setup.mjs "C:\Users\<你>\AppData\Local\npm-cache\_npx\<hash>"   # Windows 示例

或者手动编辑 <DSH安装>/node_modules/@deepseek-ai/dsh-host-apiproxy/lib/index.js, 在 WEB_SETTINGS_NAMESPACES 数组里加上 "meow-notify"

const WEB_SETTINGS_NAMESPACES = [
	"agent-loop",
	"shell",
	"locale",
	"permission",
	"ui-conversation",
	"ui-theme",
	"web-search-deepseek",
	"meow-notify"        // ← 加上这一行
];

注意:DSH 升级后补丁会丢失(安装目录被替换),重新运行 node setup.mjs 即可。

第 4 步:重启 DSH

dsh web

重启后 1~2 秒内,手机应收到 「meow-notify / 插件已加载 v8 · 你的昵称」——收到即安装成功。

第 5 步:打开 GUI 卡片

浏览器打开 DSH Web(http://127.0.0.1:3080)→ 设置 → 插件 → 插件配置,应能看到 「MeoW 推送」 卡片:

  • 展开可编辑:MeoW 昵称、推送 API 地址、完成推送最小间隔、是否通知子代理会话
  • 改完点保存:写入 $DSH_HOME/settings.yamlmeow-notify 段,1~2 秒热生效(手机收到一条「插件已加载 v8」确认)
  • 字段旁的「已覆盖」徽标表示该字段被 user 层覆盖(相对 patch config / 默认值),可点恢复默认

如果看不到卡片:确认 name 是包名、包在 profiles/node_modules/meow-notify/已运行 node setup.mjs 打平台补丁并重启 DSH,然后刷新浏览器页面(卡片由前端启动时加载,改包后需要刷新或重启)。


4. 验证安装

三步验证,全部满足即工作正常:

  1. 加载验证:启动 DSH 后手机收到「插件已加载」推送。
  2. GUI 验证:设置 → 插件 → 插件配置 → 出现「MeoW 推送」卡片,能保存配置。
  3. 日志验证:查看插件目录下的 notify.log(在 profiles/node_modules/meow-notify/ 下,首次推送后自动生成),应有:
    2026-08-14T14:17:07.025Z LOADED v8 nickname=xxx base=https://api.chuckfang.com interval=25000ms includeChildren=true node=v24.14.0
    2026-08-14T14:17:07.2xxZ PUSH-OK [meow-notify] 插件已加载 v8 · xxx :: {"status":200,"data":true,"msg":"发送成功"}
    
  4. 事件验证:随便让 agent 干个活(或发条消息),这轮结束时手机收到「✅ …」;触发一次需要授权的操作(比如让 agent 写工作区外的文件),收到「⚠️ …」。

notify.log 每行的含义:

前缀含义
LOADED …插件已加载(含生效配置)
EVENT turn/end turn=N reason=… label=…捕获到一轮结束事件
EVENT approval/asked tool=… label=…捕获到审批请求事件
PUSH-OK [标题] 正文 :: 响应已成功提交给 MeoW
SKIP-THROTTLE [标题] gap=…被节流拦截(间隔不足)
PUSH-FAIL [标题] 错误码网络请求失败
HANDLER-ERROR …事件处理异常(不应出现)

5. 可调节的配置项

5.1 通过 GUI 卡片(推荐)

设置 → 插件 → 插件配置 → 「MeoW 推送」卡片,改完点保存,1~2 秒热生效。

5.2 通过 settings.yaml

GUI 保存的内容写入 $DSH_HOME/settings.yaml

meow-notify:
  nickname: "1529e2a0"
  turnEndMinIntervalMs: 60000

5.3 通过 cordis.patch.yml(base 层)

      config:
        nickname: "你的MeoW昵称"
        base: "https://api.chuckfang.com"
        turnEndMinIntervalMs: 25000
        includeChildren: true
配置项类型默认值作用
nicknamestring无(必填)MeoW 接收昵称。推送给谁的手机。
basestringhttps://api.chuckfang.com推送 API 根地址。一般不用动。
enabledbooltrue总开关。false = 不推送。
turnEndMinIntervalMsnumber25000「任务完成」推送的全局最小间隔(毫秒)。两条完成推送间隔不足此值时,后一条被跳过(记 SKIP-THROTTLE)。调大=更安静,调小=更即时但可能触发 MeoW 限流。
includeChildrenbooltrue是否通知子代理 / workflow 会话。子会话标题带 [子] 前缀。

节流机制说明(为什么有 turnEndMinIntervalMs

MeoW 服务端有约每分钟 3 条的静默限流:超量请求 HTTP 仍返回「发送成功」,但手机实际收不到。因此插件内置客户端节流:

  • approval/asked(需要介入)永不节流——人工介入最紧急,且这类事件本身稀少;它的发送也不占用完成推送的节流额度。
  • turn/end(任务完成)维护自己的节流时间戳:距上一次完成推送不足 turnEndMinIntervalMs 就跳过,保证完成推送 ≤ 约 2.4 条/分钟,把额度让给介入通知。
  • 节流是跨所有会话全局的(多会话叠加也不会超限)。

6. 日常使用

  • 什么都不用做。插件在后台随 DSH 自动加载,事件触发自动推送。
  • 手机上的推送点开后是纯文本;MeoW 支持点按通知打开 App 查看全文。
  • 想看插件在干什么:翻 notify.log(在 profiles/node_modules/meow-notify/ 下,自动增长,可随时删除,删后下次推送会重建)。
  • 多任务并行时,靠推送标题的会话名区分(见第 1 节推送格式)。想让标题更好认:在 DSH Web UI 侧栏给会话手动改名,改名后的推送立即使用新标题。

7. 更新插件代码

改了 index.js / client.js 之后,由于 Node ESM 模块缓存,运行中的 DSH 可能仍用旧代码。两种办法:

办法 A(推荐,简单):重启 DSH

# 停掉 dsh web 再启动
dsh web

办法 B(不重启,热加载):给 name 加/递增缓存戳

      name: 'meow-notify?v=2'   # 原来 ?v=2 就改成 ?v=3

保存 cordis.patch.yml 后约 1~2 秒热加载,手机会收到新版「插件已加载」确认。

注意?v= 会改变 client-modules 的包名解析吗?不会——require.resolve('meow-notify?v=2/package.json') 会失败!所以带 ?v= 时 client 端可能不再被发现。升级代码最稳的方式是办法 A(重启);办法 B 只适合改 host 端推送逻辑、不需要动 GUI 卡片的场景。


8. 禁用与卸载

临时禁用(保留文件,随时恢复):

      config:
        enabled: false

或直接在 insert 行加 disabled: true

    - id: meow-notify
      name: 'meow-notify'
      disabled: true

只保留「需要介入」通知(静音完成推送):

      config:
        nickname: "你的昵称"
        turnEndMinIntervalMs: 2147483647   # 24.8 天,等效永久静音完成推送

彻底卸载:

  1. 删掉 cordis.patch.yml- id: meow-notify 那一整段。
  2. 删除 $DSH_HOME/profiles/node_modules/meow-notify/ 目录。
  3. (可选)删掉 settings.yaml 里的 meow-notify: 段。
  4. 下次启动 DSH 即完全恢复原状。

9. 常见问题排查

Q1:启动后没收到「插件已加载」

  1. notify.log(在 profiles/node_modules/meow-notify/ 下)是否生成:
    • 没有文件 → 插件根本没被加载。检查 cordis.patch.ymlname 是否为包名 meow-notify、包是否在 profiles/node_modules/meow-notify/、YAML 格式(顶层必须是数组)。
    • NOT-ENABLEDenabled 写成 false 或 nickname 空了。
    • PUSH-FAIL … ENOTFOUND/ETIMEDOUT → 电脑访问不了 api.chuckfang.com(代理/防火墙)。
  2. PUSH-OK 但手机没收到 → nickname 写错(MeoW App 里核对),或 MeoW 服务端限流(刚连发过几条,返回「发送太快」或「IP限制」)。
  3. 都没有 → 重启 DSH 看启动日志有无 loader 报错。

Q2:GUI 卡片不显示

  1. 确认 name包名 meow-notify(不是路径/URL)。
  2. 确认包在 $DSH_HOME/profiles/node_modules/meow-notify/,且含 package.json(带 dsh.client 声明和 exports["./client"])。
  3. 确认已打平台补丁:运行 node setup.mjs 后重启 DSH——settings.describe 必须返回 meow-notify namespace。可手动验证:POST /api/settings.describe(body {"type":"client-request","rpcId":"<uuid>","method":"settings.describe","payload":{}}),看 namespaces 里有没有 meow-notify
  4. 刷新浏览器页面(卡片在前端启动时加载);还不行就重启 DSH。
  5. 验证发现链路:浏览器打开 http://127.0.0.1:3080/plugins/meow-notify/client.js 应返回 200(内容是 JS 而不是 404)。

Q3:推送时有时无 大概率是 MeoW 每分钟 3 条限流(PUSH-OK 但手机没收到属正常现象)。处理:调大 turnEndMinIntervalMs;或 includeChildren: false 减少来源。

Q4:自动连跑(goal)时只收到第一条 这正是节流在工作:每 25 秒最多 1 条完成推送,其余记 SKIP-THROTTLE。嫌少调小间隔,嫌吵调大。

Q5:改了 nickname/配置没生效 GUI 保存后等 1~2 秒(热生效),手机会收到一条新「插件已加载」。没收到就重启 DSH。注意:GUI 写的值进 settings.yaml(user 层),优先级高于 cordis.patch.yml 的 config(base 层)。

Q6:approval/asked 什么时候触发? 任何 DSH 弹出授权确认的时刻:文件写入工作区之外、命令需要更高权限、危险操作确认等。这是最不该错过的通知,所以它不被节流。

Q7:能在不开 MeoW App 的情况下用吗? 不能。MeoW 是推送的接收端(设备以 nickname 注册)。换用其他推送渠道(如 Server酱、Bark)只需改 base 并按其 API 格式改 index.js 里的 push() 函数。


10. 目录结构与开发

meow-notify/
├── index.js        ← host 端(v8):settings 注册 + 推送逻辑
├── client.js       ← client 端:GUI 配置卡片(__ModuleLoader__.load 格式)
├── setup.mjs       ← 安装补丁脚本(把 meow-notify 加入 DSH 的 Web 设置允许列表)
├── package.json    ← 双端声明(exports["./client"] + dsh.client 元数据)
└── README.md       ← 本文档

双端机制速览(给想改代码的人):

文件运行环境职责
index.jsNode(DSH 进程)apply(ctx, config):注册 settings namespace「meow-notify」+ 监听 session/event 推送
client.js浏览器apply(ctx):注册 settings.plugin.item 卡片,绑定 settingsScope
install.mjs命令行一键安装/卸载(bin: meow-notify
setup.mjs命令行仅平台补丁(安装脚本已内含,单独提供作兜底)

关键约定:

  • package.jsonexports["./client"] 指向浏览器 bundle(client.js),dsh.client.platform 必须为 "web"dsh.client.inject 列出 client 端依赖的服务模块(@deepseek-ai/dsh-client-connection 等)。
  • client 端 bundle 以 window.__ModuleLoader__.load({ id, factory }) 格式编写,factoryrequire 只能使用 web 前端的静态模块表(react、@deepseek-ai/dsh-client-runtime 等)与 dsh.client.inject 注入的模块,不能 import 其他 npm 包。
  • host 端用 installSettingsSection(ctx, NS, Config, config, hooks)(来自 @deepseek-ai/dsh-settings)把配置挂到 settings 域;Config 是 schemastery schema,GUI 卡片与配置校验共用同一份定义。
  • 配置合并顺序:schema 默认值 ← patch config(base)← settings.yaml(user)。GUI 只写 user 层。

11. 发布到 npm(维护者)

插件已配置为可直接发布的 npm 包(bin + files 清单就绪)。发布步骤:

# 1. 登录 npm(首次)
npm login

# 2. 检查包内容(应只有 6 个文件:README、client.js、index.js、install.mjs、package.json、setup.mjs)
npm pack --dry-run

# 3. 发布
npm publish

# 4. 以后升级代码后
npm version patch   # 或 minor / major
npm publish

发布注意事项:

  • 不要声明 dependencies/peerDependencies 指向 @deepseek-ai/* 的 rc 包——它们在公共 npm registry 不可解析(曾导致 ERESOLVE 安装失败)。这些依赖由 DSH 环境自身提供(profile 的 flat fallback),插件作为 DSH 插件从不独立运行。
  • install.mjs 已加 #!/usr/bin/env node shebang,npm 生成的 meow-notify 命令可直接执行。
  • 平台补丁(WEB_SETTINGS_NAMESPACES)是 DSH 当前版本的硬限制;若未来 DSH 开放插件自行暴露 settings,安装脚本的补丁步骤会自动变为 no-op(检测到已含则跳过),插件代码无需改动。
  • 升级插件代码(index.js/client.js)后,已安装用户重跑 meow-notify install(会重新复制文件)+ 重启 DSH 即可更新。