Desktop Pet - Naiwa's Childhood (dsh-desktop-pet-naiwa): A DSH plugin that brings Agent progress, Token estimation, and real balance to your Windows desktop.

Preface

When running an Agent in DSH, most of the time you stare at the Web GUI: you have to switch back to the page to see where the task is in the step, what tools were called, and how many Tokens were burned today. The web window cannot serve as a character that always floats on the desktop and allows interactive clicks. dsh-desktop-pet-naiwa is a Windows client plugin maintained by Night-maze that projects this information onto a transparent, borderless, always-on-top native window. At the same time, this window supports single-click interaction, long-press dragging, edge-snapping semi-hiding, and dragging files into the Recycle Bin.

Below is an introduction to this plugin: first, why it is split into two layers, followed by its features, installation commands, and available configurations.

What is this

One-sentence positioning: A Windows desktop pet (desktop pet) based on the DeepSeek Harness plugin mechanism, maintained by Night-maze. Category: Client. License: MIT. GitHub repository created on 2026-11-05. Current stars: 0. NPM package name: dsh-desktop-pet-naiwa. Version: 1.0.0.

It solves the problem: Agent runtime state is absent from the native desktop. Existing DSH client plugins can only render the React interface inside the Web GUI and cannot create arbitrary OS windows.

Why Host Plugin + WPF Subprocess

DSH client plugins run in a browser sandbox and do not have permission to create native windows. To create a transparent, borderless, always-on-top, draggable window, an independent native process is required. Therefore, the plugin is split into two layers:

  • Host Plugin lib/index.js (Cordis bundle): Subscribes to session/event, maintains a daily backfilled token ledger, reads the real balance, and is responsible for launching and supervising the subprocess.
  • WPF Subprocess pet/DesktopPet.ps1 + DesktopPet.cs: Draws the window itself and handles gestures and animations.
  • Communication: Between the two, they communicate via newline-delimited JSON on the 127.0.0.1 loopback with random token authentication.

The responsibilities have clear boundaries: The Host does not hardcode Token, balance, or progress; the WPF subprocess does not access the network or read DSH internal state, only consuming the JSON sent by the host.

Core Features

Agent Progress Projection

Projection based on events: turn/start indicates the task has started, step/start and tool/call provide progress, assistant/message and assistant/attempt provide Token usage, turn/end gives completion, failure, or cancellation, and agent/error serves as a fallback for failure.

By default, it shows an indeterminate progress bar plus “Step N · Tool Name” text. The plugin explicitly does not use fabricated 0-100% numbers to avoid presenting a percentage that looks like progress but has no basis.

Token Cost Estimation & Real Balance

“Today’s Cost” is Real Token Usage × Public List Unit Price. This is marked with ≈ in the UI, as it is an estimated value. The usage ledger deduplicates by sessionId:seq; successful messages for the same turn/step replace failed attempts; attempts after llm/retry-started are allowed to be counted again. Data is backfilled from ctx.sessionPersistence on startup.

“Balance” comes from ctx.deepseekAccount.getBalance. This is the real value from the platform wallet, not estimated or fabricated. If reading fails, the previous value is retained and marked as stale. Refreshing uses exponential backoff, never using 0 as a substitute.

Prices default to built-in CNY/USD public list prices for deepseek-flash and deepseek-v4-pro, distinguishing peak hours (Beijing Time weekdays 9–12, 14–18) and off-peak hours. Models without a configured unit price only display Tokens without an amount.

Interaction Behaviors

  • Click: Randomly selects one interactions configuration item based on weight. There are 6 built-in types (blink, jump, shake, heart, random line, dance), with configurable weights, animations, dialogue, and corresponding sprites.
  • Long Press Lift: Pressing for more than longPressMs (default 450ms) counts as lifting, after which it acts like a pendulum/spring drag and naturally drops back when released.
  • Edge Semi-Hide: After dragging to the screen edge and releasing, it determines the direction based on the current monitor’s WorkingArea and edgeThreshold, sliding to reveal only edgeVisibleRatio; the mouse exits when hovering over it, and it slides back after a delay when the mouse leaves.
  • Click-Through: WM_NCHITTEST determines this based on the current sprite’s alpha. Transparent pixels return HTTRANSPARENT, preventing it from blocking other desktop operations.

Drag Files to Recycle Bin

Implemented via IFileOperation with FOF_ALLOWUNDO | FOFX_RECYCLEONDELETE. It forces “Recycle or Fail” and has no File.Delete / Directory.Delete fallback. Paths are restricted: drive root, system directories, symbolic links/junctions, no permissions, file in use, cross-drive or network recycle failures will preserve the original file and pop up a clear error. AppContainer or low-integrity processes will be rejected.

Client Side

The client side registers a sidebar 🐾 Desktop Pet entry and a settings page. You can adjust scale, volume, stats display, long-press/drag thresholds, and support refreshing stats, restarting, and showing/hiding. Settings are written to the data directory ui-config.json, overriding the same-named field in the profile; deleting this file and restarting the plugin restores the profile configuration.

Installation & Enablement

Prerequisites: Windows 10/11, system-installed Windows PowerShell 5.1 and .NET Framework 4.x (WPF components). No extra npm dependencies are required; the Host only uses Node built-in modules. The plugin declares compatibility with the DSH 0.2.1-rc.5 Cordis plugin/service API.

The recommended way is to install via bundle. First, open Plugins in the DSH Web GUI and execute:

dsh plugin --profile desktop add dsh-desktop-pet-naiwa

Or point to a local source code directory:

dsh plugin --profile desktop add link:F:\path\to\dsh-desktop-pet-naiwa

package.json already declares the bundle patch and client injection:

"dsh": {
  "bundle": { "patch": "./cordis.patch.yml" },
  "client": { "platform": "web", "inject": ["..."] }
}

The next steps:

  1. Open the “Desktop Pet - Baby Naiwa” bundle on the Plugins page, or add it to the dsh.profile.bundles in your profile.
  2. Remove any lines pointing to absolute paths to avoid loading the same plugin twice.
  3. Refresh the DSH page; the sidebar should appear with 🐾 Desktop Pet. If not, restart DSH once to let the client graph rescan dsh.client.

There is another dev mode approach, appending an absolute path entry to %USERPROFILE%\.dsh\profiles\<profile>\cordis.patch.yml. It has no bundle identity, no toggle on the Plugins page, and no client settings page; it is only suitable for temporary debugging, and should be deleted for daily use.

Configuration

See config.example.yml in the repository for full fields and comments. Common items:

Field Default Description
enabled true Plugin master switch
imagePath '' Single custom avatar; leave empty to use the built-in 12 sprites
spriteDir / soundDir Built-in assets Relative to plugin directory or absolute path
scale 1.0 Overall scale 0.5–2, scales window, UI, and avatar together
volume 0.7 SFX volume 0–1
topmost true Always on top
avoidFullscreen true Hide when full-screen apps are active
statsDisplay always always / hover / off
longPressMs 450 Long press lift threshold
dragStartPx 10 Drag start threshold
edgeThreshold 24 Edge triggering distance (physical pixels)
edgeVisibleRatio 0.38 Ratio visible after semi-hiding
currency auto CNY / USD / auto (follows wallet)
costPrecision 4 Cost decimal places
balanceRefreshMs 60000 Balance refresh, minimum 30s, fails over to 5min with exponential backoff
statsRefreshMs 30000 Stats push interval
pricing Public price list Peak/off-peak/holiday/unit price per million Tokens
interactions 6 types Weights/animations/dialogue/sprites for random click interactions
protectPaths System directories Path prefixes that refuse recycling
backfill Enabled Count/bytes/timeout limit for startup backfill

pricing.holidays defaults to an empty array: Chinese statutory holidays change every year, and the plugin does not embed an easily expiring calendar; if precise peak/valley billing is needed, manually fill in YYYY-MM-DD.

Arrays in the configuration are full replacements, not merged item by item. Clicking draws one item from interactions and uses that item’s sprite to specify which image to display (filename without .png). To keep a certain number of items, list them all; unlisted items will not appear.

Data & Logs

Default directory: $DSH_HOME/storages/desktop-pet/:

File Description
pet-config.json Merged configuration written by Host to WPF
usage.json Today + last 14 days token ledger, including model, time, and four buckets
host.log Host plugin diagnostics
pet.log WPF / Launcher diagnostics
launcher.log Launcher compilation and startup diagnostics
window.json Last window position, used for multi-monitor recovery

Logs may be rotated to pet.log.old.<timestamp>; the plugin will not delete user files.

Testing & Verification

node test/run-tests.mjs          # host unit tests
node test/mock-host.mjs          # real WPF + mock Cordis integration
powershell -STA -File scripts/demo.ps1

The Recycle Bin test must run in a normal user process, not inside the DSH workspace sandbox:

powershell -STA -File scripts/test-recycle.ps1

Use Cases & Notes

Suitable for developers running DSH Agents on Windows: those who want progress and cost to stay visible on the desktop, while accepting a persistent subprocess. In fullscreen demo scenarios, avoidFullscreen will hide it and not interrupt the presentation.

Points to note:

  • The plugin runs with the permissions of the current dsh process. It does call the platform balance interface and operates the Recycle Bin when files are dragged in, so you should review the source code before installing to ensure the ctx.deepseekAccount.getBalance call and IFileOperation call meet your expectations. The license is MIT, source is from the npm package and GitHub repository.
  • The only paths that will delete files are the Shell Recycle API. If the Shell cannot recycle, the operation fails directly, and the original file is preserved; there is no fallback for permanent deletion.
  • “Today’s Cost” is just an estimate; the amount is calculated based on the public list price, which does not equal the settled amount.
  • The progress bar deliberately does not show a percentage. If you need exact numbers, you should still check the Web GUI or logs.

Conclusion

This plugin moves the Agent runtime state from the web page to a native window. The key trade-offs are: using estimated values for cost and real values for balance, and using an indeterminate progress bar instead of fabricated percentages. The two-layer structure (Host Plugin + WPF Subprocess) is the way it bypasses the client plugin sandbox restrictions, and is also what needs to be understood during installation and troubleshooting.

Directory Page: https://www.skillhub.cn/plugins/Night-maze/dsh-desktop-pet-naiwa
Repository: https://github.com/Night-maze/dsh-desktop-pet-naiwa
NPM: https://www.npmjs.com/package/dsh-desktop-pet-naiwa

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

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

Xiaoye