live2d-board
v1.2.4
Published
DSH Live2D board plugin: bundled Momose Hiyori LPK model, local LPK import, expression/motion control, AI reply bubbles with emotion expressions, and a settings-page master switch
Readme
Live2D Board
An open-source, dual-plane (Host + Web Client) plugin for DeepSeek Harness (DSH) that renders a Live2D character in the lower-right corner of the web UI. It supports local and bundled models, expression/motion control, AI reply bubbles with emotion expressions, chat-composer avoidance, and a master switch in the DSH settings panel.
The bundled default model
Momose Hiyori(MomoseHiyori.lpk) is non-commercial. The plugin code is MIT, but the model must not be used commercially or redistributed separately.
Screenshot

Features
Direct WebGL player — no iframe; local
pixi-live2d-display+ Cubism 4 rendering.Model sources — bundled
MomoseHiyori.lpk, local.lpkimport in the UI,live2d-lpk.json, environment variables, or an extracted model directory.Expressions & motions — model
.exp3.jsonfiles first, built-in fallbacks (happy/surprised/sad/angry, nod / shake / bow).AI reply bubbles — subscribes to DSH
session/event; when enabled, each assistant reply shows a one-sentence summary in the character's bubble.Emotion expressions — lightweight keyword mapping upgrades a bubble into
expression + text:| Emotion | Trigger examples | | --- | --- | |
sad| sorry, failed, error, not found ... | |angry| warning, danger, forbidden ... | |surprised| unexpected, turns out, interesting ... | |happy| done, success, solved, no problem ... |Chat composer avoidance — the character automatically moves up when the DSH input card would cover its head.
DSH settings switch — a dedicated
Live2D 看板娘page in the DSH settings panel can enable/disable the entire plugin.Persistent preferences — the master switch persists through the DSH settings service (fallback:
~/.dsh/live2d-plugin.json).Agent tool — optional
live2d_emotetool for the agent, disabled by default to avoid changing agent behavior.
⚠️ Agent behavior warning: enabling
Agent 控制registers thelive2d_emotetool. DSH then injects the tool's name, description, and parameter schema into the agent's prompt context. That can change how the agent plans and responds in ways that are hard to predict. Keep it off by default; enable it only when you actually want the agent to control the character, and turn it off when the session no longer needs it.
Quick Start
Install from npm:
dsh plugin --profile web add [email protected]Then start DSH:
dsh --profile web --port 3080Refresh the web page. The character appears at the lower-right corner. Open Settings → Live2D 看板娘 to toggle the whole plugin.
On machines where the profile was installed with a custom pnpm store, pass the same store directory:
dsh plugin --profile web add [email protected] --store-dir ~/.dsh/.pnpm-store
In-Game Menu
The only persistent button is Menu. It contains:
- 显示 / Display — hide or show the character
- 位置 / Position — toggle chat-composer avoidance
- 模型 / Model — reload model, reset position/zoom, import LPK
- 对话控制 / Chat control —
Agent 控制(live2d_emotetool) and消息气泡(AI reply bubbles + emotion) - 表情 / Expressions and 动作 / Motions
Model Sources (Priority)
LIVE2D_LPK_FILEenvironment variableLIVE2D_LPK_DIRenvironment variable (workshop item directories)~/.dsh/live2d-lpk.json:{ "lpk": "/absolute/path/model.lpk", "config": "/optional/config.json" }UI-imported
~/.dsh/imported-model.lpk(+ optional config).lpkfiles under~/.dsh/live2d-model/Bundled
MomoseHiyori.lpk
Without any configuration the bundled model is used automatically.
Model Import Notes
- Some Live2DViewerEX workshop models are STM-encrypted: importing a single
.lpkfile alone may fail because the model also needsfileId/metaDataor a matchingconfig.json. - The UI import button accepts both
.lpkand.jsonfiles at the same time — when importing such a workshop model, select the.lpktogether with itsconfig.json. - If no JSON is selected, the host tries to auto-identify the matching
config.jsonfrom local Live2DViewerEX workshop directories by file hash; when that succeeds, the single-file import also works. - If auto-detection fails, either upload the pair via the menu, or place
config.jsonnext to the LPK (live2d-lpk.json/<lpk same name>.config.json).
HTTP API
| Route | Description |
| --- | --- |
| /live2d/web/* | Player scripts and renderer libraries |
| /live2d/model/* | Model files (directory or virtual LPK routes) |
| /live2d/player | Legacy iframe player page |
| GET /live2d/api/info | Current model information |
| POST /live2d/api/reload | Re-resolve model / unzip archives |
| POST /live2d/api/import | Upload .lpk (+ optional config.json) |
| GET/POST /live2d/api/tool | Query / toggle live2d_emote tool |
| POST /live2d/api/emote | Play expression / motion / bubble |
| GET /live2d/api/commands?since=N | Player command polling |
| GET/POST /live2d/api/diag | Browser diagnostics |
| GET/POST /live2d/api/message-bubble | Query / toggle AI reply bubbles |
| GET/POST /live2d/api/plugin | Query / toggle the whole plugin |
Repository Layout
live2d-web/
├── README.md # English documentation
├── README.zh.md # 中文说明
├── example.png # Screenshot used by both READMEs
├── LICENSE # MIT license (code only)
├── .gitignore
├── plugin-host.js # Host plugin source
├── direct-player.js # Direct WebGL player source
├── player.html # Legacy iframe player (compatibility)
├── plugin-client-v2.js # Dynamic-plugin client for cordis_define debugging
├── lib/ # Vendored renderer libraries
└── package/ # Publishable npm package
├── index.js # Host loader (dev vs bundled mode)
├── client-direct.js # Web client (menu + settings page)
├── host.js # Built copy of plugin-host.js
├── web/direct-player.js # Built copy of the player
├── web/lib/ # Built copy of lib/
├── MomoseHiyori.lpk # Bundled non-commercial model
├── cordis.patch.yml # Auto-activation patch for DSH bundles
├── scripts/build-release.js # Release build script
└── package.jsonDevelopment
cd live2d-web/package
node scripts/build-release.jsThe build script copies plugin-host.js → package/host.js, direct-player.js → package/web/direct-player.js, and lib/* → package/web/lib/.
package/index.js runs in two modes:
- dev — when
~/.dsh/live2d-web/plugin-host.jsexists, the host loads that source file (edit + restart DSH to apply); - bundled — otherwise it loads the built
host.jsinside the installed package.
Force bundled mode locally with:
LIVE2D_USE_BUNDLED=1 dsh --profile web --port 3080Publishing
cd live2d-web/package
node scripts/build-release.js
pnpm publish --access publicThe npm package contains index.js, client-direct.js, host.js, web/, the bundled model, both README files, NOTICE, LICENSE, and cordis.patch.yml.
License
- Plugin code: MIT.
- Bundled model
MomoseHiyori.lpk: non-commercial; seepackage/NOTICE.md. Do not use it commercially or redistribute the model file separately.
