
dsh-columbina-pet
《原神》哥伦比娅 2D live 桌宠 · DeepSeek Harness 插件
四套形象 · 76 句三语原声台词 · 天气播报 · 真实物理 · 表情包时刻
作者:六硬币的好活 · B 站 uid 1947282109 | GitHub @Yuanawaqwq
这是什么
把《原神》里愚人众第三席「少女」哥伦比娅放进 DeepSeek Harness 的桌面:她会浮在窗口最上层,被拖动时有真实的物理摆动,会按时间与场景轻声说话,会用官方原声念出台词,也会播报今天的天气。
本仓库是 dsh-pet(MIT)的2D 专用分支:保留并深化了 2D live 形象、语音台词、菜单与物理,移除了尚未完善的上游 3D 形象切换,补上了天气播报与开源所需的文档、占位与版权说明。
英文简介:A 2D live desktop pet of Columbina (Genshin Impact) for DeepSeek Harness — four sprite sets, 76 official voice lines in zh/ja/en with synced subtitles, weather reports, and real physics. 3D mode from upstream has been removed on purpose. See NOTICE.md for asset licensing.
关于后续
先把期待放在明面上:
- 功能面基本到这儿了。 后面不会再往里堆新功能,主要做两件事:跟住 DeepSeek Harness 的新版本(接口一变就修,兼容声明也会跟着更新),以及把现有的东西继续磨顺——性能、稳定性、交互上的小毛刺。
- 有想要的功能,欢迎来说。 B 站私信 六硬币的好活(uid 1947282109);或者你自己动手,项目是 MIT 的,改完想合回来也欢迎(提 PR 就行,不熟流程也可以先把改动贴给我看)。
- 遇到 bug,一定要来喊我修。 这条优先级最高,别自己忍着,也别自己 hack。报的时候尽量带上:DSH 版本 + 插件版本(见下面「健康检查」的
version一栏)、现象与复现步骤、F12 控制台或日志里带[dsh-pet]的行。
预览
| 桌面模式 | 右键菜单 |
|---|---|
![]() |
![]() |
| 四套 2D live 形象 | 设置面板 |
|---|---|
![]() |
![]() |
更新公告
逐版本明细见 CHANGELOG.md;可下载的包见 Releases。每个版本都会在这里留一段,说明改了什么、要不要动设置。
1.2.2 · 2026-11-09
这一版不改宠物的动作、声音和脾气,改的是「以后不容易坏」的部分:测试、CI、兼容声明、安装说明。不需要动任何设置,升级后同样请完整退出 DSH 再打开。
- 测试进了仓库:以前那 93 条断言躺在临时目录里,只有写的时候记得怎么跑。现在 5 个用例(碎碎念字幕 19 / 字幕跟音频 15 / 请求体编码 19 / Range 24 / 跨站写 16)挪到
test/,npm test一条命令跑完,零依赖、不联网、自带假 DOM 与假时钟。 - 每次提交自动跑:新增 GitHub Actions,Node 22 与 24 各跑一遍语法检查与全部用例,坏了当场标红,不用再靠人记着。
- 兼容声明跟上新版 DSH:
dsh.compatibility补上0.2.2-rc.1;@deepseek-ai/*的 peer 依赖从^0.2.0-rc.1放宽到>=0.2.0-rc.1 <0.3.0——0.2.x 里的小版本升级不会再被标成不兼容。 - 安装时不容易误会:README 安装段直接写明「tarball 约 148 MB,第一次装要等几分钟,别中途取消」,免得以为卡死。
src/讲清了定位:新增src/README.md——发布产物是lib/、没有构建步骤;src/是半同步的参考源码,会和lib/漂移,判断真实行为请看lib/。- 遇到问题能自己查:README 新增「遇到问题怎么办」——版本/代码/语音包/Helper 四个数怎么对、每个症状先看哪一行、怎么修,附报 bug 要带的信息。顺手订正了配置路径(实际目录是
~/.dsh/columbina-pet/,旧dsh-pet会自动迁移一次)。 - 文档体检:README 通篇按当前实现重过了一遍——自定义镜像变量名(
DSH_PET_ELECTRON_MIRROR)、语音包镜像示例版本(v1.1.4)、右键菜单完整表(含音量 / 夜间勿扰 / 省电 / 素材自检 / 设置面板 / 待机动作 / 真实物理)、目录结构(test/、docs/screenshots/、切片音频)都对齐了;开头补上作者署名与联系方式。 - 素材与运行时行为都没动。
1.2.1 · 2026-10-31
一版以「修碎碎念字幕」为主的补丁。不需要动任何设置,升级后请完整退出 DSH 再打开。
- 长句字幕不再提前消失:碎碎念字幕比声音先没了。根因不在文案,而在时长拿不到——宿主素材接口不返回
accept-ranges,Chromium 对不能 seek 的 Ogg 会把audio.duration报成Infinity,旧逻辑据此退回固定的 3600 ms。现在字幕跟着音频的实际播放进度走(timeupdate续命),读多久就显示多久,念完立刻收。 - 字幕不再被裁掉:碎碎念字幕挪进挂在
body的独立浮层(原先寄生在.dsh-pet-root里,祖先一旦有transform/overflow: hidden就会把长句整块切走)。 - 拖动宠物时字幕跟着走:显示期间用
requestAnimationFrame逐帧同步浮层位置,甩飞、落地、贴边都跟得上。 - 碎碎念节奏恢复正常:设过间隔却发现十几分钟才念一句——计时器被任务状态连带重置,已修。
- 桌面端也能检查素材了:桌面「语音包与素材」面板补齐,一键数语音包 / 动作 / 表情,缺语音包原地重下,不用翻日志。
- 网页右键菜单向桌面看齐:菜单项、顺序、文案统一;网页端新增「真实物理:开 / 关」,设置面板里的分区顺序也一致了。
- 天气播报文案统一:温度一律带
℃,中 / 日 / 英句式各自本地化。 - 长句不再被下一句掐断:
webAutoVoice()在触发前先看上一句还在不在播——热身 / 间隔 / 手势补播 / 天气接话这些自动来源都会让路(控制台打[dsh-pet] 碎碎念让路 来源=…),只有你手动点桌宠或点「原声台词」才是强制换句。热身那句也改成每个页面会话只排一次。 - 气泡不再出现乱码 / 豆腐块:碎碎念气泡曾整串显示成菱形问号。根因是宿主接收请求体时把非 UTF-8 字节直接按 UTF-8 解码(Windows 控制台的 curl / PowerShell 会把中文按 GBK 发出来),替换字符
�就一路写进了气泡。现在请求体先严格 UTF-8、失败再按 GB18030 重解;含�、锟斤拷这类双重转换痕迹的文本一律不写进气泡。 - 语音文件支持 Range:素材接口现在回
accept-ranges并支持206/416,音频可以按需取字节,audio.duration能拿到真值(以前不返回accept-ranges,Chromium 对不能 seek 的 Ogg 报Infinity)。字幕仍保留timeupdate兜底,客户端两个版本都稳。 - 本地接口不再对任何网页敞开:此前 24 条路由全无来源校验,任意网页都能跨站 POST
/broadcast往气泡里塞字、/whisper烧 token。现在写请求若带sec-fetch-site: cross-site且Origin是别的 http(s) 站,直接403 cross-site-blocked;同源页面、file://的桌面 Helper、本机脚本(curl / node / python)照常。 - 切回网页模式后桌面 Helper 会退出:以前
desktopModeEverActive一旦为真就永不复位,切回web后还留着 3 个空转进程(约 178 MB、无窗口)。现在没有桌面宠物就不再拉起 Helper,切回桌面时自动重启。 - 语音包标记跟着版本走:
~/.dsh/columbina-pet/voice-pack.json的version之前停在 1.1.5(只在迁移那一次写),每次启动会按当前版本刷新。 - 素材没动(沿用 1.1.11 的原始 webm,约 147 MB),本版只改代码。
1.2.0 · 2026-10-31
开发期编号是
1.1.12,因为功能面到了次版本,正式发布更名 1.2.0(内容与 1.1.12 完全一致)。
- 待机动作可选:右键「待机动作」切 精选 / 当前形象全部动作 / 自己选;「自己选…」打开设置面板里带搜索框的勾选列表,桌面与网页同一套。精选池从 2 段扩到官方 9 / 去眼罩 12 / 睁眼 12 / 闭眼 10 段。
- 待机不再一顿一顿:带「待机」的片段此前被拉成 20 秒循环(2.4 秒的官方片段 ≈0.12×,折合 3.6 fps),现在统一 0.6×。
- 省电模式真的会停:旧实现只暂停
loop的视频,而待机是 one-shot 播放,所以什么都没停;现在鼠标 30 秒不动就暂停所有在播视频,并拦住宿主推来的新动作。 - 夜间勿扰 / 音量与静音 / 素材自检与一键修复 / 网页面板同步:见下面「功能介绍」。
- 余额查询:默认模型挂在 API Key 版服务商、而本机是账号登录时,不再报「缺少凭证 DEEPSEEK_API_KEY」,自动改查账号余额。
- 素材没动:沿用 1.1.11 的原始 webm(约 147 MB),本版没有做有损压缩;
scripts/shrink-webm.mjs留作可选工具。 /healthz能分辨「磁盘换了没重启」:新增activatedBuildSha256(激活那一刻算的 sha256,留在内存)与needsRestart(内存 sha ≠ 磁盘 sha 时为true)。同一版本号重打包时,光看buildSha256永远等于新盘,只有这组字段能看出内存里跑的是旧代码。- 启动时自报身份:每次启动把「这次跑的是哪个版本、哪份代码」写进
~/.dsh/columbina-pet/activation.json(activatedAt/activatedVersion/diskVersion/buildSha256/activatedBuildSha256/needsRestart),同时往宿主日志打一行[dsh-pet] activated <版本> build <sha8>。磁盘上已经是新版本、内存里跑的还是旧的时,needsRestart为true并补一条 warn——以后不用先猜/healthz怎么访问。 - 升级后需完整退出 DSH 再打开;设置项都带默认值,不需要手动迁移。
1.1.11 · 2026-10-30
/healthz增加activatedVersion/buildSha256:换包没重启一眼可见。ensure-voice增加 120 s 总预算 + 20 s 停滞检测(DSH_COLUMBINA_VOICE_STALL_MS可调)。- npm 包去掉
src/:条目 607 → 465,tarball 148.56 → 148.11 MB。 - 路由路径解码容错:GBK 百分号编码不再整条路由 500。
1.1.10 · 2026-10-30
- 修复网页端「全不选」曾把
lines写成[0](只念第一句):宿主一次性迁移 + 写入prefsRev: 2。 - 只影响网页模式面板;桌面端一直正常。
特性
- 四套 2D live 形象:
official(官方表情包)、nochoker(去眼罩)、open(带眼罩·睁眼)、closed(带眼罩·闭眼)。右键菜单「2D live 形象」即时切换,每套自带待机 / 点击 / 拖拽 / 事件动作树(共 246 个 webm)。 - 三语原声台词:76 句哥伦比娅官方语音,按中 / 日 / 英整理为 94 段切片。配音语言与字幕语言分开设置;有声音必有字幕,一句长台词会按播放进度分段换字幕。
- 按场景碎碎念:问候、午夜、安慰、感谢、提问、玩耍、友人、睡前、认真、俏皮十组场景池,按时间与近期出镜率抽签,不连续重复;开局前 12 秒保持安静。
- 工作气泡优先:正在向用户汇报时,桌宠不会抢走气泡;它的话结束后自动把气泡还给工作状态。
- 天气播报:菜单「天气 → 今天的天气」,先用气泡给出摘要(城市、天气、当前温度、今日温度区间),隔一拍再用原声台词接一句应景的话;断网时给一句兜底台词,不会卡死。
- 真实物理:拖拽甩出弧度、松手下落、落地回弹、窗口贴边停靠,参数全部可配。
- 菜单即设置:切换间隔、2D live 形象、语言(配音 / 字幕 / 菜单)、模型大小 0.5–3×、原声台词勾选、碎碎念开关,菜单本身也随语言切换。
- 时刻表情包:12 张心情图(好耶 / 抱抱 / 期待 / 出发 / 好吃 / 思考 / 睡觉 / 困了 / 贴贴 / 唱歌 / 谢幕 / 晚安),由台词标签与场景挑选。
- 音量与静音(1.2.0):右键「音量」五档 20–100 % 加一键静音,桌面与网页共用一套设置;改完立刻生效,不会掐断正在播的那一句。
- 夜间勿扰(1.2.0):设一个时段(默认 23:00–08:00),这段时间碎碎念自动闭嘴;手动点「原声台词」照常播。
- 素材自检与一键修复(1.2.0):设置面板「语音包与素材」点一下就数一遍语音切片 / 动作 / 表情,语音包缺了直接原地重下,不用再翻日志。
- 省电模式(1.2.0,默认关):闲着 30 秒把循环待机动图定格,鼠标一动立刻继续,长时间挂桌面更省 CPU。
- 待机动作可选(1.2.0):右键「待机动作」切精选 / 当前形象全部动作 / 自己选;「自己选」会打开设置面板里可搜索的勾选列表(去眼罩、带眼罩睁眼各 82 段,带眼罩闭眼 65 段,官方表情包 17 段),勾了哪几段就只轮播哪几段。
- 网页模式补平(1.2.0):网页端补齐夜间勿扰、省电模式与待机动作(设置面板里同样可搜索勾选),碎碎念时段、音量与静音和桌面共用一套设置。
- 天气城市名本地化(1.2.0):定位拿到的城市按字幕语言翻译,中文界面显示「广州」而不是「Guangzhou」;英文/日文界面保留本地拼写。
功能介绍
每一项都能从右键菜单或设置面板进去;下面写清「入口 / 怎么用 / 要注意什么」。
形象与动作(四套 2D live)
- 入口:右键「2D live 形象」。
official官方表情包、nochoker去眼罩、open带眼罩·睁眼、closed带眼罩·闭眼;四套共 246 段 webm,各自带待机 / 点击 / 拖拽 / 事件动作树。- 切换立即生效,设置会记住;官方那套是 640×360 的 VP9,另外三套是 500×500 的 VP8 + alpha。
语音与字幕(三语原声)
- 入口:右键「语言」→ 分别设置配音语言 / 字幕语言 / 菜单语言。
- 76 句官方语音整理成 94 段切片;一句长台词会按播放进度分段换字幕,有声音必有字幕。
- 「原声台词」里可以勾选只播哪几句(全选 / 全不选 / 逐句勾),设置落
prefs.json。
碎碎念
- 入口:右键「碎碎念设置」。
- 十组场景池(问候 / 午夜 / 安慰 / 感谢 / 提问 / 玩耍 / 友人 / 睡前 / 认真 / 俏皮),按当前时间与近期出镜率抽签,不连续重复。
- 间隔 60–180 秒可调(默认 90 秒);启动后前 12 秒保持安静(每个页面会话只排一次)。
- 字幕(1.2.1):碎碎念的字幕挂在
body上的独立浮层里,不会被子元素祖先的transform/overflow裁掉;宠物被拖动、甩飞时用requestAnimationFrame跟随;显示时长跟着音频的实际播放进度(timeupdate)走,念完立刻收,不再固定 3.6 秒。念的时候 F12 里会打[dsh-pet] 字幕跟音频 duration=…与[dsh-pet] 字幕收起(计划 …ms)两条日志,方便判断走的是哪条分支。
夜间勿扰(1.2.0)
- 入口:右键「夜间勿扰」。四档预设(22:00–07:00 / 23:00–08:00 / 00:00–09:00 / 01:00–10:00),支持跨零点。
- 只挡自动碎碎念;手动点「原声台词」照常播,不会被静音。
音量与一键静音(1.2.0)
- 入口:右键「音量」→ 静音开关 + 20 / 40 / 60 / 80 / 100 % 五档。
- 桌面与网页共用一套设置(同一个 localStorage 键),改完立刻生效,不会掐断正在播的那一句。
待机动作(1.2.0)
- 入口:右键「待机动作」→ 精选(推荐)/ 当前形象全部动作 / 自己选…
- 「自己选…」打开设置面板的可搜索勾选列表(去眼罩、带眼罩睁眼各 82 段,带眼罩闭眼 65 段,官方表情包 17 段);支持全选 / 全不选 / 还原精选,勾了立即生效。
- 精选池:官方 9 / 去眼罩 12 / 睁眼 12 / 闭眼 10 段,90 秒一轮。
省电模式(1.2.0,默认关)
- 入口:右键「省电模式」。
- 鼠标 30 秒不动暂停所有正在播的视频(含宿主推来的动作),移动/点击/窗口切回来立刻恢复。
天气播报
- 入口:右键「天气」→「今天的天气」(另有重新定位)。
- 先用气泡给摘要(城市 / 天气 / 当前温度 / 今日温度区间),隔一拍再用原声台词接一句;断网给兜底台词。
- 城市名按字幕语言本地化(1.2.0):中文界面显示「广州」而不是「Guangzhou」。
素材自检与一键修复(1.2.0 网页端 / 1.2.1 桌面端)
- 入口:设置面板「语音包与素材」→ 检查素材 / 一键修复(桌面右键菜单里也有这一项)。
- 宿主接口:
GET <prefix>/voice/health、POST <prefix>/voice/repair;返回语音切片 / 动作 / 表情的目录、数量与体积,语音包缺了直接原地重下。 - 桌面端的面板页面是
file://源,所以这两个接口响应带access-control-allow-origin: *(1.2.1)。
余额查询
- 入口:右键「查看余额」(可在配置里设成定时刷新)。
- 优先用当前默认模型对应的服务商;若是 API Key 版服务商但本机没有
DEEPSEEK_API_KEY,自动改查 DSH 账号余额(1.2.0 起),不会只甩一句「缺少凭证」。
网页模式
- DSH Web 界面里的宠物与桌面端共用同一份形象、台词、菜单结构;夜间勿扰 / 省电 / 待机动作 / 音量在网页端同样可设,设置面板里也能搜索勾选。
- 网页端改动同样需要完整重启 DSH 才生效。
桌宠物理
- 拖拽有惯性、松手下落、落地回弹、贴边停靠;参数在
assets/config.jsonc的physics里可调。 - 「真实物理:开 / 关」(1.2.1 网页端补齐):关掉后松手不再甩飞、不弹跳,直接落回地面;桌面与网页各自记住选择(网页键
columbina-physics-web-v1)。
多语言菜单
- 菜单与面板支持中文 / 日本語 / English,随「菜单语言」切换;新加的菜单项也带三语。
环境要求
| 项 | 要求 |
|---|---|
| DSH | 0.2.x(0.2.1-rc.2 / 0.2.2-rc.1 桌面版实测可用) |
| Node.js | ≥ 22.12 |
| 系统 | Windows / macOS / Linux |
| Electron | 43.3.0(首次运行自动下载,或手动 node scripts/ensure-electron.mjs) |
开发与测试
发布产物是
lib/,没有构建步骤:改行为直接改lib/index.js(宿主半)或lib/client.js(网页半)。src/是半同步的 TypeScript 参考,会和lib/漂移(碎碎念浮层、网页端真实物理、data-dsh-pet-subtitle宿主这些后加的只活在lib/里)。判断真实行为请看lib/,详见src/README.md。自检命令:
npm run check # node --check lib/index.js lib/client.js npm test # test/ 下全部用例:零依赖、纯内置模块、不联网用例都是自己搭的假 DOM / 假时钟 / 假音频(碎碎念 19、字幕跟音频 15、请求体编码 19、Range 24、跨站写 16,共 93 项断言),CI 在
.github/workflows/ci.yml里用 Node 22 与 24 各跑一遍。发版前另跑
node scripts/check-voice-asset.mjs:语音包是外置资产,提前确认线上还在。
包体积:为什么这么大、怎么变小
一句话:超过 90% 的体积是四套 2D live 形象的动作视频,代码加起来约 1.4 MB。语音包(33 MB)从 1.1.5 起就外置了,不在包里。
体积构成(1.2.2 实测)
| 组成 | 大小 | 说明 |
|---|---|---|
assets/webm |
145.6 MB | 246 段 500×500 带透明通道的视频:待机、点击反馈、倒霉剧情、余额通知、移动 |
assets/fonts |
3.9 MB | 上首软糖体(字幕、气泡用) |
assets/memes |
1.4 MB | 12 张「时刻表情包」(静态图) |
assets/pic + logo.png |
0.5 MB | 预览图与插件图标 |
lib + runtime |
约 1.4 MB | 宿主与渲染端代码(lib 968 KB,runtime 去掉切片音频后约 0.5 MB) |
| 语音包 | 0(已外置) | 76 句 × 中文/日文/英文原声,下载约 33 MB、落盘约 25.9 MB,首次启动后台下载到 ~/.dsh/columbina-pet/voice/official |
webm 按形象拆开:
| 形象 | 段数 | 体积 |
|---|---|---|
| 去眼罩 | 82 | 52.1 MB |
| 带眼罩·睁眼 | 82 | 52.1 MB |
| 带眼罩·闭眼 | 65 | 39.1 MB |
| 官方表情包 | 17 | 2.2 MB |
为什么这么大
- 它们是视频,不是矢量:每段是 500×500、带 alpha 的 WebM(VP8 + 透明通道侧信道)。浏览器里能「带透明通道 + 流畅循环」的格式基本只有 WebM 系,代价就是必须逐帧编码,没法像 SVG 那样几百字节画一个人。
- 素材按 1:1 原始码率随包发布:这批片段平均 1.2–4.3 Mb/s,而桌面上实际只显示 160–400 px,码率明显过剩。1.2.0 按使用反馈没有默认做有损压缩(压完边缘会略糊),压缩留成可选脚本。
- 四套形象互相独立:发色、服装、表情都不同,帧不能共用,所以是 82 + 82 + 65 + 17 段直接相加。
怎么优化(按收益排序)
① 用官方脚本重编码(推荐,约 −56%)
FFMPEG=/path/to/ffmpeg node scripts/shrink-webm.mjs --crf 30 --backup D:/backup/webm-orig
- 本机实测:143.4 MB → 62.4 MB,VP9 + alpha 保留,首帧与原件 RGB 平均差 0.74/255(肉眼无差)
--crf 24更保险:87.3 MB;--crf 38最激进:约 30 MB(按同等比例估算,建议自己先备份试一段)- 必须用 ffmpeg ≥ 4.4(2021 年以后)。更老的构建会直接丢掉透明通道,桌宠会变成一块不透明白板;脚本无法自动识别,替换前先解码一帧看四角 alpha 是否为 0
- 默认原地替换、失败的文件保持原样;17 段官方表情包是 VP9 无 alpha,脚本会自动跳过
② 只保留要用的形象
删掉不用的 assets/webm/<前缀>*,按上表直接省:只留官方表情包约 2.2 MB,官方 + 一套约 54 MB。删完把 runtime/electron-helper/voice/voice-index.js 里对应的 skins[] 项一并去掉,否则右键菜单里还能选到一套没素材的形象。
③ 素材外置,多份安装共用
宿主支持外部素材根 ~/.dsh/columbina-pet/assets:同名的文件优先于包内(/healthz 的 assets.externalActive / assets.externalFileCount 可以查)。把 assets/webm 挪过去、包内删掉,就变成「代码随包升级、素材只留一份」。
④ 选安装方式
- 插件市场 /
npm i dsh-columbina-pet:只下 tarball(148 MB),不带 git 历史 git clone源码安装:仓库带完整历史,比 tarball 更大;升级也要自己拉- 升级时 npm 会重新取整包(本地缓存命中会快很多),所以「素材外置」对反复升级最划算
安装
ℹ️ 可以与上游
dsh-pet并存(1.0.4 起):本插件的路由前缀、bridge scheme、用户目录、会话身份都已迁到dsh-columbina-pet*命名空间,不再和上游抢/dsh-pet-7340。为兼容旧书签仍会尝试注册旧前缀,旧前缀被上游占用时静默跳过。
📦 第一次安装会等一会儿:包里有四套 2D live 形象的动作视频,tarball 约 148 MB(解开约 212 MB)。从 GitHub 或 npm 拉取慢几分钟是正常的,中途别取消;装完还要完整退出 DSH 再打开,桌宠才会换上新代码。
通过 DSH 插件管理安装(推荐)
打开 DeepSeek Harness 桌面端 → 设置 → 插件 → 添加插件
在输入框里粘贴仓库地址:
github:Yuanawaqwq/dsh-columbina-pet也可以贴完整地址
https://github.com/Yuanawaqwq/dsh-columbina-pet。安装完成后完整退出 DSH 再打开(关窗口、刷新页面都不算重启)。
第一次桌宠没出现,说明本机还没有 Electron 运行时:按提示再重启一次,或手动运行
node node_modules/dsh-columbina-pet/scripts/ensure-electron.mjs
手动装进 profile
cd ~/.dsh/profiles/<你的 profile>
npm install dsh-columbina-pet
然后把它加进 profile 的 package.json:
{
"dependencies": {
"dsh-columbina-pet": "^1.2.2"
},
"dsh": {
"profile": {
"bundles": [
"@deepseek-ai/dsh-base",
"dsh-columbina-pet"
]
}
}
}
完整退出 DSH 再打开(关窗口、刷新页面都不算重启)。
从 npm 安装(1.2.2)
cd ~/.dsh/profiles/<你的 profile>
npm install dsh-columbina-pet@1.2.2
装完同样把 dsh-columbina-pet 加进 profile 的 dsh.profile.bundles,然后完整退出 DSH 再打开。
从 GitHub 安装
cd ~/.dsh/profiles/<你的 profile>
npm install github:Yuanawaqwq/dsh-columbina-pet
从本地源码安装
cd ~/.dsh/profiles/<你的 profile>
npm install file:C:\path\to\dsh-columbina-pet
# 或 Linux/macOS
npm install file:/path/to/dsh-columbina-pet
说明:仓库自带约 147 MB 的 2D 形象动作素材(语音包外置、不在仓库里;形象沿用 1.1.11 的原始素材,不做有损压缩),npm 包 tarball 约 148 MB、解包 161 MB。想自己瘦身可以跑
node scripts/shrink-webm.mjs:VP9+alpha 重编码,crf 24 实测 143.4 MB → 87.3 MB,首帧 RGB 平均差 0.5/255、透明边缘最大差 4/255,肉眼看不出差别。国内直连 registry 可能较慢;网络不好时优先走 GitHub 或 Release 附件,或按下面的镜像写法加速。
国内网络加速(可选)
先看一眼自己走哪条线更快(数字越小越快):
curl -o /dev/null -s -w 'github %{time_total}s
' https://github.com
curl -o /dev/null -s -w 'npmmirror %{time_total}s
' https://registry.npmmirror.com
如果 github 明显慢于 npmmirror,按下面的镜像走:
| 环节 | 常规地址 | 国内镜像写法 |
|---|---|---|
| 插件安装 | github:Yuanawaqwq/dsh-columbina-pet |
https://ghfast.top/https://github.com/Yuanawaqwq/dsh-columbina-pet(或把前缀换成 https://gh-proxy.com/) |
| 依赖安装 | npm install |
npm install --registry=https://registry.npmmirror.com |
| Electron 运行时 | node scripts/ensure-electron.mjs |
先设 DSH_PET_ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/,再运行同一命令 |
| 语音包(外置素材) | node scripts/ensure-voice.mjs |
DSH_VOICE_PACK_URL=https://ghfast.top/https://github.com/Yuanawaqwq/dsh-columbina-pet/releases/download/v1.1.4/dsh-columbina-pet-voice-1.1.4.tar.gz node scripts/ensure-voice.mjs |
Windows PowerShell 里设置环境变量:
$env:DSH_PET_ELECTRON_MIRROR = "https://npmmirror.com/mirrors/electron/"
$env:DSH_VOICE_PACK_URL = "https://ghfast.top/https://github.com/Yuanawaqwq/dsh-columbina-pet/releases/download/v1.1.4/dsh-columbina-pet-voice-1.1.4.tar.gz"
镜像都是第三方服务,可用性会变;下载失败就换一个前缀,或直接走仓库自带的
dsh-columbina-pet-*.tar.gz(Release 附件里另有一份完整包)。
素材外置(可选,1.0.2+)
素材可以从插件目录里搬出去,放在 ~/.dsh/columbina-pet/assets/:宿主按「外置根优先、包内兜底」读取,形象、表情包、字体、图片与 config.jsonc 都适用。
# 复制到外置根(保留包内原文件)
node scripts/migrate-assets.mjs
# 校验后删除包内素材(插件目录立即瘦身)
node scripts/migrate-assets.mjs --move
健康检查
宿主在 GET /dsh-columbina-pet-7340/healthz 暴露一次自检:版本、Electron 路径、Helper 是否在跑、素材根、语音包状态,以及最近的启动错误(launch-error.json)。排障时先看它:
curl http://127.0.0.1:<DSH 端口>/dsh-columbina-pet-7340/healthz
版本一栏有四个字段:version(磁盘上 package.json 的版本,请求时现读)、activatedVersion(内存里正在跑的)、buildSha256(磁盘上 lib/index.js 现在的 sha256)、activatedBuildSha256(插件激活那一刻算的 sha256,留在内存里,不随磁盘变化)。前三个对得上说明版本一致;version 比 activatedVersion 新,就是换包没重启;buildSha256 与 activatedBuildSha256 不同,就是同一个版本号又重新打过包、而内存里跑的还是旧那份(needsRestart: true)。
assetRoots.externalActive 为 true 且 externalFileCount > 0 时,说明外置素材已经命中(1.0.3+);voicePack.active 为 false 时看 voicePack.lastError。
另有一个不用访问 URL 的旁证:~/.dsh/columbina-pet/activation.json 记录最近一次激活的时间、版本、buildSha256、activatedBuildSha256,以及磁盘版本与运行版本是否不一致(needsRestart)。
第一次启动
首次使用需要 Electron 运行时(约 100 MB,从 npmmirror 下载,可用环境变量换源):
node node_modules/dsh-columbina-pet/scripts/ensure-electron.mjs
# 可选环境变量:DSH_PET_ELECTRON_VERSION / DSH_PET_ELECTRON_MIRROR
下载好后桌面会出现哥伦比娅;右键她可以打开全部设置。
遇到问题怎么办
九成问题用两条命令就能定位:
curl …/healthz(宿主自检)与浏览器 F12 里搜[dsh-pet](前端日志)。下面按「症状 → 先看什么 → 怎么办」排,都不需要重装。
第 0 步:四个数对一遍
| 看什么 | 在哪 | 正常值 |
|---|---|---|
| 版本一致 | /healthz 的 version 与 activatedVersion |
两个相同;不同 = 换了包没重启 |
| 代码一致 | buildSha256 与 activatedBuildSha256 |
相同;不同且 needsRestart: true → 完整退出 DSH 重开 |
| 语音包 | /voice/health 的 voice.ready / voice.zh |
true / 76 |
| 桌面 Helper | /healthz 的 helperRunning |
桌面模式应为 true;网页模式可以是 false |
端口每次启动 DSH 都会变,写法见上一节「健康检查」。
装完没生效 / 还是旧行为
needsRestart: true→ 完整退出 DSH(关窗口不算,要从托盘/菜单退出进程)再打开。刷新页面只换前端,不换宿主。- 插件管理里
dsh-columbina-pet是否还在启用状态(被禁用时宿主照常启动,只是没有宠物)。 - 从市场装的?市场条目指向
releases/latest,装到的就是最新版;要确认拿到的是哪一版,看/healthz的version。
第一次安装很慢、像卡住了
- tarball 约 148 MB(解开约 212 MB),慢几分钟是正常的,别中途取消——取消会留下半个
node_modules。 - 磁盘至少留 400 MB;代理/公司网可能拦 npm registry。
- 真卡死:删掉
node_modules/dsh-columbina-pet再装一次即可(其它依赖不用动)。
桌宠没出现 / 看不见她
- 网页模式:先刷新页面(Ctrl+R),再看控制台有没有
[dsh-pet]的挂载日志。 - 桌面模式:她是独立的透明窗口,可能被拖到屏幕边缘之外、落在副屏、或者被全屏应用压住。看
helperRunning,再看任务管理器里有没有electron.exe。 - 全屏游戏 / 演示模式下系统会压住置顶窗口,退出全屏再试。
- 改过多显示器或分辨率后位置可能越界:把
main-config.jsonc里pets[]的position删掉,回默认位置。
没声音 / 没字幕 / 字幕比声音先没
- 先看菜单:音量、静音、夜间勿扰、碎碎念是否被关掉。
- 控制台
[dsh-pet] 字幕丢弃 seq=…表示那一句被更晚的一句顶掉了(正常行为,不是 bug)。 [dsh-pet] 字幕跟音频 duration=未知是正常兜底:音频不支持分段取字节时,字幕改按播放进度续命(1.2.1 起)。- 浏览器策略:页面还没被点过之前,自动播放会被拦。随便点一下页面,桌宠会补播一句(控制台有「补播」记录)。
- 语音包缺失:
/voice/health里voice.zh为 0 → 右键菜单「语音包与素材 → 修复」,或curl -X POST …/voice/repair。 - 字幕在画面顶部是设计如此(避免压住脚边动作),不是位置错了。
气泡出现方块 / 乱码
- 整句都是
□/?:文本本身是坏的字节(含\ufffd)。1.2.1 起宿主会拒绝写入这类文本(响应bad-encoding);已经坏掉的旧气泡会被下一条覆盖。自查:curl …/state看pets.main.say.data.text里有没有\ufffd。 - 自己用脚本打
/broadcast时,Windows 控制台会把中文先转成 GBK → 用curl --data-binary @body.json(文件按 UTF-8 保存),或先chcp 65001。 - 个别生僻字显示成方块:字体没覆盖到那个字形,属正常回落,不影响其它字。
- 自建字体路由
…/font/上首软糖体.ttf被安全软件拦时,会回落到系统字体,文字仍可读。
右键菜单打不开 / 设置面板白屏
- 网页模式:F12 看有没有
Uncaught报错;先确认版本 ≥ 1.2.1(网页端菜单对齐与浮层修正在 1.2.1)。 - 桌面模式:右键要落在宠物本体上,透明区域是穿透的。
- 面板白屏多半是素材路由 404(被安全软件拦)→ Network 里看
/dsh-columbina-pet-7340/…的响应码。
拖不动 / 一拖就飞
- 菜单里有「真实物理:开 / 关」:关掉就不抛飞、不弹天花板、落地即停。
- 拖拽要按住本体,透明区域不响应。
语音包下载 / 校验失败
- 先看
/voice/health的lastError,再看~/.dsh/columbina-pet/voice-pack.json的 marker(version应为当前版本)。 - 手动补:
node node_modules/dsh-columbina-pet/scripts/ensure-voice.mjs;可用DSH_VOICE_PACK_URL指定镜像。 - sha256 不符通常是代理改写了内容或下了一半 → 删掉
~/.dsh/columbina-pet/voice/重新下载。 - 语音包是外置的,升级插件不会重新下载。
素材自检报红
- 「语音包与素材 → 一键数」只读本机文件、不联网;只有点「修复」才会下载(约 31 MB,逐个校验 sha256)。
- 缺的是
webm动作或表情包时,它们随包发布:从用户目录删掉同名覆盖文件即可回落到包内版本,或重装一次包。
想彻底重来
- 备份
~/.dsh/columbina-pet/(配置、语音、激活记录都在里面)。 - 删掉它 → 下次启动自动重建,形象与语音会重新下载。
- 只想恢复默认设置:删
main-config.jsonc与pet/目录,保留voice/就不用重下语音。
报 bug 请带上这些
| 项 | 怎么拿 |
|---|---|
| 插件版本 | /healthz 的 version |
| DSH 版本 | DSH 的「关于」页,或窗口标题栏版本号 |
| healthz 全文 | curl …/healthz |
| 前端日志 | F12 Console 里所有 [dsh-pet] 开头的行 |
| 复现步骤 | 做了什么 → 期望什么 → 实际什么 |
| 环境 | Windows 版本、显示器数量与缩放、网页模式还是桌面模式 |
嫌麻烦就直接私信 B 站 六硬币的好活(uid 1947282109),把上面几项贴进去;也可以在仓库开 issue。
右键菜单
| 菜单 | 作用 |
|---|---|
| 切换间隔 | 一段动作放完后停留多久才切下一段(立即 / 1–60 秒,默认立即切) |
| 2D live 形象 | 四套形象即时切换 |
| 语言 | 配音语言、字幕语言、菜单语言分别切中 / 日 / 英 |
| 模型大小 | 0.5× – 3×,窗口限制在屏幕工作区内 |
| 天气 | 今天的天气 / 重新定位 |
| 音量 | 静音开关 + 20 / 40 / 60 / 80 / 100 % 五档 |
| 夜间勿扰 | 开 / 关 + 四档时段(22–07 / 23–08 / 00–09 / 01–10) |
| 省电模式 | 开 / 关:30 秒无操作暂停在播视频 |
| 语音包与素材 | 检查素材 / 一键修复 |
| 设置面板 | 打开完整设置(网页端铺在页面里,桌面端在宠物窗口内) |
| 待机动作 | 精选 / 当前形象全部动作 / 自己选… |
| 真实物理:开 / 关 | 关掉后不甩飞、不弹跳,落地即停 |
| 原声台词 | 按场景分组勾选允许说的句子 |
| 碎碎念设置 | 开 / 关、间隔(60–180 秒)、选择台词 |
桌面端另有「显示位置」等窗口相关项;网页端菜单的条目、顺序与文案已向桌面端对齐(1.2.1 起)。
配置
配置分三层,后面的覆盖前面的:
- 包内默认:
assets/config.jsonc - 用户覆盖:
~/.dsh/columbina-pet/main-config.jsonc(只写要改的键即可,pets按id合并) - 单只宠物覆盖:
~/.dsh/columbina-pet/pet/<id>.jsonc
旧版本的目录叫
~/.dsh/dsh-pet/,启动时会自动迁移到~/.dsh/columbina-pet/,一次性、不删原目录。看到两个目录并存是正常的。
素材同样支持用户覆盖(优先于包内):
| 素材 | 用户目录 | 包内目录 |
|---|---|---|
| live 形象 | ~/.dsh/columbina-pet/main-animation/webm/ |
assets/webm/ |
| 表情包 | ~/.dsh/columbina-pet/memes/ |
assets/memes/ |
| 外置素材根(1.0.2+,优先级最高) | ~/.dsh/columbina-pet/assets/ |
— |
常用字段(assets/config.jsonc 内有完整注释与默认值):
| 键 | 说明 |
|---|---|
pets[].name / size / position |
名字、初始大小与出现位置 |
physics |
重力、回弹、阻尼、贴边等物理参数 |
animations |
动作树:待机、点击、拖拽、事件、动作分组 |
memes |
表情包文件名与触发标签 |
workStatusTexts |
会话工作状态气泡文案 |
whisperPrompt |
桌宠人设(供对话 / 主动说话使用) |
语音系统
语音是一个 classic script sidecar:runtime/electron-helper/voice/voice.js,在 Electron 页面里直接跑,不需要构建。
- 语音索引:
runtime/electron-helper/voice/voice-index.js(window.__COLUMBINA_VOICE,含台词表、语义词组、四套 skins、表情包标签)。 - 音频:外置在
~/.dsh/columbina-pet/voice/official/<lang>/<file>.ogg(76 句 × 三语,首次启动下载;包内的runtime/electron-helper/voice/official已从 npm 包排除)。94 段切片音频在runtime/electron-helper/voice/clips/。 - 设置镜像:
runtime/electron-helper/voice/voice-settings.js是默认值的静态副本;菜单里的调整也会写进浏览器localStorage(键columbina-voice-local-v1)。 - 想加台词:在
voice-index.js的lines/menu里加条目,把音频放进对应语言目录,重启桌宠即可。菜单标签会映射到台词下标,改标签别忘了同步改menu。 - 想换角色:替换四套
webm动作、assets/memes、voice/official/*与voice-index.js,再把assets/config.jsonc里的名字与人设改成你的角色。
语音包是外置的,不在 npm 包体里。 新装用户首次启动时由 scripts/ensure-voice.mjs 下载(约 33 MB,带 sha256 校验,失败会依次换 gh-proxy.com / ghfast.top 镜像)。它的地址写在 package.json 的 voicePack.url,钉在 v1.1.4 那个 Release 资产上——那份资产是全世界新装用户唯一的语音来源,属于不可变归档:
- 不要删除、不要替换它。删掉之后新装用户只会静默降级成「无原声」,
/voice/repair也修不回来。 - 发版前跑一次
node scripts/check-voice-asset.mjs(秒级,只发一个 HEAD):资产 404 或大小不符会直接失败;本机到 github.com 不通时会自动用镜像判定,只报警告、不误判成资产丢失。 - 将来真要更新语音内容,走「新开一个 Release 资产 + 同时改
voicePack.url与sha256」,别原地覆盖旧文件。
设置面板是本插件自己实现的:网页端铺在页面里,桌面端在宠物窗口内。姊妹插件 dsh-columbina-theme 提供的是主题皮肤(换色、背景、BGM 等),可选,不装也不影响菜单与设置面板。
天气播报
- 定位:
ipwho.is的 IP 归属(城市、经纬度),只在需要时请求一次,缓存 24 小时。 - 预报:
open-meteo.com免费接口,取当前温度、湿度、风速、当日最高 / 最低温与 WMO 天气码,缓存 20 分钟。 - 城市名本地化:当字幕语言是中文且定位在中国时,用 open-meteo geocoding 反查中文城市名。
- 天气码 → 天气词 → 台词场景(雨 / 雷 / 雪 / 风 / 其他),再按字幕语言给出中文 / 日文 / 英文摘要。
- 断网或超时(9 秒)会弹一句兜底台词并结束,不阻塞后续交互。
- 调试接口:页面内
window.__columbinaVoice.weatherInfo(true)返回当前天气对象,.weather()触发一次播报。
目录结构
dsh-columbina-pet/
├─ lib/ # 预构建的宿主与浏览器插件(DSH 实际加载这里)
├─ src/ # TypeScript 源码(仅参考,见 src/README.md)
├─ test/ # 5 个零依赖用例(npm test 跑这个目录)
├─ runtime/electron-helper # 桌宠运行时:主进程、精灵、渲染、语音 sidecar
│ └─ voice/ # voice.js、voice-index.js、94 段切片音频(官方原声外置)
├─ docs/screenshots/ # README 预览图(不随 npm 包发布)
├─ assets/
│ ├─ webm/ # 四套形象的动作素材
│ ├─ memes/ # 12 张时刻表情
│ ├─ fonts/ # 气泡字体
│ ├─ pic/ # 光标与通知图标
│ ├─ preview/ # 其它预览素材(不随包发布)
│ ├─ config.jsonc # 默认配置
│ └─ logo.png # 插件图标(≤256 KiB)
├─ scripts/ # ensure-electron / ensure-voice / check-voice-asset / shrink-webm / migrate-assets
├─ .github/workflows/ci.yml
├─ cordis.patch.yml # 挂载声明
├─ NOTICE.md # 素材版权声明
└─ package.json
二次开发
lib/是打包产物,DSH 运行时加载的是它;src/只是源码参考。修改src/后需要自己按 TS 工程重建lib/(上游构建配置未随包发布)。runtime/下是可直接改的 classic script,改完node --check <file>.js自检,重启桌宠即生效。- 页面里调试:
window.__columbinaVoice暴露state()、speak(text)、whisper(scene, force)、weatherInfo(force)、weather(force)、setLang、setScale、setSkin等接口。
已知限制
- 本分支只含 2D 形象,上游的 3D 形象切换已移除。
assets/fonts/上首软糖体.ttf是非开源字体;对外分发或商用前请确认授权,或替换成自己的字体。- 官方语音、形象与表情属于同人二创素材,仅建议个人非商业使用,详见 NOTICE.md。
lib/与src/可能存在版本差(以lib/实际行为为准)。
致谢与版权
- 本项目作者:六硬币的好活(B 站 uid 1947282109)| GitHub @Yuanawaqwq。
- 上游:dsh-pet(MIT,Copyright © 2026 PC2005-cloud),本仓库的骨架、runtime 与大部分工程实现来自它。
- 角色与素材:详见 NOTICE.md。
- 2D 形象:「官方表情包」版由本项目整理;「去眼罩 / 睁眼 / 闭眼」三套由 B站 UP 主 @渲琳 使用 EmoteLab 制作,原作见 【EmoteLab】捏了哥伦比娅和桑多涅!。感谢作者分享,如作者希望下架请联系移除。
- 主题皮肤(可选,与设置面板无关):dsh-columbina-theme。




No comments yet. Be the first to write one.