🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

桌面伴侣 SherinG-official/dsh-desktop-pet

DeepSeek Harnessv0.2.0
SherinG-official31 天前有提交已提供中文文档扫描:含敏感能力

一个用于 DeepSeek Harness 的桌面宠物:一个悬浮、始终置顶的窗口,在你工作时显示实时 token…

30/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/1 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

自动兼容检查有告警:npm 同名包「dsh-desktop-pet」归属 sereinmono/dsh-desktop-pet,装到的可能不是本插件。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add SherinG-official/dsh-desktop-pet
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么
dsh 原生插件 · model
装得上吗
本站已真实安装成功
非静态推断
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 31 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查⚠ 装前注意

npm 同名包「dsh-desktop-pet」归属 sereinmono/dsh-desktop-pet,装到的可能不是本插件

展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✓npm 包dsh-desktop-pet @ 0.2.0
✓Node 引擎要求 ^22.19.0 || >=24.0.0 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/3 12:27:14

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

可执行外部命令读写/删除本地文件写入剪贴板(不计风险)发起外部网络请求
查看扫描证据(共 33 处,展示前 32 条)
  • 发起网络请求
    client.js:264
    const response = await fetch(`${MEMORY_API}${path}`, init)
  • 发起网络请求
    client.js:379
    const response = await fetch(SKIN_API + path, {
  • 发起网络请求
    client.js:1048
    const response = await fetch(`${PET_CONTROL}?action=status`)
  • 发起网络请求
    client.js:1067
    const response = await fetch(`${PET_CONTROL}?action=toggle`)
  • 写入剪贴板
    client.js:1364
    void navigator.clipboard?.writeText(group.memoryPath ?? '')
  • 发起网络请求
    client.js:1952
    const response = await fetch(`${PET_CONTROL}?action=status`)
  • 发起网络请求
    client.js:2019
    const response = await fetch(`${PET_CONTROL}?action=toggle`)
  • 执行外部命令固定命令
    lib/memory/routes.js:47
    spawn('cmd', ['/c', 'start', '', target], { detached: true, stdio: 'ignore', windowsHide: true }).unref()
  • 执行外部命令固定命令
    lib/memory/routes.js:49
    spawn('open', [target], { detached: true, stdio: 'ignore' }).unref()
  • 执行外部命令固定命令
    lib/memory/routes.js:51
    spawn('xdg-open', [target], { detached: true, stdio: 'ignore' }).unref()
  • 读取本地文件
    lib/memory/store.js:137
    mtimeMs = statSync(target).mtimeMs
  • 读取本地文件
    lib/memory/store.js:240
    mtimeMs = statSync(fileOf(id)).mtimeMs
  • 读取本地文件
    lib/memory/store.js:437
    const stat = statSync(target)
  • 读取本地文件
    lib/memory/store.js:440
    text = readFileSync(target, 'utf8')
  • 读取本地文件
    lib/pet.js:56
    return candidateDirs().some((dir) => existsSync(path.join(dir, 'assets', 'pet', 'idle.png')))
  • 读取本地文件
    lib/pet.js:97
    return readFileSync(path.join(dir, 'assets', 'pet', `${pose}.png`))
  • 写入本地文件
    pet/lib/index.js:39
    appendFileSync(TRACE_FILE, `${new Date().toISOString()} ${message}\n`)
  • 读取本地文件
    pet/lib/index.js:127
    if (existsSync(stable)) return stable
  • 读取本地文件
    pet/lib/index.js:144
    if (existsSync(nested)) return nested
  • 读取本地文件
    pet/lib/index.js:146
    if (existsSync(sibling)) return sibling
  • 读取本地文件
    pet/lib/index.js:154
    if (typeof resolved === 'string' && existsSync(resolved)) return resolved
  • 读取本地文件
    pet/lib/index.js:443
    trace(`start: command=${command} exists=${existsSync(command)} cwd=${resolveCwd(config)}`)
  • 读取本地文件
    pet/lib/index.js:444
    if (!existsSync(command)) {
  • 写入本地文件
    pet/lib/index.js:453
    mkdirSync(cwd, { recursive: true })
  • 执行外部命令来自配置/变量
    pet/lib/index.js:490
    proc = spawn(command, resolveArgs(config), {
  • 发起网络请求
    pet/src/balance.js:71
    const response = await fetch(ENDPOINT, {
  • 读取本地文件
    pet/src/metrics.js:109
    return fs.readdirSync(this.dir)
  • 读取本地文件
    pet/src/metrics.js:115
    stat = fs.statSync(full);
  • 写入本地文件
    pet/src/pet.js:103
    fs.mkdirSync(path.dirname(STATE_FILE), { recursive: true });
  • 写入本地文件
    pet/src/pet.js:104
    fs.writeFileSync(STATE_FILE, JSON.stringify(next, null, 2));
  • 读取本地文件
    pet/src/pet.js:1067
    const buf = fs.readFileSync(file);
  • 读取本地文件
    pet/src/util.js:23
    return fs.readFileSync(file, 'utf8');
扫描于 2026/10/31(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/dsh-tools@deepseek-ai/schemastery
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 悬浮置顶窗口
  • 显示实时token用量
  • 显示余额

DeepSeek Harness 的 Windows 桌面外壳:原生窗口 + 独立桌宠进程,实时显示 token 用量和余额

README

由 DeepSeek 最新模型翻译生成
dsh-desktop-pet 一个用于 DeepSeek Harness 的桌面宠物:一个悬浮、始终置顶的窗口,在你工作时显示实时 token 用量和账户余额。把它隐藏后,一个小徽章会取而代之——这个徽章既是返回的入口,也是上下文压力和余额的常驻读数。harness 页面也带有一组控制项,宠物被退出后就是靠它们回来的。 · Español · हिन्दी · Português 兼容性 | 界面 | 状态 | | Harness | DeepSeek Harness 0.2.0-rc.2(desktop profile) | | Node | ^22.19.0 || >=24.0.0 | | 平台 | Windows(窗口宿主是 Electron) | 它做什么 作为 Host 插件,掌管宠物窗口的生命周期。 悬浮窗口无法从插件界面内部创建:Client 模块(dsh.client)运行在 harness 页面中,而 Host 插件运行在 Node 中,没有 Electron API。因此窗口保持为独立进程,而这个插件负责管理它——激活时启动、卸载时停止、崩溃后重启。
展开完整文档(README 剩余 1 节)
dsh-desktop-pet

一个用于 DeepSeek Harness 的桌面宠物:一个悬浮、始终置顶的窗口,在你工作时显示实时 token 用量和账户余额。把它隐藏后,一个小徽章会取而代之——这个徽章既是返回的入口,也是上下文压力和余额的常驻读数。harness 页面也带有一组控制项,宠物被退出后就是靠它们回来的。

· Español · हिन्दी · Português

兼容性

| 界面 | 状态 |
| Harness | DeepSeek Harness 0.2.0-rc.2(desktop profile) |
| Node | ^22.19.0 || >=24.0.0 |
| 平台 | Windows(窗口宿主是 Electron) |

它做什么

作为 Host 插件,掌管宠物窗口的生命周期。

悬浮窗口无法从插件界面内部创建:Client 模块(dsh.client)运行在 harness 页面中,而 Host 插件运行在 Node 中,没有 Electron API。因此窗口保持为独立进程,而这个插件负责管理它——激活时启动、卸载时停止、崩溃后重启。

该进程拥有两个窗口,且同一时刻只有一个显示在屏幕上:

| 窗口 | 显示时机 |
| 吉祥物 | 正常情况下 |
| 待机徽章 | 宠物被隐藏时 |

徽章不是装饰,它是对一扇单向门的修复:桌面外壳没有“显示宠物”的开关,所以隐藏过去是永久性的——visible: false 会被记住,没有任何办法撤销。徽章填补了这个缺口,并佩戴着两个值得关注的数字:上下文压力(脸部周围的圆环,以及标签中的数字)和账户余额。

同一个陷阱还有第二个入口:宠物自身菜单中的“退出桌宠”是一次干净退出(代码 0),插件有意不重启它——它的意思是“我不用这东西了”。这过去会让宠物无法访问,直到整个桌面应用重启。所以窗口进程之外有一个控制平面:

harness 页面 ──HTTP──> Host 插件 ──TCP 127.0.0.1:52118──> 窗口进程

Host 插件在 Web 服务器上注册一个 JSON 路由 /dsh-desktop-pet(查询参数 action:status / show / hide / toggle / scale / start / stop / restart / icon)。show 和 toggle 在没有窗口时会启动窗口,所以退出宠物不再是路的尽头。

窗口自身读取自己的数据,不需要 harness 提供任何东西:

| 显示内容 | 来源 |
| token 用量 | 引擎自身的 tokenUsage 投影行,位于 /storages/session_projcache/sessions/*.json 下 |
| 余额 | 官方 GET https://api.deepseek.com/user/balance,密钥仅在窗口进程中从 ~/.dsh/.credentials.yaml 读取 |

因为插件通过单个 ctx.effect() 注册,在 harness 中将其关闭会真正停止宠物,而热重载插件不会留下孤儿进程。

使用它

| 手势 | 会发生什么 |
| 拖动 | 移动桌宠。位置会被记住;单击不会把它扔回角落 |
| 单击 | 抚摸它——一次挤压拉伸,仅此而已 |
| 双击 | 打开 / 唤起 DeepSeek Harness 窗口 |
| 右键单击 | 菜单:打开 Harness、刷新用量和余额、桌宠大小(75% / 100% / 125% / 150%)、隐藏桌宠、吸附到右下角、退出桌宠 |
| 右键单击 → 隐藏 | 桌宠消失,徽章出现在它原来站立的位置 |
| 单击徽章 | 桌宠返回,徽章消失 |
| 拖动徽章 | 移动它;位置也会被记住 |
| 右键单击徽章 | 菜单:唤回桌宠、打开 Harness、刷新、桌宠大小、退出 |

第一次出现时,徽章会在一个小气泡中显示“点我唤回桌宠”五秒钟,之后不再自我介绍。

页面中的控件(dsh.client 模块,client.js):

| 位置 | 作用 |
| 输入框左侧的小圆按钮 | 桌宠的脸。单击 = 显示 / 隐藏;在桌宠未运行时单击 = 启动它。绿点表示它已启动;未启动时变暗 |
| 设置 → 桌宠 | 完整面板:运行状态和 pid、显示 / 隐藏 / 重启进程 / 退出进程,以及大小 75% / 100% / 125% / 150% |

两者都通过上面的 HTTP 路由,因此它们显示的内容和窗口的行为永远不会不一致。

桌宠大小是整个窗口的缩放(setZoomFactor,因此图案、文本、边框和命中测试都会一起缩放,不会出现布局偏移),以底部中心为锚点,这样桌宠的脚会保持不动。从菜单或面板选择大小会立即生效并被记住;scale 配置键只设置初始值。

状态保存在 /desktop/pet-window.json 中:位置、可见性、缩放,以及徽章的位置。

安装

pnpm pack
dsh plugin --profile desktop add ./dsh-desktop-pet-0.3.0.tgz

添加目录路径不会注册该 bundle——它必须是 tarball(或 npm/git 源)。之后重启应用:bundle 插件和 dsh.client 模块都会在启动时被扫描并加载。

pnpm 不会重新安装版本未变化的 tarball,即使其内容已更改:file: 依赖会根据 lockfile 中记录的 integrity 被视为最新。要获取新代码,请先执行 dsh plugin --profile desktop remove dsh-desktop-pet,然后再次添加。

窗口宿主是 electron,作为普通依赖安装。pnpm 的构建脚本门控必须允许它——harness 将决定权留在配置文件的 pnpm-workspace.yaml 中:

allowBuilds:
electron: true

如果 pnpm 的副作用缓存导致该副本不完整(没有 electron.exe),请改为将独立运行时放入 /desktop-pet-runtime:插件会优先使用它,因此配置文件的副本可以保持损坏而不会导致桌宠无法运行。

配置

| 键 | 类型 | 默认值 | 描述 |
| enabled | boolean | true | 插件激活时启动桌宠窗口 |
| command | string | '' | 承载窗口的可执行文件。为空时优先使用 /desktop-pet-runtime 下的 electron,然后依次查找包周围的目录 |
| args | string[] | [] | 传给 command 的参数。为空时运行打包的窗口入口 |
| cwd | string | '' | 窗口进程的工作目录。为空时使用 /desktop-pet —— 刻意不使用用户配置文件目录(其 NTUSER.DAT 锁会导致文件监视器崩溃),也绝不放在包内(运行中的窗口会占用自身目录,pnpm 随后会以 ERR_PNPM_EPERM 失败,从而永久阻塞更新) |
| restartDelayMs | number | 2000 | 异常退出后重启前的延迟。0 表示禁用重启 |
| maxRestarts | number | 5 | 放弃并记录错误之前允许的连续重启次数 |
| scale | number | 1 | 桌宠的初始大小,0.5–2(通常为 0.75 / 1 / 1.25 / 1.5)。从菜单或面板中选择的大小会被记住并覆盖此值 |
| controlPanel | boolean | true | 是否注册页面控制路由 /dsh-desktop-pet。关闭后窗口仍可工作 —— 只是页面上没有按钮 |

配置由 lib/index.js 中的 Schemastery Config schema 校验;没有任何可调项是硬编码的。无效值会在加载时大声报错,而不是静默采用默认值。

正常退出(code 0)被视为用户有意关闭桌宠,不会自动重启;只有异常退出才计入 maxRestarts。页面中的「显示桌宠」是恢复的方式 —— 它是一次有意的启动,并会重置重启计数器。

窗口进程还会监听 127.0.0.1:52118 以接收单行命令(status、show、hide、toggle、snap、scale:、quit)。该监听器同时充当单实例锁:每次应用启动都会生成桌宠,若没有它,它们就会不断堆积。Host 插件是它唯一的客户端。

开发

npm install --ignore-scripts # 迭代时跳过 electron 二进制下载
npm test

tests/lifecycle.test.js 通过一个桩上下文驱动真实插件:它断言 effect 已注册(禁用时未注册)、激活会启动子进程而 dispose 会将其终止、崩溃会重启而正常退出不会、缺失的运行时会被报告而不是被吞掉,以及控制路由会挂载到 Web 服务器上,同时插件在没有 Web 服务器时仍能工作。

client.js 是一个单一自包含的客户端 bundle —— 其中只允许 require react,入口必须是 window.__ModuleLoader__.load({ id, factory }),且 id 等于包名。没有构建步骤:编辑它,pnpm pack,重新安装。

许可证

Apache License 2.0 © 2026 dsh-desktop-pet contributors。
预览分享卡片长什么样 ↓SherinG-official/dsh-desktop-pet
分享 · DeepSeek Harness Hub
SherinG-official/dsh-desktop-pet

一个用于 DeepSeek Harness 的桌面宠物:一个悬浮、始终置顶的窗口,在你工作时显示实时 token…

回到顶部