用 dsh-minigames 给 DeepSeek Harness 网页界面加一块离线小游戏面板

前言

DeepSeek Harness(dsh)把模型、工具、会话和界面都做成插件。官方仓库 deepseek-ai/deepseek-harness 的定位是「Everything is a plugin」,目前仍处于 developer preview,接口还会变。社区里已经有一批界面增强插件:侧边栏、主题、桌宠、状态文案轮播。等模型流式输出、等 Agent 跑完一轮工具调用时,网页界面右侧通常是空的。

dsh-minigames 做的事情很具体:在 Web UI 右缘挂一块可折叠的小游戏面板,内置 18 款纯 Canvas 离线游戏。它不向模型注册工具,也不访问网络。本文按插件目录页、GitHub 仓库 README / package.json 核对后整理:它是什么、装在哪、怎么玩、开发者如何加新游戏。

需要先说明来源。DeepSeek Harness 本身由 DeepSeek AI 开源;本文引用的插件目录 deepseek-harness-plugin.com 是独立的社区站点,与 DeepSeek、幻方(High-Flyer)没有从属或背书关系,不能当成官方应用商店。

这是什么

dsh-minigames 是一款面向 DeepSeek Harness 网页界面 的界面增强插件,由 GitHub 用户 lhh010 维护,仓库为 lhh010/dsh-minigames。许可证是 BSD-3-Clause,主要语言 TypeScript。npm 包名是 @dsh-external/dsh-minigames,当前 package.json 版本为 0.3.2package.json 里声明 dsh.client.platformweb,只走浏览器端。

目录页把它归在「界面增强」,2026-08-15 收录。仓库带 dshdsh-plugin 两个 topic。2026-08-17 查阅时,GitHub 显示 20 星;目录页当时仍显示 18 星,星标以仓库页面为准。

它解决的问题可以缩成一句:等回复、等任务的间隙,在 Web UI 右侧打开一款不依赖外网、不抢聊天输入框的小游戏。作者在 README 里把它写成「摸鱼神器」,能力边界也写得很清楚:全部离线、零资源文件、Canvas 绘制;最高分只写 localStorage;键盘焦点必须点进游戏区才生效。

插件清单 dsh.plugin.jsoncontributes.toolscontributes.skills 都是空数组。它不给模型增加工具或技能,只往页面上挂一块 UI。

核心功能

右侧面板:折叠条与半屏画布

面板有两种状态,README 与目录页描述一致:

  • 折叠态:浏览器右缘一条带 🎮 的小竖条,几乎不占布局。
  • 展开态:点击后默认占窗口右半(50vw),可拖左缘,宽度限制在 360px80vw

游戏画布按面板真实可用空间缩放,工具条、画布、按键提示要一起完整显示,不出现滚动条。宽高上限 960px。浏览器缩放或拖窄面板时会重排。

挂载方式是 document.body 上的 portal,不占用宿主布局槽,也不依赖宿主服务。README 写明 dsh.client.inject 为空,客户端运行时不引入 @deepseek-ai 包。布局改成左栏、右栏或折叠时,这块面板按设计不应和主界面抢槽位。

折叠面板、切换浏览器标签页时游戏会自动暂停,回来再继续。每局最高分写入 localStorage。键盘事件只在点击游戏区域后生效,避免把聊天输入框的按键抢走。

18 款内置游戏

仓库 README 列出的 18 款(v0.3.0 起定为 18 款,随后去掉了乒乓)全部离线、无外部资源文件:

  1. 恐龙跳一跳:Chrome 经典小恐龙,含昼夜切换与雨天视觉。
  2. 俄罗斯方块:10×20 标准棋盘,含幽灵落点、暂存和下一个预览。
  3. 坦克大战(带 AI):2D 坦克,敌军贪心追踪 + 视线开火,共 3 波。
  4. 消消乐:四连通同色消除,目标分过关。
  5. 华容道:16 格数字华容道(15-puzzle),从已解状态随机滑动打乱,保证可解。
  6. 贪吃蛇:环面地图,穿边界从对侧出现,撞到自己才结束。
  7. 2048:滑动合并,合成 2048 计为达成。
  8. 扫雷:9×9、10 雷,首次点击安全,支持双击数字展开。
  9. 记忆翻牌:4×4 共 8 对。
  10. 五子棋 vs AI:15×15,AI 会连五也会堵。
  11. 跳一跳:按住蓄力、松开起跳。
  12. 打砖块:清墙进下一关,球速递增。
  13. 打地鼠:30 秒限时,5×5 共 25 洞,最多 5 只同时冒头。
  14. 黑白棋 vs AI:8×8 奥赛罗,无棋可下自动让位。
  15. Flappy:点击或空格振翅过柱。
  16. 数独:9×9,D 键切换简单 / 普通 / 困难(线索数 45 / 35 / 30)。
  17. 吃豆人:迷宫吃豆,力量豆可反吃幽灵。
  18. 跟枪练习:Pointer Lock 第一人称,锁定鼠标转视角,左键射击带后坐力。

这些规则来自仓库 README 的「游戏玩法与细节」,不是演示视频或第三方评测。若某款游戏的手感与文档不一致,以当前构建产物为准。

可扩展注册表

内置游戏走 registerGame。新增一款游戏需要实现 MiniGameDefinitionsrc/client/games/types.ts):idtitleicondescriptioncontrols,以及 create(host, options)create 返回的实例由面板驱动生命周期:

  • 切换游戏:先 destroy() 旧实例,再 create() 新实例。
  • 折叠、隐藏标签页或用户暂停:调用 pause()
  • 分数变化时通过 options.onScore?.(score) 上报,面板负责显示和最高分持久化。

README 建议把规则做成不碰 DOM、不定时器的纯函数,再用 Vitest 覆盖。仓库声称当前有 201 个纯逻辑单测;开发脚本注释里仍写着 189,以 README 正文与 changelog 的 201 为准。

安装与启用

目录页给出的安装命令如下,在已经能运行 dsh 的终端里执行:

dsh plugin add github:lhh010/dsh-minigames

插件以当前 dsh 进程的权限运行,安装时可能执行代码。安装前应检查源码仓库和许可证。若需要可复现安装,按目录页说明固定 commit 哈希。当前 main 最新提交为 a22b3c143839e4ed75e98e64345e41fb02f8d9c0(2026-08-13,文档双语提交),写法是:

dsh plugin add github:lhh010/dsh-minigames#a22b3c143839e4ed75e98e64345e41fb02f8d9c0

之后用 dsh plugins list 确认是否已进入当前配置。GitHub 来源的插件在安装时可能跑构建脚本,只安装你审查过的仓库。

仓库 README 另外提供了本地开发安装路径,前置条件写的是已构建的 DSH 20260808+ 快照和 pnpm

git clone https://github.com/lhh010/dsh-minigames.git
cd dsh-minigames
pnpm install
pnpm build

# 装入当前 web profile(写入依赖并加入 dsh.profile.bundles)
dsh plugin --profile web add /绝对路径/to/dsh-minigames

# 可选:确认组合配置里只有一行
dsh --profile web --dump-config | grep dsh-minigames

插件集合变更要重启 dsh web 后才生效。卸载:

dsh plugin --profile web remove @dsh-external/dsh-minigames

README 明确写了:仓库同时带 dsh.plugin.json(registry 通道)和 cordis.patch.yml(profile bundle 通道),二选一安装,不要同时启用。

兼容性方面,README 称已在下列基线上做实机 boot 验证:snapshot0810(snapshots/20260810T155924Z)、snapshot0811(snapshots/20260811T152241Z)、最终快照 snapshot0812(snapshots/20260812T172954Z-final),以及 npm 发版 @deepseek-ai/dsh@0.0.1-rc.5(dist-tag next)和 @deepseek-ai/dsh@0.0.1-rc.2。验证项包括 window.__DSH_BOOT__ 清单含 @dsh-external/dsh-minigames,以及 /plugins/@dsh-external/dsh-minigames/client.js 返回 200。Harness 仍在 developer preview,后续快照不保证还能直接加载。

典型用法

按 README「使用」一节,日常操作是:

  1. 启动 Web UI(dsh web,官方默认地址 http://127.0.0.1:3080)。
  2. 看页面右缘是否出现 🎮 竖条。
  3. 点击竖条,面板展开到窗口右半。
  4. 点游戏卡片开始;P 暂停,结算后 R 重开,点「选游戏」回到列表。
  5. 点「收起」折回竖条。游戏会暂停,当前局进度按 README 会保留;关卡进度是否跨会话保存见下一节。

开发者若要加自定义游戏,仓库给出的接口示例如下(摘自 README,路径以源码为准):

import { registerGame, type MiniGameDefinition } from './index.ts'

const myGame: MiniGameDefinition = {
  id: 'my-game',            // 唯一 id(选中记忆与最高分 key)
  title: '我的游戏',
  icon: '🎯',
  description: '一句话介绍',
  controls: ['空格:跳跃', 'P:暂停'],
  create(host, options) {
    return {
      start() {},
      pause() {},
      resume() {},
      destroy() {},
    }
  },
}

registerGame(myGame)

本地开发常用命令:

pnpm run typecheck   # tsc --noEmit
pnpm run test        # vitest 纯逻辑单测
pnpm run build       # 产出 lib/index.js(node half)与 lib/client.js(浏览器 bundle)

lib/index.js 是 node 侧 loader 占位(仅日志),客户端扫描依赖这一行存在。lib/client.js 通过 window.__ModuleLoader__.load 注册,id 必须与 package.jsonname@dsh-external/dsh-minigames)一致。

适用场景与注意事项

比较适合这些情况:

  • 已经在用 dsh web,希望等模型输出时有一块不离开页面的离线小游戏。
  • 需要确认插件只动浏览器 UI、不给模型加工具。
  • 想按 registerGame 自己加一款 Canvas 游戏,并沿用面板的暂停、最高分和焦点门控。

使用前注意:

  1. 权限与安全。插件以当前 dsh 进程权限运行,安装时可能执行代码。安装前检查 GitHub 源码和 BSD-3-Clause 许可证;生产或共享环境建议固定 commit。社区目录不是官方商店,收录不等于背书。
  2. 只覆盖 Web UIdsh.client.platformweb。终端 TUI、无头模式不会出现这块面板。
  3. 键盘焦点是有意设计。点过聊天输入框后,必须再点回游戏区才能继续用键盘。不要把这当成故障。
  4. 持久化范围有限。跨会话只保留最高分。消消乐以及方块 / 坦克的关卡进度不跨会话保存。恐龙的昼夜和雨天是视觉氛围,不改变碰撞判定。
  5. AI 强度有限。坦克大战 AI 是贪心追踪加视线开火,没有寻路。五子棋、黑白棋是启发式,不是完整博弈引擎。
  6. 清单版本可能落后于包版本package.json0.3.2,仓库根目录 dsh.plugin.json 里的 version 仍是 0.1.0,且描述还停留在「恐龙 / 方块 / 坦克」三款。以 package.json 和 README 正文为准。
  7. 两条安装通道不要混用dsh.plugin.jsoncordis.patch.yml 同时启用可能导致重复挂载。改完插件集合后重启 dsh web

小结

dsh-minigames 把 18 款离线 Canvas 小游戏挂在 DeepSeek Harness Web UI 右侧,折叠时只留一条 🎮 竖条,展开后在面板里自选游戏。它由 lhh010 维护,BSD-3-Clause 开源,不向模型注册工具,最高分只写本地 localStorage

目录页安装命令:

dsh plugin add github:lhh010/dsh-minigames

目录页:https://deepseek-harness-plugin.com/zh-CN/plugins/dsh-minigames/

GitHub:https://github.com/lhh010/dsh-minigames

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

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

小夜