DSH 网页 GUI 实时桌宠:可把任何 Codex 桌宠图集(webp/png/gif,v1/v2 自动识别)转换为 DSH 中可拖拽的悬浮桌宠。支持拖拽/挥手/跳跃,v2 桌宠的眼睛实时追踪活动鼠标,随 agent 状态切换姿势;进度气泡反映工作状态;「设置 → 桌宠」图形界面可导入、切换与调整桌宠;内置一只原创示例桌宠(娜斯佳),用户桌宠存放在 ~/.dsh/pets。
安装
# npm 包(预构建)
dsh plugin --profile web add @signalight/dsh-codex-pet
# GitHub 源码(首次需按提示配置 allowBuilds 构建授权后重试)
dsh plugin --profile web add github:Signalight/codex-to-dsh-pet#path:/packages/dsh-codex-pet
装任何插件都等于在你的机器上跑第三方代码,权限和你本人一样大——能读你的文件、用你的凭据、访问网络,工具审批管不到它。GitHub 来源的插件还会在安装时执行构建脚本——pnpm 默认拦截,所以安装可能停在 ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED 或 ERR_PNPM_IGNORED_BUILDS;dsh 会打印出需要添加的确切键名,把它加进该 profile 的 pnpm-workspace.yaml 的 allowBuilds 下,重跑一次即可装上。放行构建本身就是一次信任判断:请只安装可信来源,并尽量锁定 commit(github:owner/repo#sha)。
README
该插件的 README 只有英文版本。
A DSH web-GUI pet runtime plugin — one plugin that renders any Codex spritesheet-atlas pet (v1 / v2) as a draggable desktop pet in the DeepSeek Harness web GUI.
It is the runtime half of the
codex-to-dsh-pet framework:
instead of building each pet into its own plugin bundle, you install this
plugin once, then add pets as plain data files — no per-pet code.
The plugin ships one built-in example pet
nastya(娜斯佳) — an original character (CC BY-NC 4.0, non-commercial) — so the registry is never empty. Seeassets/nastya/.
Features
- Renders Codex spritesheet atlases (8 columns × 192×208 cells):
- v1 (1536×1872, 9 rows) — auto-detected;
- v2 (1536×2288, 11 rows) — adds 16 mouse-tracking "look" cells.
- Draggable (position persists across restarts), wave-on-hover, jump-on-double-click.
- Opt-in mouse tracking (v2 only, default on): the «桌宠» settings section has an Eye tracking toggle; the UI notes it applies to v2 atlases only (v1 has no look cells, so the toggle is inert for v1 pets).
- Live activity poses: idle / waiting / running / review, driven by the conversation state.
- Progress bubble showing the running tool name or the live model text tail.
- Optional fixed-interval first-person LLM summaries, with a per-session journal shown when hovering the pet. Automatic summaries observe only requests completed after selecting a session; they do not backfill historical conversations. Right- click the pet to explicitly analyze prior unsummarized requests. This is disabled by default. Enabling it sends bounded excerpts of user, assistant, tool, and error content to the selected LLM and incurs that provider's usage/cost. Select a provider and model before enabling summaries. Cadence and bubble duration are configurable.
- Configurable completion, error and interruption voices, including per-track volume, bundled rotating takes and user-uploaded audio overrides.
- Zero per-pet code: the browser half is registry-driven from
/api/codex-pet/*.
DSH compatibility
DSH gates every profile plugin row on its @deepseek-ai/dsh* peerDependencies:
a peer range the running DSH version does not satisfy disables the whole row
(no pet, no settings section) with
Plugin … is incompatible with dsh …: peerDependencies ….
This plugin therefore declares only peers that exist across the DSH 0.2 line and later, with open-ended ranges:
"@deepseek-ai/dsh-client-ui-slots": ">=0.1.0-rc.6",
"@deepseek-ai/dsh-host-webserver": ">=0.1.0-rc.6"
It works on 0.1.x and on 0.2.0-rc.1+. The obsolete
@deepseek-ai/dsh-client-runtime peer is not declared: DSH 0.2.0-rc.1 removed
that package, so declaring it (^0.1.0-rc.6, as 0.3.1 did) makes DSH disable the
row — which is exactly why the pet vanished on 0.2.0-rc.1.
The same upgrade also retired the client runtime at runtime, not just in the
manifest. On 0.1.x the pet overlay read the conversation from
sessions.currentProvideInfo; that bridge is gone in the 0.2 line, which would
leave the snapshot null and the bubble permanently blank (0.3.2 had this bug —
the pet appeared but never spoke). The overlay now reads the internal
uiSession service's main binding instead:
hooks.chat→ the live tail (partial,runningCalls) plusturnEnds; this is the targetdsh-client-ui-chatregisters, i.e. the streaming reply text and the "running: <tool>" bubble text;hooks.trajectory→ the same fields plusrequests, kept as a fallback when the chat hook is absent (its ownpartialonly fills in once its target has accumulated chunks);hooks.session→running,pendingSubmissions,openState;nodes/turnEndsare rebuilt from the trajectory event nodes, keeping the done chime and the periodic summaries working.
uiSession is deliberately not listed in inject: it is an internal service
that older hosts never provide, and Cordis parks the entire plugin when a hard
dependency is missing. It is resolved lazily with ctx.get("uiSession") (plus a
short polling subscribe, because the service can arrive after the plugin loads),
and when it never shows up the overlay falls back to the legacy
currentProvideInfo path — so one build serves both hosts.
Install
Recommended — one command (needs pnpm):
# from npm
dsh plugin --profile web add @signalight/dsh-codex-pet
# or straight from GitHub
dsh plugin --profile web add github:Signalight/codex-to-dsh-pet#path:/packages/dsh-codex-pet
Manual route (no pnpm): from the repository root run
.\install-runtime.ps1
This copies the package into ~/.dsh/profiles/node_modules/@signalight/dsh-codex-pet and
registers the plugin row in ~/.dsh/profiles/web/cordis.patch.yml. Then:
- Hard-refresh
http://127.0.0.1:3080(Ctrl+Shift+R) — the DSH profile hot-reloadscordis.patch.yml. If the pet still doesn't show, fully quit and relaunch the DSH desktop app (command-line users can restartdsh web).
Rollback: delete ~/.dsh/profiles/node_modules/@signalight/dsh-codex-pet and restore the
.bak next to the patch file.
Add a pet
A pet is a folder holding a pet.json manifest plus one atlas image. Drop it
into either source (user pets override built-ins on id collision):
- built-in:
packages/dsh-codex-pet/assets/<pet>/ - user:
~/.dsh/pets/<pet>/(survives plugin updates)
pet.json:
{
"id": "nastya",
"displayName": "娜斯佳",
"description": "娜斯佳 Nastya — original character (CC BY-NC 4.0).",
"spritesheetPath": "spritesheet.webp",
"spriteVersionNumber": 2,
"size": 120,
"pin": "bottom-right"
}
Only id and spritesheetPath are required. spriteVersionNumber is
auto-detected from the image dimensions when omitted; size (px width) and
pin (top-left / bottom-right / …) default to 120 and bottom-right.
No manual editing needed: in the DSH settings surface open the «桌宠»
section and click 导入桌宠 (webp / png / gif) — the plugin writes the file
into ~/.dsh/pets/<name>/, auto-detects the atlas version, and selects the new
pet. The pet id comes from the filename (my-pet.webp → my-pet); if that id
is already taken the plugin appends a -2 / -3 suffix instead of
overwriting the earlier pet (all Codex atlases are named spritesheet.webp,
so without this every import would clobber the previous one). Re-importing the
same id with the same typed display name updates that pet in place.
Architecture
src/
├── index.js host half: name/inject/apply, mounts service + routes
├── registry.js scans assets/* + ~/.dsh/pets/*, normalizes Codex atlases
├── service.js persisted selection + display config (~/.dsh/codex-pet.json)
├── routes.js /api/codex-pet/* JSON API + /codex-pet/<id>/* assets
└── client.js browser half: registry-driven overlay renderer
- Host half registers same-origin routes via the DSH web server
(
ctx.webServer.register), serving the pet list, state and atlas assets. - Browser half fetches
/api/codex-pet/state, renders the selected pet, mirrors drags back viaPOST /api/codex-pet/set-config, and seats asettings.sectionentry («桌宠») that edits the pet through the same API.
API
| Endpoint | Method | Purpose |
|---|---|---|
/api/codex-pet/pets |
GET | pet registry (list of definitions) |
/api/codex-pet/state |
GET | selected pet + display config |
/api/codex-pet/set-pet |
POST | { petId } — switch pet |
/api/codex-pet/set-config |
POST | update display, summary, or sound settings |
/api/codex-pet/set-visible |
POST | { visible } |
/api/codex-pet/import?id=<filename>&name=<displayName> |
POST | raw image body — import a Codex atlas |
/api/codex-pet/models |
GET | available LLM providers and models for summaries |
/api/codex-pet/summarize |
POST | summarize one completed assistant-request batch |
/api/codex-pet/journal?session=<id>&limit=<n> |
GET | recent persisted summaries (&all=1 returns all records for manual coverage checks) |
/api/codex-pet/sound?track=<id> |
POST | upload a raw audio override (8 MiB maximum) |
/api/codex-pet/reset-sound?track=<id> |
POST | remove an audio override |
/codex-pet-sound?track=<id> |
GET | stream the effective done, error, or interrupt track |
/codex-pet/<id>/<file> |
GET | pet.json + spritesheet assets |
Summary journals are stored under ~/.dsh/codex-pet-journal/. Uploaded voice
overrides are stored under ~/.dsh/pets/sounds/ and survive plugin updates.
Roadmap
- Settings section («桌宠» in the DSH settings surface: pet selector, show/hide, size, corner pin, bubble color/opacity, eye tracking — the last is v2-only and noted as such), backed by the plugin's own API.
- In-GUI import button (upload a Codex atlas → auto-detect → install → select).
- In-GUI preview before import (live canvas frame preview).
- Published to npm (
@signalight/dsh-codex-pet) +dsh-pluginGitHub topic.
License
MIT — see the repository root LICENSE.
Built-in scenario voice / sound assets
The plugin ships 8 built-in scenario sounds under assets/sounds/
(done-1~4.wav, error.wav, interrupt-1~3.wav):
- Attribution: these sounds were generated by contributor @yabo083 (PR #4) using Qwen3-TTS VoiceDesign and submitted with the plugin; they were reviewed and accepted into this package, and are distributed under MIT together with the plugin.
- Generator license: the Qwen3-TTS model repo is Apache-2.0; that license applies to the model repo only and does not change this project's license. Using Qwen3-TTS does not imply endorsement by Qwen.
- Relationship to the character: these lines are usually performed as the
built-in example pet
nastya(娜斯佳). That character is an original character, and its atlas is licensed CC BY-NC 4.0 (non-commercial), so even though the sound files are MIT-licensed, using them as that character's voice keeps the character's non-commercial restriction in force; ask the character's author before any commercial use. - User audio: you may upload your own audio to replace any scenario sound (Settings → 完成提示音); custom audio's copyright and license are your own responsibility.
链接
同类插件
PC2005-cloud/dsh-pet#dsh-pet★ 960
DSH Web UI 桌面宠物:25 个透明动画、屏幕漫游、点击反应与拖拽,附可复现的素材生成链。
Nagi-ovo/dsh-ads★ 643
2005 年中文站点风格的整活广告插件:侧栏广告/信息流/角落弹窗 + 假关闭叉,素材全虚构。
vlln/whale-girl★ 339
桌面宠物(QQ 宠物形态):右下角悬浮、可拖拽/投喂/玩耍。
a86582751/dsh-nexttavern★ 128
面向 DeepSeek Harness 的角色扮演工作台:人物卡可以导入(SillyTavern/TauriTavern),也可以从零交互式写出一张;长篇 TXT 能改编成可玩的角色卡,精读或粗颗粒度两种读法;主代理按剧情主动查阅世界书,正文在独立的酒馆阅读 TAB 中呈现;同一对话里探索多条世界线(重新生成、改后发送、显式分支);带作用域的文风预设(16 种自带文风)、角色 Agent 集群、独立决策卡,以及角色卡或小说导出;长篇由固定设定前缀、硬切上下文窗口、可追溯导演笔记与关键词/语义/混合检索撑住,嵌入可用在线服务,也可完全本地运行。面向 Harness 0.1.2-alpha.3,安装需按文档应用显式兼容补丁。
yyh-001/dsh-meme★ 120
聊天表情包:纯文本斗图、情绪主动发图、像 QQ/微信 一样发图、AI 自动学图、自定义表情包。
Sutera-Diffusus/dsh-whale-musume★ 106
元气鲸鱼娘桌宠:摸头养成、按工具类型联动的工作状态、494 条台词、30 项成就、成长日记、拖拽惯性、主题适配与无障碍模式。关键词感知与余额关心默认关闭、需手动开启;可选的天气心情只在你填了城市后才会请求 Open-Meteo。无遥测。
社区评论
评论公开保存在 GitHub Discussions。加载评论会连接 GitHub 和 Giscus;发表内容需要 GitHub 账号。