dsh-live2d
v0.1.0
Published
DSH web plugin: show a Live2D character at the bottom corner of the DeepSeek Harness web page, with a load progress bar and a settings section that controls the whole widget behavior (model URL, size, position, scale, opacity, drag, volume, …) through the
Maintainers
Readme
dsh-live2d
DSH Web 插件:在 DeepSeek Harness 的 Web 页面右下角展示一个 Live2D 角色——带加载进度条、支持拖拽,挂件的全部行为都可在 Web 设置界面配置(无需手动编辑任何配置文件)。渲染基于 l2d 库(内置 Cubism 2 & 6 运行时,零额外 SDK)。
- 形态:官方 bundle 插件(
dsh.bundle组合层 +dsh.client浏览器半) - 配置:走官方 settings 通道(
@deepseek-ai/dsh-settings),Web 设置写入~/.dsh/settings.yaml,零手写 YAML - 依赖:l2d 已打进 client bundle,用户零额外安装
- 默认模型:
https://model.hacxy.cn/Mao/Mao.model3.json(Cubism 6),可在设置界面换成任意.model.json/.model3.json
安装
本地目录(开发验证)
# 在包目录内构建(产物 lib/ 需已存在)
pnpm install && pnpm run build
# 安装进 web profile(bundle 声明 dsh.bundle → 自动进入 dsh.profile.bundles 层栈)
dsh plugin --profile web add /path/to/dsh-live2d
# 重启 web 后生效
dsh webGit 源(发布后用户可一行安装)
仓库内已提交构建产物 lib/(git 安装不执行构建),因此:
dsh plugin --profile web add "github:you/dsh-live2d#<commit>"npm(发布后)
dsh plugin --profile web add dsh-live2dWeb 设置(全部行为可配,零配置文件编辑)
设置 → Live2D 分区:13 个字段全部可编辑,保存即生效(无需重启)。
| 分组 | 字段 | 说明 |
|---|---|---|
| 开关 | enabled | 总开关:关闭后右下角不再显示角色 |
| 模型 | modelUrl | 模型入口文件,.model.json(Cubism 2)或 .model3.json(Cubism 6) |
| 外观 | width / height | 挂件 CSS 尺寸(px) |
| 外观 | opacity | 挂件透明度 0~1 |
| 外观 | zIndex | 层级 |
| 位置 | anchor | 锚定右下角或左下角(right / left) |
| 位置 | offsetX / offsetY | 距锚定边/底部的间距(px) |
| 渲染 | scale | l2d 模型缩放 0.01~10 |
| 渲染 | volume | 动作音效音量 0~1 |
| 渲染 | logLevel | error / warn / info / trace |
| 交互 | draggable | 可拖拽(拖动后停在指针位置,刷新复位) |
保存与生效语义:
- 保存 = 把发生变化的字段经官方
settingsRPC 逐个写入(通道为单字段写、无事务;保存期间挂件不重新加载,全部落定后按字段类型应用——尺寸/位置/开关等布局字段原地更新 DOM,模型地址/缩放/音量/日志级别等渲染字段才会重载模型)。 - 恢复默认 = 清除用户层覆盖,全部字段回到部署默认(schema 默认 → bundle 组合配置)。
- 外部对
~/.dsh/settings.yaml的手动编辑会被 settings provider 监听并热更——同一 namespace 下所有已打开页面(含挂件与设置面板)自动刷新。 - 冲突保护:任何写入都带
expectedRevision;你的配置被外部修改后,面板会提示并自动刷新为最新值,不会静默覆盖。
配置分层(理解优先级)
配置不是"一个文件",而是三层按序解析:
- schema 默认(内置
DEFAULT_CONFIG) - base 层:插件组合配置(bundle 的
cordis.patch.yml里的live2d行)——部署者想改默认值时在这里改 - user 层:
~/.dsh/settings.yaml的dsh-live2d段——Web 设置界面写入的覆盖,优先级最高
# ~/.dsh/settings.yaml(Web 设置面板写入,不要手改——面板会替你管理)
dsh-live2d:
modelUrl: 'https://model.hacxy.cn/xxx/xxx.model3.json'
width: 320历史说明:早期版本(v0.1.x)用自建 HTTP 路由把
modelUrl直接写进profiles/web/cordis.patch.yml。v0.2.0 迁移到官方 settings 通道后已删除该通道;若你的用户 patch 层仍有手写的live2d行,它继续作为 base 层生效(无需迁移),settings 面板的值只在你通过 UI 保存后才会被 user 层覆盖。
卸载
dsh plugin --profile web remove dsh-live2d工作原理
- Node half(
src/index.ts):Cordis entry,导出Config(Schemastery schema,同时充当持久层校验 schema)。apply调用installSettingsSection(ctx, NAMESPACE, Config, config, hooks)把插件自己的组合配置注册为dsh-live2dnamespace 的 base 层(installSettingsSection来自@deepseek-ai/dsh-settings,rides 插件 fiber,settings 服务未挂载时插件按组合配置原样工作)。用户层(~/.dsh/settings.yaml)由官方 settings provider 落盘、监听与校验:解析序为 schema 默认 → base → user,任何写坏 user 层的编辑都会被拒并保留最后好值。 - Browser half(
src/client/index.ts+Panel.tsx):window.__ModuleLoader__.load({ id, factory })契约的 CJS bundle。apply(ctx)里ctx.settingsScope.bind({ namespace: 'dsh-live2d' })绑定同一 namespace(settingsScope 由官方dsh-client-ui-settings提供,transport 经 connection RPC,loopback-only):- 挂件:
ctx.effect()挂载(固定定位容器 + canvas + 进度条,默认右下角 →l2d.init(canvas).load(),监听loadstart/loadprogress/loaded驱动进度条 → 卸载时destroy()+ 移除 DOM)。订阅 scope 快照:每次配置提交(本面板保存、外部编辑、其它 tab)都会 diff 新旧值——布局字段原地更新容器样式(不重载模型),渲染字段整体重建挂件。 - 设置面板:
ctx.slots向settings.section注册 Live2D 分区(React,useSyncExternalStore订阅 scope 快照)。保存 = 校验(校验规则镜像 schema 的范围)后逐字段scope.set();恢复默认 = 按 user 层的字段scope.unset()(回到 base)。
- 挂件:
- 构建:tsdown 两段输出——
lib/index.mjs(ESM,@deepseek-ai/*保持 external,由 profile pnpm 闭包注入)与lib/client.js(CJS +__ModuleLoader__包装,l2d 内联;react/react/jsx-runtime/@deepseek-ai/dsh-client-ui-primitives走 shell 模块表保持 external;settings 契约类型 type-only)。
开发
pnpm install
pnpm run typecheck # tsc --noEmit
pnpm run build # tsdown → lib/index.mjs + lib/client.js浏览器端到端验证(需要本机装有 Chrome,且已把插件装进 web profile 并 dsh web --port 3090 运行):
# 启动 headless Chrome(软件 WebGL;Cubism 6 模型在软件渲染下无法出画面属环境限制,
# 验证渲染时先把模型临时换成 Cubism 2,如 https://model.hacxy.cn/shizuku/shizuku.model.json)
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" --headless=new \
--no-sandbox --disable-gpu --enable-unsafe-swiftshader --use-angle=swiftshader-webgl \
--disable-dev-shm-usage --no-first-run --no-default-browser-check --disable-crash-reporter \
--user-data-dir=/tmp/dsh-chrome --remote-debugging-port=9224 about:blank &
DEBUG_PORT=9224 node scripts/e2e-verify-v2.mjsscripts/e2e-verify-v2.mjs 覆盖:默认模型/右下角定位、加载进度条、设置面板改模型地址 → 保存 → 挂件重载、改尺寸/锚定/总开关 → 保存 → 原地生效,并输出页面 console 报错。测试结束后自动恢复默认配置。
发布
pnpm run build产出lib/。- 建议把
lib/提交进仓库(.gitignore已保留)——git 安装不执行构建,产物入库才是一行安装。 - 发布到 npm:
npm publish(files已限定lib、cordis.patch.yml、README、LICENSE)。@deepseek-ai/*为 optional peerDependencies,官方运行时会注入,公共 npm 无需安装它们(其中@deepseek-ai/dsh-settings是配置通道依赖)。
免责声明
本插件不包含、不分发任何 Live2D 模型资源。默认模型 URL 指向模型 CDN,请确认你有权使用所配置的模型(商用需遵循模型许可与 Live2D Proprietary Software License)。
