dsh-meep(DeepSeek 桌宠)

August 14, 2026 · View on GitHub

meep 是一种鸟类的叫声,与 deep 发音相似——正如这只桌宠:大多数时候安静地待在 桌面角落,几乎不打扰你;只有当 DeepSeek Harness 里有值得注意的事(任务完成、出错、 需要你处理)时,它才会用音效和动画变化提醒你。

dsh-meep 介绍

dsh-meep 是一只陪伴 DeepSeek Harness(dsh)的桌面小宠物,独立进程运行,不依赖浏览器

  • 安静:任务栏隐藏、默认置顶、默认不走动、表情平缓循环——你可以专心干别的事
  • 只在关键时刻提醒:工作完成 / 出错 / 需要你处理时,才播放音效并切换动画
  • 一键切到网页版:双击桌宠即可快速打开 dsh 网页界面,出现事件时第一时间处理
  • 皮肤化:便签、右键菜单、动画(gif/图片)、前后景、气泡、音效全部由皮肤配置驱动

一、运行方式

Windows 桌面                               WSL2(Linux)
┌──────────────────────────┐              ┌─────────────────────────────┐
│ dsh-meep(Electron 桌宠) │ 直连 127.0.0.1 │ dsh web(127.0.0.1:3080)   │
│  - 透明置顶小窗(任务栏隐藏)│ ----------- >  │ (Windows 经 WSL2 localhost  │
│  - 托盘图标 + 右键菜单    │  HTTP/WS 无   │  转发可达,无需任何配置)      │
│  - 点击弹出便签文本框     │  Origin 头    │                             │
└──────────────────────────┘              └─────────────────────────────┘
  • dsh 与桌宠分开启动:dsh 在 WSL 里 pnpm dsh web;桌宠在 Windows 上双击 windows/start-pet.bat(或 cd desktop && npm start)。两个进程互不依赖: 桌宠在 dsh 没启动时照常运行(显示"离线"),可一键请求启动 dsh。
  • 为什么能直连:dsh 的 /api 信任围栏要求 Origin 与 Host 一致——浏览器页面 跨源会被拒,但桌宠的请求全部由 Electron 主进程(Node) 发出,不带 Origin 头、Host 是回环地址,天然通过围栏,因此不需要代理。
  • 跨平台:Electron 原生支持 Windows / macOS / Linux(macOS 隐藏 Dock 图标, Linux 依窗口管理器支持 skipTaskbar)。dsh 也可以直接跑在 macOS/Linux 本机。

二、快速开始

:: Windows:双击即可(首次自动 npm install,需网络,约 100MB 的 Electron)
windows\start-pet.bat

:: 或手动:
cd desktop
npm install
npm start

macOS / Linux 同样 cd desktop && npm install && npm start

可选环境变量:DSH_PET_URL 指定 dsh 地址(默认 http://127.0.0.1:3080)。


三、使用

操作行为
单击桌宠弹出/收起便签(独立可移动、任务栏隐藏、右上角 [×] 关闭)
双击桌宠快速打开 dsh 网页版(出现事件时最快切过去处理)
按住拖拽移动桌宠位置(便签同样可整张拖动)
右键自绘皮肤菜单:打开网页、音效/置顶/走动开关、大小、重启服务、调试、退出
右键菜单外点击 / Esc关闭菜单
单击托盘图标 / 双击托盘图标打开 dsh 网页版

便签(信息文本框)

点击桌宠弹出的便签:

  • 首要内容:最近事件 —— 服务器连接/断开、[启动] 开始工作、[完成]/[出错]/[等你] 等, 网页内的工作启动/停止会带上会话名称;消息完整展示不截断。
  • 次要内容:状态与个数 —— 运行中会话数、后台任务数、等你数 + 桌宠当前状态。
  • 底部设置条 —— 只保留:大小调整(−/+)、皮肤切换、退出(其余设置都在右键菜单)。

行为约定

  • 默认安静:任务栏隐藏、窗口置顶(均可在便签/右键菜单调整);默认不走动 (非拖拽不随意移动);表情平缓、不镜像翻转、不弹无关气泡。
  • 事件才提醒:只有状态切换(完成/出错/需要你/启动)才播放对应音效与气泡。
  • 透明点击:桌宠本体/前景/后景可能是透明图——落在透明像素上不算点中桌宠, 且鼠标穿透(透明像素上的点击会透到后面的窗口/桌面)。
  • 便签层级:便签始终在桌宠之下,不会遮挡桌宠。

四、事件与状态

状态含义是否提醒
offlinedsh 未启动/连不上进入时气泡提示
sleeping待机(无任务,绝大部分时间)安静
working工作中(有会话/后台任务)安静(动画平缓轮换)
waking开始干活(空闲 -> 有任务)气泡/音效
done任务完成(短暂庆祝)音效 + 动画
error出错音效 + 动画
waiting需要你处理(审批/提问)音效 + 气泡
fatal连续出错阵亡音效,点一下复活
  • 事件出现时,双击桌宠(或托盘单击)即可快速打开 dsh 网页版去处理。
  • 事件记录会写进便签"最近事件",并持久化(userData/history.json)。

五、皮肤与动画自定义

皮肤 = pet/skins/<皮肤名>/skin.json,一个文件统管便签、菜单、动画、前后景、 气泡与音效(完整字段说明见 pet/skins/README.md)。

{
  "note": {   // 便签:背景图(可换)/文字配色/窗口尺寸
    "image": "images/note.png", "textColor": "#334155", ...
  },
  "menu": {   // 右键菜单:背景装饰(图或色)/文字配色
    "backgroundImage": "images/menu-bg.png", "textColor": "#1f2937", ...
  },
  "animation": {   // 动画子块(加权动画槽)
    "pack": "yuyi",             // 动画包名;null = 图片体系
    "mode": "gif-first",        // 图片选择的解析模式(gif-first | image)
    "foreground": "front.png",  // 前景(png/gif 均可)
    "background": "back.png",   // 后景(png/gif 均可)
    "effects": { "sleeping": "breathe", ... },   // 图片特效兜底
    "bubbles": {   // 每状态气泡(文字 + 是否弹出,每皮肤可定制)
      "offline": "找不到服务器…",
      "working": ["工作中…", "努力干活中…"],   // 数组 = 随机挑一个
      "waking": { "text": "开工啦!", "show": false },  // show:false = 不弹气泡
      ...
    },
    "states": {   // 每状态一个动画槽,槽内若干加权选择
      "working": [ { "gif": "yuyi.gif", "weight": 2 }, { "image": "潜水", "weight": 1 } ],
      "sleeping": [ { "gif": "yuyi.gif" } ],
      "offline":  [ { "gif": "yuyi.gif" } ],
      "done":     [ { "gif": "yuyi-loud.gif", "loop": 3, "sound": "yuyi-loud.mp3" } ],
      ...
    }
  }
}

动画槽模型:每个状态一个"动画槽",槽内是若干加权选择weight 控制频率, 主状态定时按权重重新挑选)。每个选择可以是:

类型写法说明
gif{ "gif": "a.gif", "loop": n, "speed": x, "durationMs": ms, "sound": "s", "weight": w }loop 播 n 次后结束;durationMs 循环到超时;主状态无需这两项(无限播放)
图片{ "image": "表情key或文件", "effect": "breathe", "sound": "s", "weight": w }表情 key 走转换;effect 仅 image 体系生效
{ "none": true, "weight": w }小状态可无动画无音效

内置皮肤:default(表情体系示例)、meepyuyi(gif 动画包示例)、simple (image 体系示例)。换肤:便签底部"皮肤"下拉,或改 userData/settings.jsonskin 字段。

皮肤现状defaultsimple 目前作为测试皮肤,效果不佳(素材与动画 未打磨);meepyuyi 是主要演示皮肤。后期会对现有皮肤进行功能优化。

欢迎贡献新皮肤:按上文方式做好 pet/skins/<名字>/ 后,把 skin.json 与 素材提交到本仓库(或 PR),大家都能用上你的皮肤 🎨


六、扩展

1. 新表情系列(零代码)

python3 tools/build-manifest.py --source "新表情目录" --pack 表情包名 --out pet/expressions

图片复制到 pet/expressions/src/<表情包名>/,manifest 记录 pack 字段; 然后在皮肤 animation.states 对应状态槽里引用({image: key})。

2. 动画 gif 包

建目录 pet/expressions/gif/<包名>/,放入各状态 gif/图片/音效,在皮肤 animation.states 里引用。tools/jpg2gif.ps1 可把 jpg 预转成动画 gif。

3. 新皮肤

复制一个现有皮肤为 pet/skins/<名字>,改 skin.json、换图片,再把名字加进 pet/js/config.jsskins 列表。

4. 新状态 / 自定义事件

config.jsstates 里加一项,在皮肤 animation.states 加对应动画槽, 然后在 state-machine.js 事件处理里加触发规则(或 config.custom 钩子从外部触发)。


七、目录结构

deepseek-pet/
├── desktop/                  # Electron 桌面程序(主产品)
│   ├── main.mjs              # 主进程:窗口/托盘/自定义协议/IPC/皮肤菜单窗口
│   ├── preload.cjs           # 安全桥(contextBridge)
│   ├── pet-core.mjs          # 核心编排:直连 dsh + 状态机 + 快照(Node 可测)
│   ├── settings.mjs          # 设置读写(userData/settings.json,含 skin)
│   ├── package.json          # electron + electron-builder 配置
│   └── app/                  # 渲染层:桌宠窗口 / 便签 / 自绘右键菜单
├── pet/                      # 共享素材与核心逻辑
│   ├── js/
│   │   ├── config.js         # 状态机/表情/音效配置
│   │   ├── skin.js           # 皮肤加载
│   │   ├── skin-anim.js      # 动画槽选择逻辑(归一化/加权挑选,纯函数可测)
│   │   ├── gif-encoder.js    # 纯 JS GIF89a 编码器(量化/抠底/动画合成)
│   │   ├── gif-utils.js      # GIF 字节补丁(NETSCAPE 循环次数 / GCE 帧延迟)
│   │   ├── expressions.js    # 表情解析(gif/image 双体系)
│   │   ├── dsh-client.js     # dsh 协议客户端(WS 双流 + SSE 降级 + RPC + 重连)
│   │   └── state-machine.js  # 状态机(纯逻辑,可注入时钟测试,含事件记录)
│   ├── skins/                # 皮肤目录(default / meep / simple / yuyi)
│   ├── expressions/
│   │   ├── manifest.json     # 表情清单(含 pack 字段)
│   │   ├── src/<表情包>/*.jpg # 表情素材
│   │   └── gif/<动画包>/…    # 动画 gif 包(含前后景/音效)
│   └── assets/sounds/        # 全局提示音
├── assets/icon.png           # 应用/托盘图标
├── windows/start-pet.bat     # Windows 一键启动
├── tools/                    # 构建与调试工具
└── tests/                    # Node 单元测试 + mock dsh 服务器

八、测试

cd deepseek-pet
node --test tests/run-tests.mjs tests/desktop-core.test.mjs

40 项测试:GIF 编码往返与字节补丁(loop/speed/时长)、动画槽选择(加权挑选/ 气泡配置/旧格式兼容)、状态机全场景(三大主状态、事件记录与会话标题、后台任务 与会话隔离)、协议客户端(WS/SSE/重连)、PetCore 编排、设置读写。测试不依赖 dsh 本体(mock 服务器按当前 dsh 协议模拟)。

调试工具(可选):

  • node tools/probe-dsh.mjs [url]:用桌宠自己的 DshClient 直连 dsh,验证协议。
  • node tools/cdp-drive.mjs:桌宠以 --remote-debugging-port=9222 启动后, 自动验证核心交互(默认场景 / 便签 / 皮肤菜单 / 皮肤切换)。