dsh-kun-like-pet (kunpet-dsh)
yang-wudi/dsh-kun-like-pet/packages/kunpet-dsh
A Kun-Like desktop pet living in the corner of the DSH web UI; switches animations with agent state and plays a voice line on task completion.
설치
dsh plugin --profile web add github:yang-wudi/dsh-kun-like-pet이 플러그인은 저장소의 packages/kunpet-dsh 하위 디렉터리에 있습니다.
README
🐤 Kun Like 桌宠
DeepSeek Harness(DSH)桌面宠物插件 —— 一只住在 Web 界面右下角的小坤宠。 它会盯着 Agent 干活:你搓代码时它努力搬砖,你思考时它托腮,等你回复时它翘首以盼,任务完成时它挥手跳跃、大喊 「你干嘛~哎哟」 🏀


✨ 特性
- 9 种状态动画:完全沿用 Codex 桌宠精灵图契约(8 列 × 9 行、每格 192×208),素材零重绘
- 实时感知 Agent 状态:轮询
agents服务感知每个 Agent 的 running/idle 状态,配合tools/execute、approval/request、agent/request-error事件推导工作 / 思考 / 等待 / 出错 / 空闲五种模式 - 任务完成全机可闻:宿主进程用系统命令播放「你干嘛~哎哟」,任何窗口、任何会话完成任务都会响,与浏览器静音无关
- 可互动:拖动桌宠到处跑(跑步动画方向跟随),点击它会挥手打招呼
- 内置调试工具:
kun_pet_debug可随时查看状态机内部计数与轮询健康度
🙏 来源与致谢
本仓库是 liyupi/dsh-kun-like-pet(原作者 liyupi)的派生仓库:原项目以 DSH 动态插件(cordis_define)形式开发迭代(v1–v5)。本仓库在此基础上:
- 将其升级为正式 profile 插件包(
packages/kunpet-dsh):重启仍在、所有会话共享,无需 cordis 会话与授权; - 修复 Windows 完成音播放(
System.Media.SoundPlayer不支持 MP3,改用内置 MCI/winmm); - 修正素材路径并使其自包含,发布到 npm(
kunpet-dsh)。
遵循 MIT License,代码版权归原作者 liyupi,派生改动版权归本仓库维护者(见 LICENSE 末尾的附加声明)。
🎮 状态 → 动作映射
| Agent 工作状态 | 桌宠动作 | 气泡文案 |
|---|---|---|
| 工作中(有工具在执行) | 专注干活(第 7 行) | 努力工作中… |
| 回合中但空闲 | 思考循环(第 8 行) | 思考中… |
| 等待用户回复 / 审批 | 期待等待(第 6 行) | 在等你回复哦~ |
| 出错 | 难过低落(第 5 行) | 呜…出错了 (._.) |
| 空闲 | 呼吸待机(第 0 行) | 休息中~ 有事叫我 |
| 任务完成 | 挥手 + 跳跃庆祝(第 3/4 行交替)+ 系统音「你干嘛~哎哟」 | 完成啦!你干嘛~哎哟 |
| 拖动 | 跑步(第 1/2 行,方向跟随) | 呜哇~ 别拽我! |
| 点击 | 挥手(2.4s 反应) | 诶嘿~ |
🚀 安装
方式一:DSH 动态插件(已实测,会话级)
桌宠以 DSH 动态插件 形式开发并运行验证(cordis_define)。在 DSH 会话里让 Agent 执行,或手动调用 cordis_define 工具:
-
克隆本仓库:
git clone https://github.com/Yang-wudi/dsh-kun-like-pet.git -
修改
src/host.js顶部CONFIG中的素材路径:const CONFIG = { spritePath: '/你的/路径/dsh-kun-like-pet/assets/spritesheet.webp', voicePath: '/你的/路径/dsh-kun-like-pet/assets/voice.mp3', // macOS 默认用 afplay;Windows / Linux 请改成对应播放命令 playCommand: (path) => "afplay '" + path.replace(/'/g, "'\\''") + "'", } -
生成一键安装载荷并粘贴给
cordis_define工具:node scripts/build-kunpet-package.mjs - # 输出 JSON 载荷载荷结构(
kind: "new"创建新插件;后续更新用kind: "existing"+pluginId):{ "plugin": { "kind": "new", "idPrefix": "kunpet" }, "name": "Kun Like 桌宠", "purpose": "在 Web 界面右下角显示 Kun Like 桌宠,随 Agent 工作状态切换动作,任务完成时播放「你干嘛~哎哟」语音。", "code": { "host": "<src/host.js 内容>", "client": "<src/client.js 内容>" } } -
用
cordis_run激活,Web 界面右下角即出现桌宠。
方式三:正式 profile 插件包(推荐 ✅ 重启仍在、所有会话共享)
把桌宠做成 profile 插件 挂载到 web profile:DSH 重启后自动生效,每个会话页面右下角都有桌宠,任何会话完成任务都会响「你干嘛~哎哟」。无需 cordis 会话、无需授权。插件包自包含(素材内嵌 + 播放命令按平台自动选择),安装时无需改任何路径。
-
安装进 web profile(会写入
~/.dsh/profiles/web/package.json的 dependencies +dsh.profile.bundles):dsh plugin --profile web add -w <本仓库>/packages/kunpet-dsh(Windows 上跨盘符时不要用
file:前缀,直接传目录路径即可。) -
重启 DSH,桌宠即出现在所有页面右下角。
验证:curl http://127.0.0.1:3080/kun-pet/state 应返回 JSON(mode/spriteUrl/lastPlayError…);/kun-pet/spritesheet.webp 返回 image/webp。
卸载:dsh plugin --profile web remove kunpet-dsh,并从 ~/.dsh/profiles/web/package.json 的 dsh.profile.bundles 移除 kunpet-dsh,再重启。
调试:node packages/kunpet-dsh/scripts/mount-smoke.mjs 可在不重启的情况下验证插件能完整挂载(素材加载 + 路由 + 工具注册)。
📤 分享给其他人
插件包是自包含的(packages/kunpet-dsh/ 内含 lib/、client/、assets/),三种分享方式任选:
-
方式 A · GitHub 仓库:把本仓库推送到 GitHub,别人只需:
git clone <你的仓库地址> dsh plugin --profile web add -w <克隆路径>/packages/kunpet-dsh # 重启 DSH -
方式 B · npm(✅ 已发布,最省事):
kunpet-dsh已发布到 npm,别人一行安装:dsh plugin --profile web add kunpet-dsh # 重启 DSH(国内网络下 npm 默认走 npmmirror 镜像,npmjs 发布后几分钟内自动同步。)
-
方式 C · DSH 插件市场:配合 dshmarket 上架(npm 包已就绪,在市场注册即可),别人可以在 Web 界面里一键安装。
⚠️ 版权提醒:
assets/voice.mp3为含公众人物声音的梗语音片段、spritesheet.webp为粉丝二创像素形象,仅供个人学习交流。公开发布(npm/市场)等于分发这些素材,请先自行评估版权风险,或换成自己的素材(在 profile 的cordis.patch.yml给 kunpet-dsh 行加config.spritePath/config.voicePath覆盖,或改packages/kunpet-dsh/lib/index.js的DEFAULTS)。
方式二:直接预览动画(无需 DSH)
打开 demo/index.html(建议起个静态服务器,如 npx serve . 或 python3 -m http.server),即可查看全部 9 种动画并拖动互动。
⚙️ 配置
- 动态插件(
src/host.js顶部CONFIG)与 profile 插件(packages/kunpet-dsh/lib/index.js顶部DEFAULTS)各有一份配置,结构相同:
| 配置 | 默认值 | 说明 |
|---|---|---|
spritePath | profile 插件:包内 assets/spritesheet.webp(自包含) | 精灵图路径 |
voicePath | profile 插件:包内 assets/voice.mp3(自包含) | 完成音路径 |
playCommand | 按平台自动选择(macOS afplay;Linux ffplay;Windows 内置 MCI/winmm 播 MP3) | 系统级播放命令(Windows 注意:System.Media.SoundPlayer 只支持 WAV 不支持 MP3) |
pollMs | 500 | Agent 状态轮询间隔 |
celebrateMs | 4800 | 庆祝动画时长 |
failedMs | 2600 | 失败动画时长 |
📁 项目结构
dsh-kun-like-pet/
├── src/
│ ├── host.js # 动态插件 Host 半:状态机、素材路由、系统音、pet-state RPC、kun_pet_debug 工具
│ └── client.js # 动态插件 Client 半:shell.overlay 注入、9 种动画渲染、拖动/点击互动
├── packages/kunpet-dsh/ # 正式 profile 插件包(重启仍在、所有会话共享)
│ ├── lib/index.js # Host 半:素材加载、/kun-pet/* 路由、状态机、系统音、kun_pet_debug
│ ├── client/client.js # Client 半:手写 lazy-CJS 协议,渲染桌宠(零构建)
│ ├── cordis.patch.yml # bundle patch:insert { id: kun-pet, name: kunpet-dsh }
│ └── scripts/mount-smoke.mjs # 不重启即可验证挂载的冒烟脚本
├── assets/
│ ├── spritesheet.webp # 8×9 精灵图(1536×1872,Codex 桌宠契约)
│ └── voice.mp3 # 「你干嘛~哎哟」完成音
├── demo/index.html # 独立动画演示页(无需 DSH)
├── docs/
│ ├── SPRITESHEET-CONTRACT.md # 精灵图契约与动画行速查
│ └── screenshots…
├── scripts/
│ ├── build-kunpet-package.mjs # 生成 cordis_define 安装载荷
│ └── validate.mjs # 仓库完整性校验
├── CHANGELOG.md # v1 → v6 迭代记录(含事件隔离根因分析、profile 插件化)
└── kunpet.package.json # 由 build 脚本生成的一键安装载荷(动态插件用)
校验:node scripts/validate.mjs
❓ 常见问题
为什么桌宠只在某一个窗口里? 动态插件是会话级绑定:桌宠界面只注入到激活它的会话页面。完成音自 v5 起由宿主进程系统级播放,任何窗口/会话完成任务本机都会响。要让桌宠形象出现在所有窗口、且重启仍在,用方式三安装正式 profile 插件包即可。
为什么不用事件监听而要轮询?
开发过程中用 internal/dispatch 探针实证发现:部分部署里 agent/status、agent/turn-stopping 等 Agent 状态事件不流经动态插件所在总线(831 次事件观测中 status 类事件为 0),事件监听永远等不到「任务完成」。轮询 agents 服务是最可靠的跨部署方案。详见 CHANGELOG v3/v4。
⚠️ 素材版权声明
assets/voice.mp3为网络公开的二创梗语音片段(含公众人物声音),版权归原作者所有,仅供个人学习交流使用,请勿用于商业用途;如需商用请自行替换为无版权素材。assets/spritesheet.webp为粉丝二创像素形象,沿用 Codex 桌宠素材契约制作。- 若您是权利人且不希望相关内容被展示,请联系删除。
📄 License
代码以 MIT License 开源。素材文件(assets/)仅限个人学习交流,遵循上一条声明。