dsh-clippy-companion: Add a pixel companion that follows session state to the DSH chat area

Introduction

The philosophy of DSH is “everything is a plugin”, and the interface layer leaves room for this as well. Most plugins modify behavior (tools, permissions, output), while visual changes are rare. This plugin places a small pixel person in the chat area; it moves according to the session state: tools are running, errors occur, messages are queued, and the context is almost full—each has a corresponding expression.

The plugin is named extreme-russian-dsh-fandom/dsh-clippy-companion, the package name is @local/dsh-clippy-companion, and the maintainer is extreme-russian-dsh-fandom. It is categorized under “Client” on the directory page, has 0 GitHub stars, and is a plugin that solves a personal fun requirement, not infrastructure.

Below is an introduction to what it is, how to install it, and how to switch sprite packs.

What is it

In a nutshell: it places a draggable, skin-switchable companion in the DeepSeek Harness chat area, animating and prompting based on the current dialogue state.

It does not solve efficiency issues, but rather the fact that the chat area is pure text and you cannot see what is happening in the background. For tool calls exceeding ten seconds or when the context is about to fill up, you originally had to rely on logs to judge; this plugin turns these states into a visible little person expression.

There are two skin packs released with the package:

  • Clippy, using tiles from OpenClippy.
  • Doomguy, the head pixel art from the DOOM II status bar, complete with meme faces.

The draggable area is measured against the session column itself, so the companion will not run into the sidebar or the “Shown Files” panel. It can keep up with layout changes such as the sidebar collapsing, the right panel, window resizing, or the input area becoming taller.

Core Features

The verifiable capabilities are as follows.

Draggable. Drag anywhere within the session column; the position is constrained within that column, saved to localStorage, persists after refresh, and adapts to window size changes.

Skin Pack Switching. Right-click (long press on touchscreens) the companion to switch packs, or go to Settings → General → Companion. Selection is remembered.

Each pack has its own dialogue style. Idle loops, greetings, reactions, and random sentences all come from that pack’s preset.json.

Context Damage. Only the DOOM pack uses this mechanism: it reads the real-time pressure value of the token meter. Below 35% shows healthy; 35% onwards shows hurt; 65% onwards shows critical. If the expression does not have a corresponding broken variant, it keeps the normal frame.

Perceiving Agent State. During a conversation round, it reflects the thinking state, current tool (edit/read/shell/general tool), tool success or failure, waiting for user decision, queued messages for the next round (hand raised, no bubble), tool calls exceeding ten seconds (Clippy uses IdleFingerTap, Doomguy uses Angry), and the end of a round. During this time, the bubble briefly takes over, and the activity animation resumes afterwards.

Meme Faces. The DOOM pack includes 22 high-resolution Reddit meme faces, scaled to the same 24×29 size as the status bar head. Some have exclusive dialogue; the rest appear randomly during idle animation gaps.

Pokeable. Clicking the companion (or pressing Enter when it has focus) pops up a themed bubble comment; poking it repeatedly makes it impatient, and double-clicking throws a meme face.

Sleep. After being quiet for 5 minutes, it falls asleep, showing a Zzz bubble and switching to the sleep animation (if available); any subsequent activity, click, key press, or comment wakes it with a wake-up animation.

Keyboard Operable. Tab to focus, arrow keys to move (hold Shift for larger steps), Enter or Space to speak, Menu key or Shift+F10 to open the pack menu, Escape to close.

Follow Theme & Reduce Motion. Bubbles, menus, and setting rows use host theme tokens; only the art assets retain their own color scheme. When the system has prefers-reduced-motion: reduce, the companion stays in a static frame and does not play looping animations.

Installation and Enablement

Installation method in the README: it is a standard pnpm dependency; it can be installed via GitHub reference or local checkout. For the desktop app, go to the Plugins page; for the command line (Windows / Linux / macOS), run the following:

# Install from GitHub
dsh plugin --profile desktop add github:extreme-russian-dsh-fandom/dsh-clippy-companion

# Install from local checkout (Windows)
dsh plugin --profile desktop add C:\path\to\dsh-clippy-companion

# Linux or macOS
dsh plugin --profile desktop add /path/to/dsh-clippy-companion

Replace desktop with your own profile name (web, tui, …). dsh plugin passes arguments to pnpm directly, so github: is pnpm’s GitHub shorthand; to fix the version, append #<branch-or-commit> at the end.

The update cost differs for the two installation methods: a local directory is linked, so you only need to re-enable the plugin after making changes; a GitHub reference copies the package, so you need to push first and then reinstall. No build step is required.

After installation, restart Harness and refresh the page. The plugin will appear as Clippy Companion in the Plugins settings.

Uninstall:

dsh plugin --profile desktop remove @local/dsh-clippy-companion

Or simply remove it directly on the Harness Plugins page.

Typical Usage

After installation, there is no other configuration to do; by default, the Clippy pack stays in the chat area. There are only two daily operations:

  1. When you want to change the style, right-click the companion to switch to Doomguy, or select it in Settings → General → Companion.
  2. When you want it to reply, click it, or press Enter when it has focus.

To verify if the context pressure mechanism is working, you can run a long context task with the DOOM pack open and observe the face variant switching as the token meter changes.

Customizing Sprite Pack

Each pack is a directory under assets/; the file structure is as follows:

assets/<pack>/
  preset.json        pack description
  sprite-data.json   frameWidth, frameHeight, animations[{duration, position}]
  <sheet>.png        tiles referenced in preset.json
  LICENSE | LICENSE.md

Key fields in preset.json:

  • scale scales frame size and background positioning; pixelated enables nearest-neighbor rendering for pixel art.
  • version cache-busting for images and manifest. You must bump the version when changing images; otherwise, the browser will still fetch the old image within its cache validity period (the preset.json itself is always fetched fresh).
  • greeting plays once on load, rest is for reduced motion and fallback, and idle is randomly selected during pauses.
  • speech maps a locale key to a reaction animation; optional memeIdle (array of animation names) and memeChance (0–1) allow the idle state to occasionally show a meme face, and the double-click meme burst also uses this list.
  • Optional poke (list of { key, anim }) answers clicks, pokeMad answers the third consecutive poke, and sleep/wake specify sleeping and waking animations. Missing items fall back to compatible animations in that pack.
  • Damage variants are regular manifest animations with suffixes: Angry, AngryHurt, AngryBad. The client will take the highest tier available under that base name.

To add a new pack: drop the directory into assets/ and add a line in client.js’s PRESETS. No changes are needed on the Host side; the assets route is a prefix for the entire directory.

To rebuild the DOOM pack, run in the repository root:

python tools/build-doom-pack.py

The script indexes classic tiles, flood-fills the black background of meme faces, scales meme faces to 24×29, packs all frames into 32×32 cells, and outputs faces.png and the damage tier manifest. Classic tiles store five tiers of health per expression (100/80/60/40/20 percentages), and three damage tiers use 100/60/20. The build process asserts that the generated animations do not mix health tiers, avoiding mid-animation changes in intensity.

Implementation Details

  • index.js (Host side) mounts assets/ in read-only mode to /clippy-companion/assets/<pack>/..., with checks for path traversal, extensions, and content types.
  • client.js (Client side) registers a hidden probe in conversation.input.dock to measure the session column and projects contextPressure and inbox to the companion; it also passes session activity (running, current tool, last tool result, pending input, queued messages) to the companion. The companion renders in shell.overlay, and the corresponding line in settings is registered in settings.general.item.
  • Tile frames are drawn via background-position shifts on a single sheet, with timing read directly from each pack’s sprite-data.json.

package.json declares "platform": "web", "immediately": true, injects @deepseek-ai/dsh-client-ui-conversation, version 1.5.0, and license MIT.

Applicable Scenarios and Notes

Suitable for desktop/Web users who keep a chat window open and want to intuitively see what is running in the background, and who don’t mind a little pixel person in the interface. Those who want to customize skins or add memes can use the pack instructions in the README.

A few things to note:

  1. The plugin runs with the permissions of the current dsh process and can access session content. Read the source code and license before installing (this package is MIT licensed); do not globally enable it based solely on the directory page description.
  2. It has 0 stars, and the maintainer is a personal account, so the update frequency is not guaranteed. For long-term dependency, it is recommended to clone the repository locally and use the local directory install.
  3. It is not an official product. The directory site is an independent site with no official affiliation with DeepSeek or Fangfang.
  4. Data like contextPressure comes from the host projection. If behavior is abnormal after changing versions, first check if the plugin’s injection point still matches.

Summary

The value of this plugin lies not in functional complexity, but in making session state visible on the screen, while exposing a very clear interface for sprite packs: a tile image arranged in a 32×32 grid plus a preset.json file is enough to change the look, without needing to modify the Host. It is suitable for DSH users willing to tinker with visual effects.

Directory page: https://www.skillhub.cn/plugins/extreme-russian-dsh-fandom/dsh-clippy-companion
Repository: https://github.com/extreme-russian-dsh-fandom/dsh-clippy-companion

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

Xiaoye