DeepSeek Harness Plugin

Gin-7/dsh-pet-remielle

Stars ★ 47 Downloads (30d) 2,033 Category Just for Fun Added 2026-08-17 npm dsh-pet-remielle

A Remielle(ZZZ) desktop pet for the dsh web GUI that switches animated sticker moods with the harness work state.

Install

# from npm (prebuilt)

dsh plugin --profile web add dsh-pet-remielle

# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)

dsh plugin --profile web add github:Gin-7/dsh-pet-remielle

Any plugin you install runs third-party code with your own permissions — it can read your files, use your credentials, and reach the network, and tool approvals don’t sandbox it. GitHub-sourced plugins also run build scripts at install time — pnpm blocks those until you allow them, so an install can stop with ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED or ERR_PNPM_IGNORED_BUILDS; dsh prints the exact key to add under allowBuilds in your profile’s pnpm-workspace.yaml, and the install works on the next run. Allowing a build is a trust decision: only install sources you trust, and pin a commit (github:owner/repo#sha).

README

A multi-pet web desktop pet driven by real DSH session events — it tracks DeepSeek Harness task progress in real time and presents it with sticker animations + status bubbles.

  • Multi-pet registry + status bubbles (project / phase / tasks / progress in real time)
  • SSE live push + optional desktop floating window (bundled Electron, transparent & always-on-top)
  • Double-click drawing: brush-reveal artwork (drawing → satisfied → fade-out)
  • Built-in version check + one-click incremental update
  • Settings panel: pet management (tabbed) + plugin config card

Compatible with DeepSeek Harness (and its forks) web profile; desktop mode is off by default and can be enabled anytime. Desktop mode requires DSH >= 0.1.2-alpha.1 to provide an authenticated root URL with a launch token.


Features

Capability Details
State source DSH session/event real events — no DOM scraping
State machine Pure-function PetReducer with mood mapping (unit-tested)
Message protocol Typed protocol (protocol.js)
Configuration schemastery persistence + settings card
Multi-session priority Approval > plan review > waiting for an answer (ask_user_question) > completion reminder > waiting/error > current session > state priority > recency. Hysteresis only stabilizes the top two; third and later still rotate with recency
Live push SSE stream (auto-reconnect + polling fallback)
Status bubble Adaptive two-layer deck on both the in-page pet and the desktop window: top status card + +N summary backboard; message + detail (project · completed x/y · phase)
Session actions Web and desktop match: card / ? / ! open the session, ✓ allows once; with no web client online, a card/icon click opens the DSH page in the system browser
Completion reminders Persist until handled; a completion on the current session is auto-cleared only by a foreground browser tab (even while the desktop window is up), so background tabs never clear a reminder ahead of you; the desktop window only shows the reminder — opening that session (in-page jump, browser, or clicking the desktop completion card) also clears it. The already-open session has no unread dot (current Host lifetime only)
Error reminders A failed turn (model-call error, etc.) keeps the pink attention mark until that conversation is opened; a failure in the current session never becomes a reminder. Opening the session (bubble jump or sidebar) dismisses it. Approvals and questions are unchanged
Balance With both status and usage on, the left dot or a wheel on the bubble switches to the balance page (60s auto-refresh, rolling-number animation, stale fallback on network blips); stays on the current page, no auto-return
Today usage Two modes: ledger (default, token-free, balance-delta) / real-time token (platform usage API + peak/off-peak pricing, exact)
Desktop float Bundled Electron transparent always-on-top window (opt-in)
Multi-pet Settings → Pet Management (registry + switch active pet)
Version update Built-in check + one-click incremental update

Sticker (mood) → State Mapping

Sticker Preview Trigger
01 Drawing THINKING + streaming: streaming output / double-click drawing
02 Slacking WORKING / ERROR: tool calls (search/edit/test/command)
03 Pleased PULSE SUCCESS: turn completed / drawing finished / click interaction
04 Thinking THINKING: turn/step start, reasoning, result compilation
05 Waiting WAITING: question answer, approval pending, plan review, turn blocked
06 Idle IDLE / DISCONNECTED: idle, after turn ends

When multiple sessions run concurrently, the top task is selected by approval > plan review > waiting for an answer > completion reminder > waiting/error > current session > state priority > recency; every other session is represented by a clickable +N summary backboard. Sub-agents are ignored by default (configurable).

Pet Definition Convention

assets/pets/<id>/01.gif  Drawing (output)
assets/pets/<id>/02.gif  Slacking (tools/errors)
assets/pets/<id>/03.gif  Pleased (completed/interaction)
assets/pets/<id>/04.gif  Thinking
assets/pets/<id>/05.gif  Waiting
assets/pets/<id>/06.gif  Idle

Optional extensions (don't affect completeness validation):

assets/pets/<id>/07.gif           Extra sticker slot
assets/pets/<id>/pet-manifest.json  Per-sticker alignment offsets + artwork count
assets/pets/<id>/pics/<n>.png      Artwork images (double-click to pop, n starts at 1)

id may contain only letters, numbers, underscores, and hyphens. Built-in pet: Remielle (see NOTICE for asset copyright).


Installation

For DSH / DeepSeek Harness (including Fairy and other DSH-based forks) web profile.

# Option 1: npm registry (recommended, one-click incremental update)
dsh plugin --profile web add dsh-pet-remielle

# Option 2: GitHub repository (build install, no version check)
dsh plugin --profile web add github:Gin-7/dsh-pet-remielle

# Option 3: Local directory (dev/debug, link install)
dsh plugin --profile web add D:\path\to\dsh-pet-remielle

# Option 4: GitHub Release tgz
dsh plugin --profile web add "C:\Users\you\Downloads\dsh-pet-remielle-<version>.tgz"

Plugin row id: dsh-pet-remielle. Uninstalling removes everything cleanly.


Updating

Built-in update check in Settings → Pet Management → Update + bottom-right update bubble: checks GitHub for the latest version and offers one-click update.

Install type Version Update method
Local link ≥ 0.3.0 One-click git pull (incremental)
npm registry ≥ 0.3.0 One-click pnpm update dsh-pet-remielle (incremental)
Any type < 0.3.0 No auto-update: package/row-id changed since 0.3.0 — must fully uninstall then reinstall

Why? Before 0.3.0 there were package/row-id renames (before 0.2.0 it was @dsh-external/dsh-client-ui-pet-remielle, from 0.2.0–0.3.0 it was dsh-pet-remielle). git pull/pnpm update can't cross that boundary, so versions below 0.3.0 must be uninstalled first (otherwise you get loaded without registering … via __ModuleLoader__.load errors):

# Uninstall by the actual old row id (whichever applies):
dsh plugin --profile web remove @dsh-external/dsh-client-ui-pet-remielle   # <= 0.2.0
dsh plugin --profile web remove dsh-pet-remielle                            # > 0.2.0

# Reinstall latest:
dsh plugin --profile web add dsh-pet-remielle
# or: dsh plugin --profile web add github:Gin-7/dsh-pet-remielle

The same uninstall/reinstall guidance is shown in Settings → Pet Management → Update when the installed version is below 0.3.0.


Desktop Floating Mode (opt-in)

desktopMode is off by default. When enabled, a transparent, always-on-top, frameless Electron window displays the pet.

  • Window supports dragging (position remembered), scroll-wheel zoom, double-click drawing, right-click menu.
  • Status/balance bubbles match the web pet: stacked session cards, a single toggle dot, the same tooltips and click behavior; ✓ still clicks Allow once.
  • Known limit: the sidebar “pending content” green-dot feed is synced only while a web client is online. Reminders that appear while the page is closed may be missing from the desktop bubble until the page is opened again.
  • The desktop window compensates UI size from the system scale so it matches the in-page pet.
  • Double-click drawing: artwork appears in a desktop top-right independent window, brush-reveal along the diagonal, then "Pleased → fade-out".
  • Right-click menu: switch to web mode, lock, bubble toggle, size, drawing, etc.
  • Closing/switching returns to the in-page pet automatically; the window closes when the DSH host exits (within 1 second).
  • The desktop window's Electron data dir is pinned under the system application-data directory (%APPDATA%\dsh-pet-remielle on Windows) instead of a temp dir, which disk-cleanup tools would wipe along with its cache. Only one desktop window may hold it at a time: on detecting another live instance (host restarted while the old window is still exiting) it falls back to a pid-suffixed sibling directory, so the two never share one Chromium cache.

Electron runtime sources (probed in order): DSH_PET_ELECTRON → vendor/electron-<platform>-<arch>/ (not in Git; downloaded for the current system) → system-installed Electron → none → in-page only.

First run: if desktop mode is enabled but no Electron runtime is found locally, a prompt will offer to download and install it (requires confirmation, about 100–220 MB). Download failure falls back to in-page display automatically. You can also manually extract the matching Electron release to vendor/electron-<platform>-<arch>/ or set DSH_PET_ELECTRON to an existing executable (electron.exe on Windows, Electron.app/Contents/MacOS/Electron on macOS, electron on Linux).

Platform support

Platform Desktop float In-page pet
Windows x64 ✓ (Electron transparent window) Hidden when desktop mode is on
macOS (arm64 / x64) ✓ (matching darwin runtime) Hidden when desktop mode is on
Linux x64 ✓ (matching linux runtime) Hidden when desktop mode is on

Usage

  • Single-click pet: cycle through random sticker moods.
  • Double-click pet: enter drawing animation; after completion a artwork pops up (screen top-right) and fades out.
  • Right-click pet: the same menu in-page and in the desktop window (same width and order, sliders aligned) — character size / opacity / mirror / lock position / pause animation / show bubble / drawing / reset position / desktop float mode. "Reset position" clears both the in-page and the desktop-window position at once; "Pause animation" freezes on the currently displayed frame (not the first frame) — exact on secure contexts (127.0.0.1 / localhost / https), falls back to the first frame over plain-HTTP LAN addresses; resuming replays the GIF from frame 0 (an inherent consequence of re-assigning src — <img> cannot seek to a given frame).
  • Settings-only: enable / hide pet, pet management, respond to sub-agents, usage mode and platform token, bubble sub-toggles and bubble-scaling details — these are either low-frequency or would remove their own entry point (hide pet), so they stay out of the right-click menu.
  • Both ends share one theme source: the in-page menu/bubbles and the desktop window use the same colours and follow the same theme — the page reports the host theme (body[data-ds-dark-theme]) and the desktop window colours itself from that report; with no web client online (or the report expired) it falls back to the system light/dark setting, which stays a sensible default for a standalone window. Rows, order and geometry match item by item as well (a toggle's check mark never changes its row height), and a cross-file assertion pins the colours.
  • Bubble paging: with both status and usage on, the left dot or a wheel on the bubble switches between the status card and the balance page; stays on the current page, no auto-return.
  • Scroll wheel (pet): resize character.
  • In-page pet menu can also launch the desktop window.

Balance & Today Usage

With both status and usage on, the left dot or a wheel on the bubble shows your DeepSeek account balance and today's spend (bubble shows "DeepSeek Balance ¥X" + "Today ¥X · Off-peak/Peak", the period is color-coded: green = off-peak, red = peak). Usage-only shows the balance page directly. Stays on the current page; does not auto-return to status.

  • Balance: from the official API api.deepseek.com/user/balance (credential DEEPSEEK_API_KEY). Auto-refreshes every 60s; switching to the balance page fetches once; rolling-number animation on changes; transient network blips keep the last known balance instead of flashing errors.
  • Today usage · ledger (default, token-free): accumulates balance deltas into $DSH_HOME/.dshp-usage.json (cross-day reset & archive). No extra token needed, but it is an estimate — usage while DSH is off is not recorded.
  • Today usage · real-time token (exact): after configuring the platform session token DEEPSEEK_PLATFORM_TOKEN, it queries the platform cost API (platform.deepseek.com/api/v0/usage/by_api_key/cost) and reads the platform's own per-hour CNY amount — no local pricing table, so DeepSeek price changes are followed automatically:
    • The bubble also shows the current period (off-peak / peak): on workdays peak is 09:00–12:00 and 14:00–18:00 Beijing time, while Saturdays, Sundays and Chinese public holidays are off-peak all day (weekends that are adjusted workdays still count as off-peak, matching the official rule). The holiday calendar falls back to a built-in table and silently refreshes a public calendar in the background (cached at $DSH_HOME/.dshp-holidays-<year>.json), issuing a year-only request on first use or after expiry
    • Falls back to ledger mode when the token is missing or invalid

Switching usage mode: Settings → Pet Management → Behavior → "Usage Mode" (ledger / real-time token). It is a configuration choice rather than a live tweak, so it lives in Settings only.

To obtain DEEPSEEK_PLATFORM_TOKEN: sign in to platform.deepseek.com → F12 DevTools → Network → open the "Usage" page → copy the Authorization header value of the api/v0/usage/... request → add it to the DSH credentials service.


Configuration (Settings → Plugin → Remielle Desktop Pet)

Field Default Description
enabled true Enable the pet (disables immediately, re-enabling restores)

All other appearance/behavior options (size, opacity, mirror, lock, bubble, usage mode, desktop float, pause, hide, etc.) live in Settings → Pet Management, not duplicated in the plugin config card. The few that are instantly visible and high-frequency also appear in the right-click menu (list under "Usage") — both ends share one skeleton and one set of labels, so changing one means changing the other.

Settings → Pet Management

Pet registry as its own tab, alongside Appearance / Pets / Behavior / Desktop Float / About (five tabs).

  • Enable/disable pets, set as current, rename, add new pets; pets with a missing directory or incomplete stickers show the reason on the card (the enable switch is disabled alongside).
  • Behavior page: enable / lock / pause / hide / respond to sub-agents / show bubble / usage mode.
  • "Update": shows current version, check for updates, one-click update, upgrade guide.
  • "Feedback": shows pet version, submit bug reports / feature requests.

Development

npm install
node scripts/build-client.mjs    # Build lib/client.js (version injected from package.json)
npm test                          # node --test unit tests
npm run check                     # Syntax check

Directory Structure

src/
├── index.js          # Host: config, event wiring, config/state/balance/pets/assets/desktop endpoints, self-update routes
├── balance.js        # Balance service: fetch (retry/cache/stale fallback), today usage (ledger/token), peak pricing
├── holidays.js       # Holiday calendar: peak/off-peak decision (weekends & public holidays are off-peak all day), builtin table + remote refresh + disk cache
├── self-update.js    # Version check + one-click update (GitHub direct + HTTP proxy fallback; git pull / pnpm update)
├── pet-reducer.js    # Pure state machine: session events → state/pulse/task (unit-tested)
├── protocol.js       # Typed protocol: PetState / PetMood / PetMessageKind
├── pets.js           # Pet registry: directory discovery/merge/validation (unit-tested)
├── status-copy.js    # Remielle-flavored status copy (replaceable)
├── turn-watchdog.js  # Turn-hang watchdog: recovers a session stuck in THINKING after a forced kill
├── desktop-window.js # Desktop mode: Electron discovery + window process management (unit-tested)
├── electron-fetch.mjs # On-demand cross-platform Electron runtime download and extraction
├── pet-window.cjs    # Desktop mode: Electron main (transparent window + top-right artwork window)
├── pet-window-paths.cjs # Pet-window userData directory policy (isolated from the host's Electron)
├── pet-preload.cjs   # Pet-window preload: page ↔ main bridge (click-through, drag, hit rects, menu expand)
├── pet-view.html     # Desktop mode: pet window page (GIF + bubble + SSE + drawing + balance bubble)
├── balance-widget.js # Balance controller (client): fetch/rolling animation, rendered into the pet's own bubble
└── client.core.js    # Browser side: pet UI + settings (wrapped at build time)

# Shared between both ends. The `.cjs` suffix is what lets the host ESM pick the
# exports up through createRequire; the served URL keeps the `.js` extension
# because a browser <script> doesn't treat `.cjs` specially. One implementation for
# both ends, so copy and geometry can't drift apart.
├── session-order.cjs # Deck ordering (approval > plan review > ask > completion > attention …)
├── pet-tip.cjs       # Page-switch-dot hover copy, tip viewport clamp, bubble zoom resolution
├── gif-frame.cjs     # The GIF frame currently on screen (right-click pause; canvas only ever paints frame 0)
├── bubble-title.cjs  # Session-card presentation: title throttle, width measurement, approval/review/done copy & classes
└── markdown.cjs      # Markdown rendering for release notes (escape first, then transform; only http(s)/mailto links)

lib/client.js         # Build artifact (version injected, ready to use)
assets/pets/remielle/ # Remielle assets (GIFs + artwork)
scripts/build-client.mjs
test/                 # node --test

When you add a shared module, wire it into both scripts/build-client.mjs (web bundle) and the host's route registration (desktop window). Verify the actual script response in test/host-transport.test.js, and check the page's script src and shared-module calls in test/desktop-window-ui.test.js.

Publishing to npm

npm login
pnpm version patch    # Bump version
pnpm pack --dry-run   # Check what will be published (no node_modules / vendor)
pnpm publish

Published content is controlled by the files field: src/, lib/client.js, assets/, scripts/, test/, cordis.patch.yml, NOTICE, README.md. The vendor/ (Electron runtime) is not published — desktop mode downloads it on demand.


License & Asset Copyright

Source code is distributed under MIT License; the Remielle character art and GIF/ artwork assets are copyrighted by miHooyoverse (HoYoverse), commercial use and redistribution of assets is prohibited. See NOTICE for details.

Content from the project README on GitHub ↗

Links

More in this category

View the whole category →

Community comments

Comments are public GitHub Discussions. Loading them connects to GitHub and Giscus; a GitHub account is required to post.