silverhand-dsh-pet
Silverhand desktop pet for DeepSeek Harness — drag to move, reacts to agent state.
- Stars
- 1
- Language
- JavaScript
- Created
- Aug 19, 2026
- Updated
- Aug 19, 2026
Introduction
Silverhand — DSH Desktop Pet
A desktop pet for the DeepSeek Harness Web GUI. Silverhand (a cyberpunk mercenary with a silver cybernetic arm) lives in the bottom-right corner and reacts to what the agent is doing — idle breathing, active work, reviewing output, waving hello, celebrating a finished turn, sulking on an error, and waiting for your approval.
The character artwork is migrated as-is from the Codex pet format — no
redesign, just the original spritesheet.webp + pet.json.
Features
- Renders in the frame-wide
shell.overlaylayer, fixed to the bottom-right. - Click-through by default (only the pet itself is interactive).
- Reacts to real agent state, driven by DSH host events:
idle/runningfromagent/statusreviewfromtools/resultfailedfromagent/errorwavingfromagent/created/agent/session-startjumpingwhen a turn finishes (running→idle)waitingwhile an approval request is open (approval/request)
- Drag the pet to move it — it walks left/right in the drag direction.
- Hover to see the current state; click (no movement) to make it jump.
- The sprite atlas is embedded directly in
src/host.js, so the plugin is fully self-contained — clone it anywhere and it works with zero config.
Layout
Silverhand/
├── README.md
├── LICENSE
├── .gitignore
├── package.json
├── assets/
│ ├── pet.json # migrated Codex manifest
│ └── spritesheet.webp # migrated sprite atlas (8×9, 192×208 cells)
├── src/
│ ├── host.js # DSH host half (asset + state)
│ └── client.js # DSH client half (renderer)
├── scripts/
│ ├── embed-sprite.js # regenerate the embedded atlas in src/host.js
│ ├── make_demo_gif.py # render docs/demo.gif (animated demo)
│ ├── analyze_frames.py # measure per-row frame counts / diffs
│ └── contact_sheet.py # render a labeled contact sheet
└── docs/
├── demo.gif # animated demo (all animations)
└── sprite-atlas.md # atlas layout + state mapping
Anatomy
A DSH plugin is a Cordis plugin split into two halves:
- Host (
src/host.js) runs in the DSH Node process. It embeds the sprite atlas as base64 (no filesystem path), serves it over HTTP (with a data-URI fallback), and derives the pet state from agent events. It exposes two package-private RPC methods:getStateandgetSprite. - Client (
src/client.js) runs in the browser. It registers intoshell.overlay, renders the sprite, and pollsgetStateevery 300 ms, animating the matching atlas row.
The two halves communicate over the package-private RPC (harness.handle on
the Host, host.call on the Client).
Run it (dynamic package)
The quickest way to try it is the DSH dynamic-plugin mechanism. In a DSH
session, load the two source files and pass their contents as code.host /
code.client to cordis_define, then cordis_run.
No setup needed: the sprite is embedded in
src/host.js, so both halves work straight out of the box on any machine.
Persistent install
A dynamic package does not survive a process restart. To install permanently, copy the plugin into a preset composition:
- Copy this repo into a stable location (e.g. keep it where it is).
- Add the two halves as plugin rows in a
cordis.ymlcomposition — one row for the host half, one for the client half — pointing atsrc/host.jsandsrc/client.js, or inline their bodies. - Mount that preset for the sessions that should show the pet.
See the DSH composition docs for the exact cordis.yml schema for your
deployment. The inject declarations matter: the host half needs webServer
and agents; the client half needs slots and timer.
Configuration
All tunables are constants at the top of each half:
src/host.js—ROUTE_PATHand the per-state transient durations in the event listeners. The sprite is the embeddedSPRITE_B64block; after replacingassets/spritesheet.webp, regenerate it withnode scripts/embed-sprite.js.src/client.js—ANIMS(row / frame count / cadence per animation),STATE_ANIM(state → animation),PET_W/PET_H(display size), and theCSSblock (position, shadow, hover).
Asset provenance
The artwork was migrated from the local Codex pet directory
(~/.codex/pets/silverhand/). It is your asset — before publishing this
repo to GitHub, confirm you hold (or have) the right to redistribute the
sprite and the Silverhand likeness. The code in this repository is MIT
licensed; the sprite's licensing is yours to state.
Development helpers
# Regenerate the embedded sprite after changing assets/spritesheet.webp
node scripts/embed-sprite.js
# Regenerate docs/demo.gif
python scripts/make_demo_gif.py
# Report per-row opaque-cell counts and consecutive-frame deltas
python scripts/analyze_frames.py
# Render a labeled contact sheet (full + zoomed ambiguous rows)
python scripts/contact_sheet.py
analyze_frames.py / contact_sheet.py require Python 3 with Pillow and
numpy.