DeepSeek Harness 插件

Signalight/codex-to-dsh-pet#dsh-codex-pet

Star 数 ★ 5 下载量(近 30 天) 610 分类 娱乐 收录于 2026-08-18 npm @signalight/dsh-codex-pet

DSH 网页 GUI 实时桌宠:可把任何 Codex 桌宠图集(webp/png/gif,v1/v2 自动识别)转换为 DSH 中可拖拽的悬浮桌宠。支持拖拽/挥手/跳跃,v2 桌宠的眼睛实时追踪活动鼠标,随 agent 状态切换姿势;进度气泡反映工作状态;「设置 → 桌宠」图形界面可导入、切换与调整桌宠;内置一只原创示例桌宠(娜斯佳),用户桌宠存放在 ~/.dsh/pets。

安装

# npm 包(预构建)

dsh plugin --profile web add @signalight/dsh-codex-pet

# GitHub 源码(首次需按提示配置 allowBuilds 构建授权后重试)

dsh plugin --profile web add github:Signalight/codex-to-dsh-pet#path:/packages/dsh-codex-pet

装任何插件都等于在你的机器上跑第三方代码,权限和你本人一样大——能读你的文件、用你的凭据、访问网络,工具审批管不到它。GitHub 来源的插件还会在安装时执行构建脚本——pnpm 默认拦截,所以安装可能停在 ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED 或 ERR_PNPM_IGNORED_BUILDS;dsh 会打印出需要添加的确切键名,把它加进该 profile 的 pnpm-workspace.yaml 的 allowBuilds 下,重跑一次即可装上。放行构建本身就是一次信任判断:请只安装可信来源,并尽量锁定 commit(github:owner/repo#sha)。

README

该插件的 README 只有英文版本。

A DSH web-GUI pet runtime plugin — one plugin that renders any Codex spritesheet-atlas pet (v1 / v2) as a draggable desktop pet in the DeepSeek Harness web GUI.

It is the runtime half of the codex-to-dsh-pet framework: instead of building each pet into its own plugin bundle, you install this plugin once, then add pets as plain data files — no per-pet code.

The plugin ships one built-in example pet nastya (娜斯佳) — an original character (CC BY-NC 4.0, non-commercial) — so the registry is never empty. See assets/nastya/.

Features

  • Renders Codex spritesheet atlases (8 columns × 192×208 cells):
    • v1 (1536×1872, 9 rows) — auto-detected;
    • v2 (1536×2288, 11 rows) — adds 16 mouse-tracking "look" cells.
  • Draggable (position persists across restarts), wave-on-hover, jump-on-double-click.
  • Opt-in mouse tracking (v2 only, default on): the «桌宠» settings section has an Eye tracking toggle; the UI notes it applies to v2 atlases only (v1 has no look cells, so the toggle is inert for v1 pets).
  • Live activity poses: idle / waiting / running / review, driven by the conversation state.
  • Progress bubble showing the running tool name or the live model text tail.
  • Optional fixed-interval first-person LLM summaries, with a per-session journal shown when hovering the pet. Automatic summaries observe only requests completed after selecting a session; they do not backfill historical conversations. Right- click the pet to explicitly analyze prior unsummarized requests. This is disabled by default. Enabling it sends bounded excerpts of user, assistant, tool, and error content to the selected LLM and incurs that provider's usage/cost. Select a provider and model before enabling summaries. Cadence and bubble duration are configurable.
  • Configurable completion, error and interruption voices, including per-track volume, bundled rotating takes and user-uploaded audio overrides.
  • Zero per-pet code: the browser half is registry-driven from /api/codex-pet/*.

DSH compatibility

DSH gates every profile plugin row on its @deepseek-ai/dsh* peerDependencies: a peer range the running DSH version does not satisfy disables the whole row (no pet, no settings section) with Plugin … is incompatible with dsh …: peerDependencies ….

This plugin therefore declares only peers that exist across the DSH 0.2 line and later, with open-ended ranges:

"@deepseek-ai/dsh-client-ui-slots": ">=0.1.0-rc.6",
"@deepseek-ai/dsh-host-webserver": ">=0.1.0-rc.6"

It works on 0.1.x and on 0.2.0-rc.1+. The obsolete @deepseek-ai/dsh-client-runtime peer is not declared: DSH 0.2.0-rc.1 removed that package, so declaring it (^0.1.0-rc.6, as 0.3.1 did) makes DSH disable the row — which is exactly why the pet vanished on 0.2.0-rc.1.

The same upgrade also retired the client runtime at runtime, not just in the manifest. On 0.1.x the pet overlay read the conversation from sessions.currentProvideInfo; that bridge is gone in the 0.2 line, which would leave the snapshot null and the bubble permanently blank (0.3.2 had this bug — the pet appeared but never spoke). The overlay now reads the internal uiSession service's main binding instead:

  • hooks.chat → the live tail (partial, runningCalls) plus turnEnds; this is the target dsh-client-ui-chat registers, i.e. the streaming reply text and the "running: <tool>" bubble text;
  • hooks.trajectory → the same fields plus requests, kept as a fallback when the chat hook is absent (its own partial only fills in once its target has accumulated chunks);
  • hooks.session → running, pendingSubmissions, openState;
  • nodes / turnEnds are rebuilt from the trajectory event nodes, keeping the done chime and the periodic summaries working.

uiSession is deliberately not listed in inject: it is an internal service that older hosts never provide, and Cordis parks the entire plugin when a hard dependency is missing. It is resolved lazily with ctx.get("uiSession") (plus a short polling subscribe, because the service can arrive after the plugin loads), and when it never shows up the overlay falls back to the legacy currentProvideInfo path — so one build serves both hosts.

Install

Recommended — one command (needs pnpm):

# from npm
dsh plugin --profile web add @signalight/dsh-codex-pet

# or straight from GitHub
dsh plugin --profile web add github:Signalight/codex-to-dsh-pet#path:/packages/dsh-codex-pet

Manual route (no pnpm): from the repository root run

.\install-runtime.ps1

This copies the package into ~/.dsh/profiles/node_modules/@signalight/dsh-codex-pet and registers the plugin row in ~/.dsh/profiles/web/cordis.patch.yml. Then:

  1. Hard-refresh http://127.0.0.1:3080 (Ctrl+Shift+R) — the DSH profile hot-reloads cordis.patch.yml. If the pet still doesn't show, fully quit and relaunch the DSH desktop app (command-line users can restart dsh web).

Rollback: delete ~/.dsh/profiles/node_modules/@signalight/dsh-codex-pet and restore the .bak next to the patch file.

Add a pet

A pet is a folder holding a pet.json manifest plus one atlas image. Drop it into either source (user pets override built-ins on id collision):

  • built-in: packages/dsh-codex-pet/assets/<pet>/
  • user: ~/.dsh/pets/<pet>/ (survives plugin updates)

pet.json:

{
  "id": "nastya",
  "displayName": "娜斯佳",
  "description": "娜斯佳 Nastya — original character (CC BY-NC 4.0).",
  "spritesheetPath": "spritesheet.webp",
  "spriteVersionNumber": 2,
  "size": 120,
  "pin": "bottom-right"
}

Only id and spritesheetPath are required. spriteVersionNumber is auto-detected from the image dimensions when omitted; size (px width) and pin (top-left / bottom-right / …) default to 120 and bottom-right.

No manual editing needed: in the DSH settings surface open the «桌宠» section and click 导入桌宠 (webp / png / gif) — the plugin writes the file into ~/.dsh/pets/<name>/, auto-detects the atlas version, and selects the new pet. The pet id comes from the filename (my-pet.webp → my-pet); if that id is already taken the plugin appends a -2 / -3 suffix instead of overwriting the earlier pet (all Codex atlases are named spritesheet.webp, so without this every import would clobber the previous one). Re-importing the same id with the same typed display name updates that pet in place.

Architecture

src/
├── index.js     host half: name/inject/apply, mounts service + routes
├── registry.js  scans assets/* + ~/.dsh/pets/*, normalizes Codex atlases
├── service.js   persisted selection + display config (~/.dsh/codex-pet.json)
├── routes.js    /api/codex-pet/* JSON API + /codex-pet/<id>/* assets
└── client.js    browser half: registry-driven overlay renderer
  • Host half registers same-origin routes via the DSH web server (ctx.webServer.register), serving the pet list, state and atlas assets.
  • Browser half fetches /api/codex-pet/state, renders the selected pet, mirrors drags back via POST /api/codex-pet/set-config, and seats a settings.section entry («桌宠») that edits the pet through the same API.

API

Endpoint Method Purpose
/api/codex-pet/pets GET pet registry (list of definitions)
/api/codex-pet/state GET selected pet + display config
/api/codex-pet/set-pet POST { petId } — switch pet
/api/codex-pet/set-config POST update display, summary, or sound settings
/api/codex-pet/set-visible POST { visible }
/api/codex-pet/import?id=<filename>&name=<displayName> POST raw image body — import a Codex atlas
/api/codex-pet/models GET available LLM providers and models for summaries
/api/codex-pet/summarize POST summarize one completed assistant-request batch
/api/codex-pet/journal?session=<id>&limit=<n> GET recent persisted summaries (&all=1 returns all records for manual coverage checks)
/api/codex-pet/sound?track=<id> POST upload a raw audio override (8 MiB maximum)
/api/codex-pet/reset-sound?track=<id> POST remove an audio override
/codex-pet-sound?track=<id> GET stream the effective done, error, or interrupt track
/codex-pet/<id>/<file> GET pet.json + spritesheet assets

Summary journals are stored under ~/.dsh/codex-pet-journal/. Uploaded voice overrides are stored under ~/.dsh/pets/sounds/ and survive plugin updates.

Roadmap

  • Settings section («桌宠» in the DSH settings surface: pet selector, show/hide, size, corner pin, bubble color/opacity, eye tracking — the last is v2-only and noted as such), backed by the plugin's own API.
  • In-GUI import button (upload a Codex atlas → auto-detect → install → select).
  • In-GUI preview before import (live canvas frame preview).
  • Published to npm (@signalight/dsh-codex-pet) + dsh-plugin GitHub topic.

License

MIT — see the repository root LICENSE.

Built-in scenario voice / sound assets

The plugin ships 8 built-in scenario sounds under assets/sounds/ (done-1~4.wav, error.wav, interrupt-1~3.wav):

  • Attribution: these sounds were generated by contributor @yabo083 (PR #4) using Qwen3-TTS VoiceDesign and submitted with the plugin; they were reviewed and accepted into this package, and are distributed under MIT together with the plugin.
  • Generator license: the Qwen3-TTS model repo is Apache-2.0; that license applies to the model repo only and does not change this project's license. Using Qwen3-TTS does not imply endorsement by Qwen.
  • Relationship to the character: these lines are usually performed as the built-in example pet nastya (娜斯佳). That character is an original character, and its atlas is licensed CC BY-NC 4.0 (non-commercial), so even though the sound files are MIT-licensed, using them as that character's voice keeps the character's non-commercial restriction in force; ask the character's author before any commercial use.
  • User audio: you may upload your own audio to replace any scenario sound (Settings → 完成提示音); custom audio's copyright and license are your own responsibility.

内容来自项目 README(GitHub)↗

链接

同类插件

查看整个分类 →

社区评论

评论公开保存在 GitHub Discussions。加载评论会连接 GitHub 和 Giscus;发表内容需要 GitHub 账号。