dsh-pet-live2d
已验证dsh-pet-live2d · v3.3.1 · MIT · Web 界面
Live2D 桌宠插件:为 DSH Web GUI 挂一只可拖动、会跟随鼠标、能换动作与表情的 Live2D 宠物。
安装
dsh plugin add dsh-pet-live2d 用 dsh --profile default --dump-config 确认 layer 已生效 —— 参见安装指南。
源码
标签
作者
说明文档
dsh-pet-live2d
给 DSH(DeepSeek Harness)Web GUI 用的 Live2D 桌宠插件:一只可以拖动、跟着鼠标看、 点她会害羞、还会跟着会话状态换动作的桌宠。
自带 DS鲸鱼娘(8 组动作 + 44 个表情/道具),开箱即用。
宠物会跟着插件一起更新:随包的那只(以及它的默认设置:台词、互动反应、 会话相位、摸鱼槽位)在插件升级时自动同步到
%DSH_HOME%\pets\ds-whale-girl\。 你自己改过的那份**不会被覆盖**(判定是内容指纹,改过就一个字都不碰), 想拿回随包版本就把目录删掉、重启dsh web,它会重新装一份。更新日志见 CHANGELOG.md。

功能
- 拖动 / 缩放:位置和大小记在 localStorage,重启还在
- 跟随鼠标:视线和头部跟着指针,移开(或窗口失焦)自动回正
- 点击反应:点头部才挥锤撒娇,点身上其它地方只出气泡
- 事件穿透:只有角色剪影吃鼠标事件,方形画布的透明处穿透到底下的页面,不挡 DSH 的 UI
- 跟着会话走:订阅 DSH 的真实事件(
tools/*等),思考/工具/等待/完成/出错换动作与表情, 长任务持续播放对应动画 - 待机摸鱼:静置一会儿自己演一段(不会演「点击」「出错」这类专属动作)
- 都会自己收尾:动作、定格、表情到点全部回到初始待机,不会卡住
- 全都可配:20 个互斥槽位(装扮 + 表情),每个槽位一张可增删、带权重的条目表, 条目之间还能配「同时 / 前提」关系;会话相位是同一套池子机制
安装
# 从 npm 装(推荐;插件和自带宠物一起下好)
dsh plugin --profile web add dsh-pet-live2d
# 或从仓库装(# 后面是 pnpm 的 path: 协议,注意那个斜杠)
dsh plugin --profile web add "github:A8Chann/dsh-pet-live2d#path:/dsh-live2d-pet"
# 或先克隆再装本地目录
git clone https://github.com/A8Chann/dsh-pet-live2d
dsh plugin --profile web add "link:./dsh-pet-live2d/dsh-live2d-pet"
装到哪个 profile? 取决于你在哪里用它:
- 浏览器里跑的
dsh web⇒--profile web(上面几条都是这个);- DeepSeek Harness 官方桌面客户端 ⇒ 它用的是
--profile desktop,例如dsh plugin --profile desktop add dsh-pet-live2d。装完重启一次(插件在启动时加载,客户端 bundle 也不做热重载)。
Cubism Core:不用手动装
live2dcubismcore.min.js 是 Live2D 株式会社的专有运行时,不能随插件分发 —— 但你也不
用自己去找:插件第一次用到它时,宿主半区会去
Live2D 官方 CDN 取一份
(校验过再发出去),并缓存到 %DSH_HOME%\pets\.runtime\live2dcubismcore.min.js,之后离线也能用。
只有当这台机器访问不了外网时,才需要手动下载
Cubism SDK for Web、把 Core/live2dcubismcore.min.js
放到上面那个路径。
宠物:随包自带
插件包里就带着一只可用的宠物(pets/ds-whale-girl/,CC BY-NC-SA 4.0)。**第一次运行时
宿主半区会把它复制进 %DSH_HOME%\pets\**,所以装完插件、重启 dsh web 就能看见。
升级时原封不动的随包宠物会同步新版默认值(包括提示音);你自己改过的宠物目录优先,不会被覆盖。
怎么用
- 右键点宠物 呼出面板:「动作」「装扮」两个页签,底部是大小滑杆和「归位」。 平时画面上没有常驻 UI。
- 改配置 两个入口:DSH 设置页 → 桌宠(完整设置),或侧栏「插件」→ 本插件(常用开关)。
设置说明
官方「插件」页上的那一节
侧栏点「插件」,「已安装」里那张带图标的卡片就是本插件。点进详情,描述与插件行之间是它 自己的配置区:
- 常用开关:气泡、会话提示音、摸头 / 摸尾巴 / 转圈、跨启动记住装扮;
- 四根滑杆:注视满偏、收回倍数、静置多久开始摸鱼、提示音音量;
- 显示位置:自动 / 页面内 / 桌面。
改的是与设置页同一份配置(%DSH_HOME%\pet-settings.json),两边随时一致。相位台词、
池子编辑器、装扮与台词文案仍在 设置 → 桌宠 里改 —— 那里才是完整设置。
摸鱼:每个槽位一张条目表
摸鱼 = 静置一会儿之后,宠物自己换个样子。每个槽位各掷一次骰子(不是"这次只动一两个"), 条目上的权重就是"多久动一次"。
- 一张表里的条目可以增删:
+ 名字是虚线药丸,行尾×删掉。 宠物给的那套只是建议,你加进来的运行时真的会抽到。 - 摸鱼默认盯宠物声明的那几个槽位(这只宠物是七个:右手 / 左手 / 情绪 / 脸红 / 嘴部 /
眼部 / 自拍,写在
pet.json的live2d.fidgetSlots里),其余槽位在卡片底部点一下就 加进来(+ 槽位)。 - 「默认」=回到默认(把这个槽位清空)。
默认 10 : 脸红 1= 大约每 11 次摸鱼脸红一次、 其余时间回到没有。想让某个槽位完全不动,把它的条目删光或权重归 0。
会话相位:动作、气泡与提示音放在一起
设置页「会话提示音」卡统一控制开关和音量;紧邻的「会话相位」卡将八个相位排成宽屏两列、窄屏单列的概览,默认收起,点开一个相位后才显示它的「气泡与提示音」「动作槽位」编辑区。行头「重置动作」只恢复动作槽位;台词用自己的「恢复默认」按钮,提示音可单独静音、试听或上传文件。动作池子仍是"槽位 → 条目表",机制和摸鱼一样。宠物跟着 DSH 的真实事件换相位:
| 相位 | 什么时候 | 这只宠物演什么 |
|---|---|---|
thinking |
模型在想 / 刚开工 | 抬头看 |
tool |
调工具(detail 带工具名) | 写本本 + 流汗 |
waiting |
有操作等你批准 | 问号 |
asking |
它问了你一个问题、在等你回答 | 举手 + 问号 |
helper |
起了子代理(一段长活) | 喵喵手 + 调皮 |
queued |
你发的话排队了(它还在忙) | 感叹号(短促一下) |
done |
这一轮说完(庆祝 3.5 秒) | 开心 + 情绪花花 |
failed |
出错了 | 大哭 + 流汗 |
来源是 agent/status、tools/pre-execute|post-execute、approval/request、
user-questions/request、subagent/start|end、agent/inbox/inserted、
agent/turn-stopping、agent/error —— 按主题折成上面这几个相位。
相位表一开始就列出全部相位,显示的是有效池子:
| 行头概览 | 含义 | 恢复方式 |
|---|---|---|
| 动作默认 / 已改 | 动作槽位沿用宠物默认 / 用你的池子 | 动作改过才显示「重置动作」,只重置动作池 |
| 台词默认 / 已改 | 该相位台词是否被你修改 | 展开后点「恢复默认」 |
| 音频宠物默认 / 已上传 / 已静音 / 未配置 | 宠物音符、当前宠物的上传文件、单独静音或未声明 | 展开后上传、移除上传或勾选提示音 |
改动只在真的编辑时才落盘,所以"看一眼"不会留下覆盖 —— 以后宠物更新了默认值, 没改过的相位照样吃得到。
相位是"接管",不是"叠加":会话一开始,宠物换相位那一套样子 ——
- 相位点名的槽位用它抽到的(
thinking就是头顶鲸 + 画笔); - 相位没点名的槽位一律让位(收回):你手选的掏出手机、爱心眼、自拍不会在整场 会话里一直挂着。挂在槽位上的动作(掏出手机是定格动作)也会跟着交还身体,手放下来;
- 装扮槽永远归你:眼镜 / 发饰 / 魔爪 / 巴菲 / 桌布 / 手机换色 会话不碰;
- 会话进行中想改也能改:手点一下会临时盖过相位的那一格(这场会话里有效);
- 会话结束后,你原来的样子回来(让位不是删除)。
右键面板的「装扮」页签跟着相位走 —— 会话中它显示的是相位抽到的,不是你上次手选的。
提示音:完成 / 失败 / 需要你处理
在 DSH 设置页 → 桌宠 → 会话提示音 打开总开关并调节音量(默认关闭);到紧邻的「会话相位」卡点开相位,在「提示音」处选 上传音频。支持 MP3 / WAV / OGG,单文件最多 1 MB;每只宠物、每个相位分别保存到 $DSH_HOME/pet-sounds/,换宠物不会沿用另一只的上传音频。「移除上传」恢复宠物默认音符,静音勾选框也能关闭已上传音频;上传成功会解除该相位先前的静音,但不会替你打开总开关。上传音频比宠物音符优先,两个窗口最多 3 秒同步一次。
上传的文件是按容器结构校验的(不是看扩展名,也不是只看开头几个字节):MP3 要有合法的帧头、Ogg 要过页校验、WAV 的 fmt/data 块要自洽 —— 网页端与桌面端用的是同一套判据(同一份合同向量在两边测试里跑)。长度字段写成 0 或 0xFFFFFFFF 的"流式" WAV 也收;明显不是音频、或被截断的文件会在上传时就报错,不会写进 $DSH_HOME/pet-sounds/。
旁边的 「试听」 让你不必等会话真的跑到那个相位:点一下直接听这一相位会响的那段声音(有上传听上传,否则听宠物/内置音符)。它故意不受总开关与单相位静音影响 —— 默认总开关就是关的,跟着它走等于"点了没反应";音量用当前提示音音量,音量为 0 时按 0.35 试听。没有任何音源(未配置、也没上传)的相位,按钮是灰的。
拖动「会话提示音」卡里的音量滑杆也会即时试听一小段(防抖:停手才响,响的是最终音量;这只宠物一个音源都没有时只给数字反馈)。音量滑杆这条按真实音量响 —— 拖到 0 就是静音,不会像「试听」按钮那样兜底发声,否则你听到的就不是"0 有多大声"了。
未上传时,内置宠物的 done、failed、waiting(待批准)、asking(待回答)各有一段合成短音;别的宠物可在 pet.json 的 live2d.sounds 声明自己的音符,空数组表示该相位不响,未声明整个字段的旧宠物沿用内置四声。音量拉到 0 会静音;首次播放前浏览器需要你点击一次页面解锁音频。初次连接的状态快照和重复状态不会响;若两个窗口同时接收相位,两边都开启时可能各响一次。
互动:摸头 / 摸尾巴 / 转圈
点她身上会有反应,判定用的是模型自己的几何,不是画出来的区域:
| 互动 | 怎么触发 | 默认反应 |
|---|---|---|
| 摸头 | 点在头部(含头发、耳朵 —— 宿主读 cdi3 里作者的部件命名认出来的 21 个部件) | 重锤出击 / 问号 / 星星眼 随机一个,不脸红 |
| 摸尾巴 | 点在尾巴/翅膀上(狐狸尾 / 猫尾 / 狼尾 / 大翅膀…15 个部件) | 吐魂 / 问号 随机一个 |
| 转圈转晕 | 鼠标绕着角色转圈:默认 2 圈、1.6 秒内 | 演「晕晕」 |
- 摸头/摸尾巴按三角面判定:圆顶带耳朵尖的头部轮廓、尾巴的边缘都对得上,不是方框。 顶点是当前帧变形后的,所以头歪着、身体摆着也准。
- 尾巴只认"鲸鱼尾鳍"那一块:这只模型有 16 块 drawable 的名字里带"尾/翅/翼",但其中
11 块是可选配件(狐狸尾 / 猫尾 / 狼尾 / 天使翅膀…)的几何、一直留在原地、横跨全身。
全算成尾巴的话"点到哪儿都是尾巴",而摸头又优先,可见的尾鳍反而摸不到。所以尾巴是按
贴图认的:
texture_00.png上鲸鱼尾鳍那一块对应的 5 块 drawable(都属部件尾巴(蒙皮))。 - 可点区域跟着尾巴动:决定事件归谁的那层轮廓是开机抓一次的,尾鳍摆动时会摆出去 —— 现在尾巴有一块实时跟随的可点矩形并进轮廓里,所以摆到哪儿都点得到。
- 摸头优先于摸尾巴:尾巴判定收紧之后两者基本不再重叠,重叠处仍然算摸头。
- 尾巴/翅膀是可选配件:没戴的时候它们的几何是退化的,"摸尾巴"就是没反应 —— 这是对的,不是坏了。戴上尾巴(装扮槽)之后才摸得到。
- 转圈看的是累计转角(不是位置绕了几圈),所以贴着角色转小圈、远远转大圈都算。
- 三个互动各自可开关,反应也能改(见下)。共用的三句台词在「气泡」设置里。
上表那三组是默认反应,来源分两层:宠物
pet.json里声明了就用它的;没声明就用 插件内置的这几个(重锤出击 / 问号 / 星星眼、吐魂 / 问号、晕晕)—— 自己做的宠物不写 这三个键也有反应。设置页「互动」卡的行尾会标明当前用的是哪一层(宠物默认 / 内置默认 / 已改过),候选勾选本来就是最高优先级。
气泡:说什么、在哪、要不要
她说话时会弹一个小气泡(问候、点击、摸头、摸尾巴、转晕、归位,以及每个会话相位一句: 思考中 / 用工具 / 等你批准 / 等你回答 / 叫了帮手 / 消息排队 / 完成 / 出错)。
- 所有文本都能改:会话台词在「会话相位」卡的对应相位里,其他台词在「气泡」卡。非相位的一组台词用
|分隔多个变体(随机挑一句),留空使用宠物默认;相位台词是一句,留空表示该相位不弹,点「恢复默认」可回到宠物台词。看一眼设置不会留下覆盖。 - 位置可调:左右 / 上下偏移两个滑杆(相对她头顶的默认位置),另有"一句话停留多久"。
- 总开关:关掉之后任何台词都不弹。
关系:同时(pairs)与前提(requires)
条目下面缩进那一层是关系,两种刻意用不同前缀:
| 关系 | 含义 | 例 |
|---|---|---|
同时 pairs |
抽中它 / 选了它就一起点亮 | 喵喵手 → 贴纸 = 猫猫 |
前提 requires |
必须先处于那个状态才播得出来 | 挤番茄酱 → 左手 = 蛋包饭 |
- 两者都能加能删(行尾
×,条目下面的+ 关系里按「同时 / 前提」分组选目标)。 - 摸鱼抽签时前提是闸门:前提不成立的条目不进池子。前提可能靠同一轮里别的槽位满足 (挤番茄酱要蛋包饭),所以抽签会抽到稳定为止(最多三轮)。
- 手动点选时前提由插件补上:点「自拍」会先把手机掏出来,跟点「挤番茄酱」会把蛋包饭 端上来是同一套 —— 不会"点了没反应"。
- 关系跟着选项走(不是池子里的某一条):同一个姿势在摸鱼表、相位池、右键面板里看到的 是同一份关系,改一处三处一起变。
装扮:穿在身上的东西
眼镜 / 发饰 / 魔爪 / 巴菲(桌面摆设)/ 桌布 / 手机换色 这六个槽位是装扮,和"这一轮临时挑的 表情"不是一回事:
| 场景 | 临时表情 | 装扮 |
|---|---|---|
| 会话相位开始 / 结束 | 由相位接管,相位结束就撤掉 | 不动 |
| 点「归位」 | 清空 | 保留 |
| 重启 / 刷新页面 | 回到默认 | 从 localStorage 穿回来 |
这只宠物有什么
44 个表情归入 20 个互斥槽位(换过宠物 / 改过配置的话,以设置页和 pet.json 为准)。
分类依据是模型作者在 cdi3 里自己写的分组和中文名(例如 ParamGroup29 被作者命名为
「C款动作开关」,里面正好是一组互斥的手部状态),不是按文件名猜的。
| 槽位 | 不选 | 可选项 |
|---|---|---|
| 眼镜 | 无 | 圆眼镜 / 方眼镜 / 椭圆眼镜 / 墨镜 |
| 贴纸 | 无 | 猫猫 / 兔兔 / 蝴蝶结 |
| 发饰 | 戴着 | 摘掉发箍 / 单边马尾 |
| 桌布 | 白色 | 黑色 |
| 魔爪 | 无 | 粉魔爪 / 白魔爪 |
| 鲸鱼 | 无 | 头顶鲸 / 放桌上 |
| 桌面摆设 | 无 | 巴菲 |
| 右手 | 无 | 掏出手机 / 喵喵手 / 双手比耶 / 挤番茄酱 / 写本本 |
| 自拍 | 无 | 自拍 / 快速自拍 |
| 左手 | 无 | 撤回 / 画笔 / 橡皮 / 蛋包饭 |
| 眼部 | 默认 | 星星眼 / 爱心眼 / 呆呆眼 / 晕晕 / 阴暗 |
| 情绪 | 平静 | 开心兴奋 / 悲伤 / 大哭 / 生气 / 调皮 / 闭眼口水 / 吐魂 |
| 嘴部 | 闭嘴 | 吐舌 / 吹泡泡糖 |
| 符号 | 无 | 问号 / 感叹号 / 流汗 |
| 氛围:花花 | 无 | 情绪花花 |
| 氛围:心跳 | 无 | 心跳 |
| 氛围:冒爱心 | 无 | 冒爱心 |
| 脸红 | 否 | 脸红 |
| 其他 | 无 | 手机换色 |
| 点菜 | 无 | 点菜按下 |
一个选项可以带多个表达式(「白魔爪」= 桌面粉魔爪 + 魔爪换色),选择常驻(不会过几秒 自己消失;自动清理只留给"反应"和"会话相位")。
做一只自己的宠物
宠物放在 %DSH_HOME%\pets\<id>\,最小结构:
%DSH_HOME%\pets\<id>\
pet.json # 清单(renderer: live2d)
c_0120.model3.json
model\ # .moc3 / physics3 / cdi3
textures\ # 贴图
motions\ # .motion3.json
expressions\ # .exp3.json
catalog.json # 可选:动作/表情的中文名与分类
{
"petManifestVersion": 2,
"id": "ds-whale-girl",
"displayName": "DS鲸鱼娘",
"renderer": "live2d",
"license": "...",
"live2d": {
"model": "c_0120.model3.json", // 相对于本目录
"scale": 1, // 在自适应缩放上乘算
"translate": { "x": 0, "y": 0 },
// 槽位:一个槽位 = 一个互斥组,`none` 是"不选"
"expressionSlots": [
{ "id": "eyes", "label": "眼部", "none": "默认",
"options": [{ "label": "爱心眼", "expressions": ["爱心眼"], "pairs": { "heart": "冒爱心" } }] }
],
// 会话相位 -> 槽位 -> 选项(读成"每个槽位一条、权重 1"的池子)
"looksByPhase": { "done": { "whale": "头顶鲸", "mood": "开心兴奋" } },
// 可选:每个相位一组 [频率 Hz, 从开始播放起的秒数];空数组表示该相位静音
"sounds": { "done": [[660, 0], [880, 0.13]], "failed": [] },
// 摸鱼默认盯哪些槽位(用户还能再加;不写就是"手/情绪/脸红/嘴/眼"那五个兜底)
"fidgetSlots": ["rhand", "lhand", "mood", "cheek", "mouth", "eyes", "selfie"],
// 互动反应候选(标签 = 动作的中文名或表情名)。**三个键都可以不写** ——
// 不写就用插件内置的:摸头 重锤出击/问号/星星眼、摸尾巴 吐魂/问号、转晕 晕晕
"patReactions": ["重锤出击", "问号", "星星眼"],
"tailReactions": ["吐魂", "问号"],
"spinReactions": ["晕晕"],
// 可选;模型自己表达不了的「作者意图」
"motionOptions": {
"OpenCase": { "hold": true },
"Selfie": { "prepend": "OpenCase" },
"SprayWater": { "preset": { "jingyu": 1 } }
},
"motionGuards": { "SprayWater": { "whale": ["头顶鲸", "放桌上"] } }
}
}
- 动作和表情列表以
.model3.json里声明的为准,插件启动时从模型读出 —— 换模型 / 改模型 文件立刻生效,不用改插件代码。 sounds:宠物声明后只有列出的相位会响;每相位最多 8 个正弦音符,频率 80–4000 Hz、起始时间 0–2 秒。没写整个字段的旧宠物沿用内置四声;无效音符不会播放。声音由页面合成,音量和静音可在设置页调整。motionOptions:hold(停在最后一帧)/persist(定格且不自动放手)/prepend(先播前置 动作)/preset(开播前把某些参数写死)。不写就是"播一次然后回待机"。motionGuards:动作的前提,形如"槽位 = 标签白名单"。白名单形式没法自动满足,只能拦 (喷水要鲸鱼,而鲸鱼有"头顶"和"放桌上"两种)——所以"能自动补上"的前提请写在选项的requires上(形如"槽位 = 某一个标签")。- 路径片段只允许
[A-Za-z0-9._-],中文文件名会让整个宠物加载失败。
动作与表情的语义(定格 / 前置动作 / 参数还原 / 表情叠加)见 skill cubism-engine。
宿主 HTTP 接口
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/live2d-pet/catalog |
已安装宠物 + 各自的动作/表情清单 + 运行时 URL |
| GET | /api/live2d-pet/asset/<id>/<path> |
只服务 model3.json 引用闭包内的文件(白名单 Set 比对 + realpath 包含,.. 永远匹配不上) |
| GET | /api/live2d-pet/runtime/live2dcubismcore.min.js |
Cubism Core:本地有就发本地的,没有就去 Live2D 官方 CDN 取一份并缓存(x-live2d-core-source: cdn);两边都拿不到才 502 |
| GET | /api/live2d-pet/runtime/live2d-vendor.js |
插件内置的 MIT vendor 分包(pixi.js + 引擎),按需懒加载 |
| GET | /api/live2d-pet/sound/<id> |
查询这只宠物已上传音频的相位、URL、格式和版本 |
| GET | /api/live2d-pet/sound/<id>/<phase> |
读取已上传的相位音频 |
| POST | /api/live2d-pet/sound/<id>/<phase> |
JSON { "base64": "..." } 上传,或 { "action": "reset" } 移除;限 MP3 / WAV / OGG、1 MB |
API 与资产路由默认只答本机回环请求。
架构与二次开发
dsh-live2d-pet/
package.json dsh.client.platform = web -> 双半区包
cordis.patch.yml bundle patch:插一行 live2d-pet
lib/
index.js 宿主半区:宠物发现 / 引用闭包资产路由 / 运行时分发
client.js 浏览器半区:手写 __ModuleLoader__ 工厂,无构建步骤
live2d-vendor.js pixi.js + untitled-pixi-live2d-engine 的 IIFE(esbuild 产物)
src/vendor-entry.ts vendor 分包入口(npm run build:vendor 重新生成)
Vendor 分包懒加载:只有真正挂载宠物时才注入,页面首屏不为它买单。
npm install # pixi.js / engine / esbuild
npm run build:vendor # 改动 src/vendor-entry.ts 或升级依赖时
改完 lib/client.js 重启 dsh web(bundle 不做热重载)。回归测试在仓库的
tools/browser-test/:无头 Edge + CDP,在真实 WebGL 里跑 16 个 driver 的完整契约。
cd ../../tools/browser-test && npm install && npm run suite
开发记录不在这个 README 里:踩坑、测量陷阱、帧序、验证写法按主题放在仓库的
.dsh/skills/下(cubism-engine/client-state/verification-signals/browser-cdp/docs-and-workflow),入口见仓库根的AGENTS.md。 用户可见的变化写 CHANGELOG.md。
排查
宠物根节点上挂着诊断读口(window.__dshLive2dPet),常用几个:expressions()(当前钉住的
表情)、slotSelections()(各槽位选了什么)、drawn(id)(这一帧真正写进模型的参数值)、
fidgetTally()(摸鱼抽签统计)、effectiveRelations() / settingsOverrides()(有效关系与
存档覆盖)、ambientDebug() / keptPoseDebug()(氛围回放与姿势保持的内部状态)。
交流群
大肥鱼 pet-live2d 交流群 —— QQ 群号 974641848:装不上、模型不对劲、想投稿自己的宠物, 都欢迎进群说。群二维码在仓库 README 的「交流群」一节。
许可
插件代码:MIT
vendor 分包:pixi.js(MIT)+ untitled-pixi-live2d-engine(MIT),可随包分发
Cubism Core:Live2D 专有,不随包分发;缺失时由宿主半区从 Live2D 官方 CDN 取一份并缓存到本地
DS鲸鱼娘模型:CC BY-NC-SA 4.0(署名 · 非商业 · 相同方式共享),见
pets/ds-whale-girl/LICENSE。 插件图标icon.png同属这一许可(由模型待机画面裁切缩放而来,属于改编)。版权链:上善无形(鲸鱼娘角色原作,原创 OC「溟月」)→ ZipZipPipe(DeepSeek 女仆二创) → 氵六青(本模型)。氵六青已授权本项目转载开源,但该授权不解除基础版权, 所以 NC / SA 依然有效;商业使用需分别取得三人授权。完整说明见
../NOTICE.md。