Bundle
dsh-plugin-night-dog
A cute DeepSeek mascot dog named 夜官 that lives inside the DSH web GUI: it floats in the corner, reacts to the harness, and adapts to the active theme.
- Source
- zzhi191
- License
- MIT
- Updated
- Updated 6 days ago
Readme
# dsh-plugin-night-dog
一只住在 DSH Web 界面角落里的**土黄色小狗**,名字叫 **夜官** 🐕。
它是 **纯客户端插件**:不做任何宿主侧工作、不碰网络、不访问模型。所有颜色都取自 DSH 实时主题令牌(`--dsw-*`,主体用琥珀色系),因此会自动跟随用户当前皮肤(浅色/深色/任何第三方主题)。
## 造型
正面坐姿小狗,按真实犬类解剖绘制:**突出的吻部**(奶油色口鼻伸出头部下方)、**狗鼻子 + 人中线**、**胡须点**、**下垂的长耳朵**、**右眼眼罩斑块**(比格犬风)、**眉弓**、**可见的前腿和爪子**、**卷起的尾巴**。
## 功能
| 交互 / 状态 | 效果 |
| --- | --- |
| 点击夜官 | 开心地蹦一下 + 吐舌头 + 冒泡(**左键绝不会隐藏它**) |
| 按住拖动 | **跟手 1:1 跟随鼠标**,移动到任意位置(记住位置,刷新后还在;窗口级监听 + 坐标守卫,杜绝跳变) |
| **双击**夜官 | **复位位置**(回到右下角默认位置) |
| 右键(macOS 双指点按/control+点击)夜官 | 隐藏到右下角小圆点(**仅本次会话**,刷新页面即召唤回来) |
| 点击小圆点 | 唤醒夜官 |
| 悬停夜官 | 头顶浮现名字「夜官」 |
| 空闲时 | 缓慢呼吸、眨眼、**摇尾巴**、偶尔吐泡泡 |
**周期性自动动作**(全部只从空闲态触发,互不打断,也不会让自己忘记睡觉):
| 动作 | 节奏 | 表现 |
| --- | --- | --- |
| 张嘴吐舌 | ~9s | 张大嘴哈气 + 舌头伸出 + 眯眼笑 + 尾巴狂摇 |
| 双脚站立 | ~26s | 站立姿势 SVG:身体竖直、前爪作揖、弹跳入场 |
| 歪头 | ~32s | 歪着脑袋卖萌,微微左右晃 |
| 站起来走动 | ~52s | 站立姿势 **左右踱步**(前爪交替迈步 + 身体起伏),原地走出一个小来回 |
| 打哈欠 | ~42s | 大张嘴 + 眯眼,一副困困的样子 |
| 凶叫 | ~45s | 怒眉 + 怒视 + 龇牙 + 抖动 +「汪!」气泡 |
| 追尾巴转圈 | ~60s | 原地转一整圈 |
| 委屈呜咽 | ~78s | 水汪汪的狗狗眼 + 撇嘴 |
| 其它状态 | 效果 |
| --- | --- |
| 长时间无操作(20s) | **趴下睡觉**:侧卧、头枕在前爪上、闭眼、打呼噜(冒出 Zzz)、身体随呼吸轻轻起伏 |
| 连接重置时 | 吓一跳(X 眼 + 抖动) |
| 执行斜杠命令时 | 开心庆祝(眯眼 + 吐舌头) |
> 注意:隐藏状态不持久化。右键隐藏后,点击右下角呼吸光晕的小圆点,或直接刷新页面,夜官都会回来;重新启动 DSH 也会恢复显示。
> 位置持久化带版本号和视口校验(`dsh.night-dog.state.v6`):任何越界/损坏的位置数据都会被丢弃,夜官始终从右下角开始。
> 注意:隐藏状态不持久化。右键隐藏后,点击右下角呼吸光晕的小圆点,或直接刷新页面,夜官都会回来;重新启动 DSH 也会恢复显示。
> 位置持久化带版本号和视口校验(`dsh.night-dog.state.v6`):任何越界/损坏的位置数据都会被丢弃,夜官始终从右下角开始。
情绪状态机:`idle → thinking / tool / error / cheer / sleep → idle`(`thinking` / `tool` 状态已实现动画,等待下一步接上真实 agent 信号触发)。
## 它在 DSH 里是怎么工作的
DSH 的客户端插件体系(已对照源码验证):
1. 插件是一个 **npm 包**,`package.json` 声明:
- `dsh.client.platform: "web"` —— 告诉 web 前端这是浏览器侧插件;
- `exports["./client"]` —— 指向浏览器 bundle,webserver 把它服务为 `/plugins/dsh-plugin-night-dog/client.js`;
- `dsh.bundle.patch` —— 指向一个 YAML overlay 补丁(`cordis.patch.yml`),把插件行插入当前 Profile。
2. `cordis.patch.yml` 的 `name` **必须等于 npm 包名**:加载器以 `entry.options.name` 为键做增量扫描,解析 package.json → `dsh.client` → `exports["./client"]`。
3. 浏览器端 bundle 是 `window.__ModuleLoader__.load({ id, factory })` 格式(与所有官方插件一致),`factory` 里的 `require("react")` 由启动图物化解析,**无需打包器、无需 JSX**。
4. UI 注册进 `shell.overlay` 槽位(root 级 list 槽,官方文档指定给浮层/提示用),通过 `ctx.get("slots")` + `slots.inject` + `slots.register` 挂载,生命周期由 `ctx.effect` 的 disposer 管理。
## 目录结构
```
dsh-plugin-night-dog/
├── package.json # 插件契约(dsh.client / dsh.bundle.patch / exports)
├── cordis.patch.yml # Profile overlay:插入 night-dog 行
├── lib/
│ ├── index.js # 宿主侧入口(v0.1 为空操作,仅为让加载器可激活)
│ └── client.js # 浏览器 bundle(由脚本生成,勿手改)
├── src/
│ └── client-source.cjs # 桌宠源码(唯一真源,CommonJS 便于直接嵌入)
└── scripts/
├── build-client.mjs # 把 src 包装成 __ModuleLoader__ 格式的 lib/client.js
└── smoke-test.mjs # 零依赖冒烟测试:包契约 + patch + bundle 信封 + apply 导出
```
## 本地开发循环
```bash
# 改代码:编辑 src/client-source.cjs
# 重新生成 bundle 并跑冒烟测试
node scripts/build-client.mjs && node scripts/smoke-test.mjs
```
把包装进你自己的 DSH(任选其一):
- **社区市场**:发布到 npm 并上架目录后,在 DSH 设置 → 插件市场里一键安装(见下);
- **DSH CLI**:`dsh profile plugin add dsh-plugin-night-dog`(等价路径);
- **手动**:在 Profile 的 node_modules 里 `pnpm add dsh-plugin-night-dog`,并把 `cordis.patch.yml` 的 insert 行合入 Profile 的 `cordis.patch.yml`,重启。
> 开发期改 bundle 后,web 前端通过 bundle 内容哈希(`?rev=`)感知变化,配合 `pnpm run dev:web` 的热更可免刷新迭代;正式包则重新 `npm publish`。
## 发布到插件市场
### 1. 发布到 npm
```bash
npm login
npm version patch && npm publish
```
市场安装时只接受 npm 官方 `latest` 的**精确稳定版本**,并校验 `dsh.bundle.patch` 是合法、安全的相对路径。包名不能是 `dsh-plugin-desktop` 或 `dsh-community-market`。
### 2. 上架目录(二选一)
**A. 提交到合作目录**:DSH 内置了 DSH 1024Store(deepseek1024.com)与 dsh-marketplace(qilewl.net)两个合作提供方,向它们提交收录申请(各自有审核流程)。
**B. 自建标准目录源(零门槛,自主可控)**:目录契约(v1)明确允许任何个人/社区发布符合规范的来源,用户添加 manifest URL 即可使用。最小实现 = 一个静态 JSON endpoint,例如:
```json
// https://your-domain.example/catalog-source.json
{
"manifestVersion": "1.0.0",
"providerId": "org.example.nightdog-catalog",
"name": "Night Dog Catalog",
"transport": {
"kind": "https-json",
"endpoint": "https://your-domain.example/v1/plugins",
"method": "GET"
},
"query": { "supported": ["q", "category", "cursor", "limit"], "defaultLimit": 50, "maxLimit": 50, "sorts": [] }
}
```
```json
// https://your-domain.example/v1/plugins?limit=50
{
"schemaVersion": "1.0.0",
"generatedAt": "2026-01-01T00:00:00Z",
"revision": "2026-01-01T00:00:00Z",
"items": [
{
"id": "night-dog",
"name": "dsh-plugin-night-dog",
"displayName": "Night Dog 夜官",
"summary": "A cute tan DeepSeek dog named 夜官 that lives in the corner of the DSH GUI.",
"latestVersion": "0.1.0",
"license": "MIT",
"categories": ["fun"],
"keywords": ["pet", "dog"],
"package": { "registry": "npm", "name": "dsh-plugin-night-dog" },
"publisher": { "name": "Your Name", "url": "https://github.com/your-name" },
"media": { "icon": { "url": "https://your-domain.example/dog.png", "alt": "Night Dog icon" } }
}
],
"page": { "total": 1 }
}
```
用户在 DSH 设置 → 插件市场 → 来源 里添加 `https://your-domain.example/catalog-source.json` 即可浏览、一键安装你的插件。
## 路线图
- [ ] **agent 状态感知**:注册一个会话级"传感器"组件(如 `conversation.chat.turnTail`),读取会话快照/投影,把"思考中 / 正在调工具 / 报错 / 完成"转发给桌宠——真正让鲸鱼与你一起工作
- [ ] **皮肤联动包**:同名主题包(`--dsw-*` 令牌),鲸鱼外观随皮肤整体换装
- [ ] **进化系统**:与 goal/job 数据联动,完成任务解锁新形态(帽子、围巾、颜色)
- [ ] 音效(默认关闭,可配置)
- [ ] 设置项:注册 `settings.general.item` 做显示/隐藏、尺寸开关
## 安全与边界
- 纯客户端插件:无宿主执行、无网络、无模型访问,符合 DSH 插件安全模型
- 所有副作用(事件监听、定时器、localStorage)都在 `ctx.effect` disposer 内,卸载/更新可完全回收
- 不依赖任何未声明服务(`slots` 用 `ctx.get` 可选获取)
Install
dsh plugin --profile web add github:zzhi191/dsh-plugin-night-dog#fcf878ae29bc255873999b46194c1de24cb62a8a
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install dsh-plugin-night-dog from the hub
- This package builds from source on install. pnpm will ask you to allow its build script — that is permission to run the package’s code on your machine, outside the agent sandbox. Only allow sources you trust.