dsh-plugin-pet
A virtual pet companion for the DeepSeek Harness web GUI: mood animations driven by live agent state, built-in sprites, custom image upload, and Codex-style multi-frame spritesheet import.
AI 分析
核心用途是提供一个能根据 AI 思考、报错等状态做出动画反馈的桌面宠物。适合想要增加界面趣味性和陪伴感的用户。
インストール
検証済み bundle がないか、互換性チェックに失敗しています。先にリポジトリの説明を読んでください。 README 全文を読む ↗
ドキュメント
README 全文を読む ↗dsh-plugin-pet
A virtual pet companion for the DeepSeek Harness web GUI: built-in, custom, and Codex-style sprites with mood animations driven by live agent state.
A desktop pet for DeepSeek Harness Web GUI, inspired by the Codex companion and Claude Code Buddy. The pet lives in the bottom-right corner and reacts in real time to the agent state (thinking / tool calls / errors / turn completed / waiting for you), with rename, scale, visibility, and full reskinning support:
- 6 built-in sprites (blob / cat / duck / robot / axolotl / ghost; inline SVG, pure CSS animation)
- Custom image upload (PNG / JPEG / GIF / WebP; animated images play as-is)
- Codex-style multi-frame spritesheets — import a Codex pet pack
(
pet.json+spritesheet.webp, V1 1536×1872 and V2 1536×2288; see the Codex pet package spec), or configure a generic grid (columns / rows / fps / per-mood state rows)
All state is stored under $DSH_HOME/storages/dsh-plugin-pet/ and survives dsh web
restarts.
Structure
| File | Purpose |
|---|---|
lib/index.js | Host plugin: pet persistence + HTTP routes mounted on the harness webServer service |
lib/client.js | Browser bundle (hand-written factory-CJS, no build step): pet overlay and settings panel |
test/ | node --test suite covering host routes and the zero-dependency image sniffer |
This is a dual-face package: the host half is a plain Cordis plugin; the client half is
declared through "dsh": { "client": { "platform": "web", "inject": [], "immediately": true } }
plus the "./client" export, so the harness client-modules system serves it at
/plugins/dsh-plugin-pet/client.js and loads it immediately at boot.
Install
Install into the web profile from GitHub (requires pnpm on PATH; otherwise use the
corepack fallback below):
npx @deepseek-ai/dsh plugin --profile web add "github:c-ling/dsh-plugin-pet#v1.0.2"
Or with an existing dsh binary:
dsh plugin --profile web add "github:c-ling/dsh-plugin-pet#v1.0.2"
When pnpm is not on PATH:
cd ~/.dsh/profiles/web
corepack pnpm add "github:c-ling/dsh-plugin-pet#v1.0.2"
dsh pluginforwards its arguments to pnpm and fetches the package from this repo (pnpm 9+,gitrequired). The warningdeclares no dsh.bundle — installed as a plain dependencyis expected: this plugin is not a profile bundle layer; it is activated by the loader row below.
Then add a loader row to ~/.dsh/profiles/web/cordis.patch.yml:
- insert:
- id: dsh-plugin-pet
name: 'dsh-plugin-pet'
config:
maxImageBytes: 5242880 # optional: single-image upload limit (default 5 MB)
maxSheetBytes: 10485760 # optional: spritesheet upload limit (default 10 MB)
Restart dsh web (client-modules caches package verdicts per process; new packages require a
host restart), then hard-refresh the page. The pet appears in the bottom-right corner; its
settings live under Settings → Pet.
Verify
curl -s http://127.0.0.1:3080/plugins/dsh-plugin-pet/client.js | head -c 60
It should print a factory bundle starting with window.__ModuleLoader__.load({; the pet
should be visible in the bottom-right corner.
Update
dsh plugin --profile web add "github:c-ling/dsh-plugin-pet#v1.0.2"
# or: npx @deepseek-ai/dsh plugin --profile web add "github:c-ling/dsh-plugin-pet#v1.0.2"
# or: cd ~/.dsh/profiles/web && corepack pnpm add "github:c-ling/dsh-plugin-pet#v1.0.2"
Re-running the install command with the new #v1.0.2 pin upgrades the dependency;
the loader row in cordis.patch.yml stays unchanged. Restart dsh web, then hard-refresh.
Uninstall
cd ~/.dsh/profiles/web
corepack pnpm remove dsh-plugin-pet # or: dsh plugin --profile web remove dsh-plugin-pet
Remove the matching insert row from cordis.patch.yml, then restart dsh web.
Uploaded data remains under $DSH_HOME/storages/dsh-plugin-pet/ until you delete that
directory manually.
Using the pet
- Drag the pet anywhere; the position is remembered per browser.
- Single-click pets it (hearts pop out). Double-click hides it; click the paw button to bring it back.
- Mood is derived from the live session state: idle, thinking, working (the bubble shows the current tool name), sad (prompt error), waiting (pending confirmation), plus a celebratory hop when a turn finishes.
Codex spritesheet import
- Go to Settings → Pet → Spritesheet → Import a Codex pet pack.
- Upload
spritesheet.webp/spritesheet.pngfirst. It must be 1536×1872 (V1, 9 rows) or 1536×2288 (V2, 11 rows) — an 8-column grid with 192×208 cells. The version is auto-detected. - Optionally import
pet.json— it appliesdisplayNameand verifiesspriteVersionNumberagainst the uploaded spritesheet.
Codex rows map to DSH moods as: idle→0, thinking→8 (review), working→7 (running), happy→4 (jumping), sad→5 (failed), waiting→6, petting→3 (waving). Direction rows (1/2) and V2 facing rows (9/10) are unused by this plugin.
Generic spritesheet
Under Spritesheet → Generic spritesheet, any PNG/WebP whose width and height divide evenly into the grid works: set columns, rows, and fps, upload the image, then assign a row and frame count to each mood. A live preview player animates the draft before saving.
HTTP API
| Method | Path | Purpose |
|---|---|---|
| GET | /dsh-plugin-pet/config | Current effective pet configuration |
| POST | /dsh-plugin-pet/config | Update name / size / visibility / builtin sprite / sheet fps, state rows, frame counts |
| GET/POST/DELETE | /dsh-plugin-pet/image | Read / upload (raw bytes) / delete the custom image |
| GET/POST/DELETE | /dsh-plugin-pet/sheet | Read / upload (raw bytes; ?source=codex&version=1|2|auto or ?source=custom&cols=&rows=&fps=) / delete the spritesheet |
| POST | /dsh-plugin-pet/petjson | Import a Codex pet.json (requires a matching spritesheet already uploaded) |
All uploads are validated server-side: magic-byte sniffing (PNG/JPEG/GIF/WebP), size limits, exact Codex dimensions, and even cell splitting for generic grids. Config writes are atomic.
Development
node --check lib/index.js lib/client.js
node --test test/sniff.test.mjs test/host.test.mjs
The client bundle is pure JavaScript in the harness factory-CJS format
(window.__ModuleLoader__.load({ id: "dsh-plugin-pet", factory })); require("react")
resolves through the shell static module table. All UI contributions are registered via
the shell.overlay and settings.section slots and managed by disposers held through
ctx.effect.
Known limitations
- One global pet per page (root-scope overlay), not per session.
- Codex “trailing empty frames” auto-detection is not implemented; frame counts come from the spec defaults or your explicit configuration.
- The pet position is stored per browser (
localStorage) and is not synced across devices. - Activating the plugin requires restarting the
dsh webhost process (the web profile disables Cordis HMR for host rows by default).