Skip to content
dsh.fish
Bundle

dsh-minesweeper

DeepSeek Harness 扫雷插件 —— agent 工具集 + 人类面板,人机同棋盘

Source
jinzheng8115
stars
1 stars
License
MIT
Updated
Updated yesterday

Readme

# dsh-minesweeper

DeepSeek Harness 扫雷插件 —— **agent 与人类同棋盘对战**。

## 两种玩法(同一张棋盘)

- **Agent**:模型通过 `minesweeper_*` 工具经真实工具流水线落子
- **人类**:Web UI 侧边栏点「⛏ 扫雷」打开浮层面板(非模态,点聊天不会关闭);左键挖开 / 右键插旗 / **双击数字格快翻**;切换难度立即开新局。面板每 2.5s 轮询,AI 落子的格子闪烁高亮,状态栏显示每步归属(你 / AI)
- 任一方触发终局,广播一次 `minesweeper/game-over` 事件(排行榜等插件可监听)

**防作弊**:引擎棋盘每个格子都带 `isMine` 字段,工具渲染与 HTTP API 共用同一个防作弊滤网(`visibleGlyph`),双方都只能看到玩家视角信息。

## 工具集

| 工具 | 说明 |
|---|---|
| `minesweeper_new` | 开新局。可指定难度 / 自定义尺寸(rows+cols+mines)/ 随机种子 |
| `minesweeper_state` | 查看当前盘面(不含未翻开格子的地雷信息) |
| `minesweeper_auto` | 服务端确定性求解:迭代执行「旗数满足→快翻」「剩余隐藏格恰为雷数→插旗」,绝不猜测。把机械步骤从 LLM 挪到服务端 |
| `minesweeper_moves` | 批量按顺序执行多步(reveal/flag/chord,≤40 步,遇终局停止),减少逐格往返 |
| `minesweeper_reveal` | 挖开格子;踩雷即输,翻开全部安全格即胜 |
| `minesweeper_flag` | 插旗 / 拔旗(toggle \| place \| remove) |
| `minesweeper_chord` | 快翻:数字格周围旗数恰等于数字时批量翻开 |

另注册系统提示词策略段(`minesweeper-strategy`):引导模型「先 auto 清机械步骤 → 确定的多步用 moves 批量提交 → 只在真正需要推理时逐步来」。

## 配置

```yaml
- id: minesweeper
  name: dsh-minesweeper
  config:
    defaultDifficulty: beginner   # beginner | intermediate | expert
```

## 安装与运行

```sh
npm run build                                          # esbuild 打包 src → lib/index.js
dsh plugin --profile web add /Volumes/Code/Coding/DSH/dsh-Minesweeer   # 安装进 profile
nohup dsh --profile web --no-open > /tmp/dsh-web.log & # 启动 Web UI (http://127.0.0.1:3080)
```

安装后无需 --patch:bundle 自带的 `cordis.patch.yml` 会把插件插入配置树;`dsh.client` 声明让宿主自动 serve `/plugins/dsh-minesweeper/client.js` 并注入浏览器启动图。

本地开发也可用 overlay 免打包加载工具半边(见 examples/dev.overlay.yml),但客户端面板需要 bundle 安装才能被发现。

## 架构

```
src/
├── game/          纯游戏内核(移植自 Retro Minesweeper,零框架依赖)
│   ├── types.ts       Board/Cell/GameState 类型
│   ├── config.ts      三档难度 + 邻格/安全区计算
│   ├── board.ts       建盘、布雷(RNG 可注入 + mulberry32 种子随机)
│   └── gameLogic.ts   reveal/chord/flag/胜负判定(纯函数)
├── session.ts     单局会话(无 React 版 useMinesweeper;计时惰性计算,无定时器)
├── service.ts     MinesweeperService —— 人机共享的唯一状态源 + 终局事件恰好广播一次
├── routes.ts      人类面板 HTTP API(GET state / POST new·reveal·flag·chord,同源防护)
├── render.ts      模型可见渲染(防作弊层,visibleGlyph 是字形规则的唯一实现点)
├── index.ts       Cordis 接线:工具注册 + 路由挂载 + 配置 schema + 事件
└── ../client/client.js  人类玩家面板(plain JS + React,宿主 __ModuleLoader__ 加载,slots 注册侧边栏入口)(唯一依赖 harness 的文件)
```

关键实现细节:

- **依赖声明双保险**:模块级 `export const inject = ['tools']` 供 loader 读取;同时 `Object.assign(apply, { inject, Config })` 附着到函数上,使直接 `ctx.plugin(apply)` 挂载(测试 / 组合场景)也能被 cordis 正确解析依赖并用 Standard Schema 校验配置。
- **种子可复现**:相同 seed + 相同操作序列 ⇒ 同一局,便于评测与调试。

## 测试

```sh
npm run typecheck    # TS 全量类型检查(含真实 @deepseek-ai 类型)
npm run smoke        # 无头冒烟:逻辑不变量 + 防作弊不泄露 + 种子可复现
npm run integration  # 真实 Cordis 运行时:挂载 SystemPrompt → tools → 本插件,
                     # 经 ctx.tools.execute 完整管线对局并验证事件广播
npm test             # 两者全跑
```

Install

dsh plugin --profile web add github:jinzheng8115/dsh-Minesweeper

Profile: web

  • This package builds from source on install. pnpm will ask you to allow its build script — that is permission to run the package’s code on your machine, outside the agent sandbox. Only allow sources you trust.
  • This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.
Source