zw11591-sketch/dsh-pet-panel1

dsh-pet-panel

A dual-face DeepSeek Harness Web UI plugin: desktop pet, session dashboard, and self-service capability panels (Skill Forge, Tool Integrations, A2A Management) with per-profile isolation and a /pet command

包名
dsh-pet-panel
版本
0.1.0
许可证
MIT
最近更新
2026年9月12日

安装

$npx -p @deepseek-ai/dsh dsh plugin --profile web add github:zw11591-sketch/dsh-pet-panel

dsh-pet-panel

A dual-face plugin for DeepSeek Harness Web UI: a browser half (desktop pet, session dashboard, and five self-service capability panels — Skill Forge, Tool Integrations, A2A, Team, Scheduled Tasks) plus a host half (skill / MCP / A2A / team / scheduler gateways, model-facing A2A tools, and an inbound A2A endpoint), with per-profile data isolation.

Features

Browser (client)

  • Desktop pet (PetView) — a global floating pet above every column, independent of the active session. Draggable, skinnable (five SVG species with eye/mouth emotes), resizable, persisted to localStorage. Reacts to session lifecycle (running → busy, pending → waiting, finishing → celebration) plus manual feed/play/sleep controls. Toggle it from the chat with /pet on / /pet off / /pet.
  • Session dashboard (DashboardView) — a conversation-view tab (会话仪表盘 / Dashboard) with two sections: 概览 (live context occupancy, session totals, 7-day activity trend, archived/forked session lists) and 用量分析 (token-spend ranking, detailed context analysis of the active session). Renders derived data only.
  • Skill Forge (技能工坊) — list / read / write / delete SKILL.md files, and generate a new skill from a natural-language description via the default model.
  • Tool Integrations (工具集成) — list / add / edit / delete MCP servers (stdio or streamable-http).
  • A2A Management (A2A 管理) — configure this plugin's own Agent Card (with an AI "智能生成" button that drafts the persona from name/description/capabilities via the default model), register external A2A agents (name / URL / description / capabilities / keywords / examples), show live online/offline/latency status per registered agent, and show the generated agent-card URL and message/send endpoint for copy.
  • Team (团队) — create teams from yourself ("me") plus registered external A2A agents; group chat and 1:1 chat with @mention routing (@name directed, @all broadcast, no @ = broadcast), multi-turn memory via per-agent A2A contextId, live member online/offline status, and a "对方回复中" typing indicator while waiting for a reply.
  • Scheduled tasks (定时任务) — create cron tasks (5-field cron + IANA timezone, Asia/Shanghai by default) that run a prompt through the real agent loop on every fire, each with its own optional provider/model override so a cheap model can handle the routine jobs. The panel lists every task with its next/last run time and the full text of the last result — including the failure reason, so a broken run is diagnosable from the UI alone. Per task, results can push to a Feishu (Lark) group webhook; WeChat push is not wired up yet.
  • File attachment (附件) — the conversation composer and team chat accept file attachments. Text files are read inline and Excel files (xlsx/xls/xlsm) are parsed to a table via SheetJS; both insert as a reference chip (Doubao/ChatGPT-style) showing the filename and serializing to the file content on submit. Binary files are rejected with a toast instead of turning into mojibake.
  • Image attachment (图片) — team chat supports image uploads, canvas-compressed to ≤700KB so they stay under the A2A gateway body limit. When sent to external agents, the image is first described into a text caption by the default vision model (A2A is text-only); "me" reads the image directly through the multimodal prompt path.
  • Voice input (语音输入) — both the conversation composer and team chat have a mic button backed by the browser's Web Speech API (Chrome/Edge). Click to record; speech is transcribed live (zh-CN) and appended to the draft/input. Mic-denied and no-speech surface as a toast, and the button hides itself on unsupported browsers (Firefox/Safari).
  • Background switcher — four Papergames official wallpapers with a brightness/dim control, persisted to localStorage.

Host (Node service)

  • SkillForgeGateway, ToolIntegrationsGateway, A2AConfigGateway, TeamGateway, ScheduledTasksGateway — Typert remotes backing the panels above. SchedulerService owns the cron loop and fires each task by creating a real agent session (its own prompt, tools, skills, and MCP), so a scheduled run is the same agent you get in the chat.
  • A2A outbound tools — a2a_list_agents / a2a_call let the model discover and call registered external A2A agents.
  • A2A inbound endpoint — serves /.well-known/agent-card.json and a JSON-RPC message/send handler at /a2a, driving the same agent runtime as the WebUI (identical model, tools, skills, MCP, and multi-turn memory via contextIdsessionId). The agent card advertises A2A protocol v1.0 (supportedInterfaces with protocolBinding: JSONRPC).
  • Unified self persona — a single deployment:persona section is injected into every non-subagent agent (WebUI-hosted, inbound /a2a, and team "me") from the one Agent Card soul, so all three entry points share the same persona rather than relying on per-create setup injection.
  • Session grouping — inbound A2A and team "me" sessions each resolve to their own dedicated workspace group (A2A会话 / 团队会话) so they show up grouped in the session dashboard instead of cluttering the default workspace.
  • Per-profile isolation — skills, MCP config, A2A config, and teams all resolve to the active profile (~/.dsh/profiles//), so each profile sees only its own skills, tools, and teams.
  • Feishu OAuth login gate — optionally require Feishu (Lark) login before the WebUI opens: unauthenticated visitors are 302-redirected to Feishu's consent page before the index renders. After login a signed cookie stores open_id/name/avatar, surfaced as a sidebar-footer logout entry (avatar + name) beside Settings. Enabled only when FEISHU_APP_ID / FEISHU_APP_SECRET are set; unset → the WebUI stays open (safe default). See "Feishu login (optional)".
  • Image-to-text descriptionSelfAgentService.describeImages uploads images to the attachment store and runs them through the default vision model, returning a text caption that rides the A2A channel to external agents (which are text-only).

Requirements

  • Node.js ^22.19.0 || >=24.0.0 (see package.json engines).
  • pnpm on your PATH — dsh plugin is a thin forwarder that spawns pnpm inside the profile directory, so pnpm not found is a hard blocker.
  • DeepSeek Harness >=0.1.1-rc.1 (see package.json dsh.engines). For development, keep it on the same version as the @deepseek-ai/* packages you compile against — see "Dependency versions".

Dependency versions

The plugin is compiled against the @deepseek-ai/* packages that DeepSeek Harness itself ships at runtime, so the declared versions and the harness you actually run need to line up.

PackageDeclared hereWhere it comes from at runtime
@deepseek-ai/dsh-client-{locale,ui-conversation,ui-layout,ui-sidebar,ui-slots,connection}, dsh-home-paths, dsh-skill-filesystem, dsh-token-meter, dsh-tools, dsh-typert-protocoldevDependencies / peerDependencies: ^0.1.5-rc.2shipped inside the harness (@deepseek-ai/dsh/node_modules/@deepseek-ai/…, observed at 0.1.5-rc.2), and resolvable from the registry at the same version
@deepseek-ai/dsh-client-runtimedevDependencies: ^0.1.1-rc.2not bundled by the harness; the registry tops out at 0.1.1-rc.2 — nothing to bump
@deepseek-ai/cordisdevDependencies: ^4.0.2ordinary semver, no prerelease trap — the harness ships 4.0.2, so pnpm update moves it normally

The prerelease range trap. ^0.1.1-rc.2 reads as `>=0.1.1-rc.2 FEISHU_APP_SECRET=

optional (defaults to /auth/feishu/callback when unset):

FEISHU_REDIRECT_URI=http://127.0.0.1: /auth/feishu/callback FEISHU_OAUTH_SCOPE=


Details:

- This uses Feishu's **企业自建应用 (internal app)** OAuth endpoints (`open.feishu.cn/open-apis/authen/...`), not the passport (网页应用) endpoints.
- In the Feishu developer console, register the callback URL under 安全设置 → 重定向 URL — it must match exactly (`127.0.0.1` ≠ `localhost`). Either fix `FEISHU_REDIRECT_URI` to one value, or register every port you start with.
- **Register only ONE redirect URL.** Keeping several URLs under 安全设置 → 重定向 URL trips Feishu error 20029 (重定向 URL 有误) at the consent page — keep exactly the one you use, e.g. `http://127.0.0.1:8801/auth/feishu/callback`.
- **Production apps need a version publish + admin approval** before a redirect-URL change takes effect. During development, use 开发配置 → 测试企业和人员 → 关联应用 to get a test version whose config applies instantly, with no approval.
- If the variables are unset, the plugin logs a warning and the WebUI stays open (no login) — the safe default, so a normal install is unaffected.

### Launch steps by environment

Pick your shell. The `
` in `FEISHU_REDIRECT_URI` must match the port dsh actually listens on (`--port`), and that exact URL must be registered in the Feishu console. The examples below use port `8801` — change it to your own.

#### Linux / macOS (bash, zsh)

Without login:

```sh
dsh --profile 

With Feishu login (inline env vars):

FEISHU_APP_ID= \
FEISHU_APP_SECRET= \
FEISHU_REDIRECT_URI=http://127.0.0.1:8801/auth/feishu/callback \
dsh --profile  --port 8801

Or export once, then start:

export FEISHU_APP_ID=
export FEISHU_APP_SECRET=
export FEISHU_REDIRECT_URI=http://127.0.0.1:8801/auth/feishu/callback
dsh --profile  --port 8801

Windows PowerShell

Without login:

dsh --profile 

With Feishu login:

$env:FEISHU_APP_ID = ""
$env:FEISHU_APP_SECRET = ""
$env:FEISHU_REDIRECT_URI = "http://127.0.0.1:8801/auth/feishu/callback"
dsh --profile  --port 8801

Clear them afterwards (current session only):

Remove-Item Env:FEISHU_APP_ID, Env:FEISHU_APP_SECRET, Env:FEISHU_REDIRECT_URI

Windows cmd (Command Prompt)

Without login:

dsh --profile 

With Feishu login (no spaces around =set VAR = x sets a key with a trailing space):

set FEISHU_APP_ID=
set FEISHU_APP_SECRET=
set FEISHU_REDIRECT_URI=http://127.0.0.1:8801/auth/feishu/callback
dsh --profile  --port 8801

Clear them afterwards:

set FEISHU_APP_ID=
set FEISHU_APP_SECRET=
set FEISHU_REDIRECT_URI=

Install

From a git repository (recommended for consumers)

dsh plugin --profile  add github:zw11591-sketch/dsh-pet-panel

--profile is required — a bare dsh plugin add ... errors with required option '--profile ' not specified.

This is a git-source install, so pnpm ≥ 10 blocks the prepare build step until you allow it. pnpm prints the exact package key to copy. For the first install the key is just the package name — add it to the profile's pnpm-workspace.yaml:

allowBuilds:
  dsh-pet-panel: true

Then re-run the add command. The first install builds lib/index.js + lib/client.js from source via the prepare script (no type checking — that is what CI does).

Finally start the profile:

dsh --profile 

From a local checkout (file:)

cd dsh-pet-panel
pnpm install
pnpm run build
dsh plugin --profile  add file:.
dsh --profile 

file: installs are copy-not-symlink on Windows: rebuilding the checkout does NOT propagate into the profile. See "Rebuild done but the change isn't visible" below.

Update

git-source installs

Pitfall: pnpm update will NOT fetch a new commit. A github:user/repo spec only re-fetches when the spec string changes (no version bump → no re-fetch). To actually pull a new commit, use one of:

# A. remove + re-add (simplest, deterministic)
dsh plugin --profile  remove dsh-pet-panel
dsh plugin --profile  add github:zw11591-sketch/dsh-pet-panel

# B. pin a specific ref, then update
dsh plugin --profile  add "github:zw11591-sketch/dsh-pet-panel#
"

# C. break the semver range and go newest (only relevant for npm-published plugins)
dsh plugin --profile  update --latest dsh-pet-panel

After a git re-add, pnpm will again block the new commit's prepare build until you allow it. The allowBuilds key is commit-specific — update pnpm-workspace.yaml to the exact key pnpm prints:

allowBuilds:
  dsh-pet-panel@https://codeload.github.com/zw11591-sketch/dsh-pet-panel/tar.gz/: true

Drop the stale `` entries, then re-run the add.

file: installs

Re-run the add (triggers re-copy + prepare), or copy the build output directly:

cp -rf /path/to/dsh-pet-panel/lib/. ~/.dsh/profiles//node_modules/dsh-pet-panel/lib/

Then restart the profile (see "Rebuild done but the change isn't visible" for the full restart + verify loop).

Uninstall / remove

dsh plugin --profile  remove dsh-pet-panel

This is equivalent to pnpm remove inside the profile directory: it deletes the dependency entry, uninstalls from node_modules, and a post-run reconcile step prunes the plugin from dsh.profile.bundles. Restart the profile; it now boots wi