Skip to content
dsh.fish
Bundle

dsh-plugin-onekey

真正一键安装/卸载 DeepSeek Harness 插件:拦截插件中心“复制安装命令”直接安装、/卸载 斜杠命令卸载、自动重启后端。全程代码实现,不调用 LLM。

Source
lishLRF
stars
2 stars
License
MIT
Updated
Updated 4 days ago

Readme

<div align="center">

<img src="docs/logo.svg" alt="dsh-plugin-onekey logo" width="110" />

# dsh-plugin-onekey

**真正一键安装 / 卸载 DeepSeek Harness 插件**

<em>点一下「复制」,插件就装好了;敲一下 `/卸载`,插件就没了。</em>

[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
[![CI](https://github.com/lishLRF/dsh-plugin-onekey/actions/workflows/ci.yml/badge.svg)](https://github.com/lishLRF/dsh-plugin-onekey/actions/workflows/ci.yml)
[![Release](https://img.shields.io/github/v/release/lishLRF/dsh-plugin-onekey?color=2ea44f)](https://github.com/lishLRF/dsh-plugin-onekey/releases)
[![Topic: dsh-plugin](https://img.shields.io/badge/topic-dsh--plugin-0e7490.svg)](https://github.com/topics/dsh-plugin)
[![Tests](https://img.shields.io/badge/tests-129%20passing-2ea44f)](https://github.com/lishLRF/dsh-plugin-onekey/actions)

**简体中文** · [English](README.en.md)

</div>

---

## 为什么需要它

DSH 内置的插件中心(`dsh-plugin`)目前只能把 `dsh plugin add <repo>` **复制到剪贴板**——剩下的都得自己做:打开终端、粘贴、等 pnpm、重启后端。更麻烦的是卸载:没有入口,只能手动编辑配置。

`dsh-plugin-onekey` 把整条链路补完:

| 之前 | 之后 |
|------|------|
| 点「复制」→ 自己开终端粘贴执行 | 点「复制」→ 弹窗确认 → 进度条 → 装好 |
| 装完手动重启 `dsh web` | 「立即重启后端」一键完成,页面自动恢复 |
| 装失败自己复制报错去问 AI | 「复制到工作区询问LLM」一键把提示词+报错写进输入框 |
| 卸载靠手动改配置 | 输入框敲 `/卸载` → 选中 → 确认 → 自动卸载并重启 |

## ✨ 功能特性

### 🖱️ 真正一键安装

- 在 **设置 → 插件中心** 点击任意插件的「复制」后自动弹出确认框,展示将执行的命令;
- 确认后弹窗内显示**实时进度条**(解析 → 校验 → pnpm 安装 → 配置写入);
- 后端**从系统剪贴板读取安装命令**(Windows / macOS / Linux),严格白名单校验后在 profile 目录执行,并写入 `dsh.profile.bundles`。

### 🚨 失败红条 + 一键转人工

- 失败时进度条变红、错误详情展示在弹窗下方;
- **「复制到工作区询问LLM」**:关闭弹窗并把「预置中文提示词 + 完整报错」直接写入当前工作区输入框(无会话时自动回退剪贴板),按发送即可让 LLM 诊断;
- **「关闭」**:直接关闭。

### 🔄 成功一键重启后端

- 成功提示「已经顺利配置完成,请重启 DSH 以刷新配置」;
- **「立即重启后端」**:程序按记录的原启动命令重启 DSH,前端定时探测端口恢复后自动刷新,全程无感;
- **「暂不重启,关闭弹窗」**:只关闭弹窗。

### 🗑️ `/卸载` 斜杠命令

- 工作区输入 `/卸载`,输入框上方弹出候选选项框(与原生 `/` 命令一致);
- 候选列表来自 profile 配置依赖解析,自动排除本插件、插件中心和 DSH 内置插件;
- 选中即弹确认框,**完全不经过 LLM**:直接卸载 → 写回配置 → 自动重启后端 → 弹窗显示「正在重启请稍后」→ 恢复后自动刷新。

### 🛡️ 安全与权限

- **全程代码执行,不调用 LLM**;
- 安装命令**严格白名单解析**:只接受 `dsh plugin [--profile X] add <spec>`(npm 包名 / `owner/repo` / `github:` / `git+https` / https tarball),拒绝 `file:`、`link:`、路径与一切 shell 元字符(含 `./`、`../` 路径绕过防护);
- pnpm 以参数数组启动,执行前弹窗展示将要运行的命令;
- 每次操作前后双重权限校验(配置级网关)。

### 🎛️ 设置 → 插件 → 插件配置

| 配置项 | 默认 | 关闭后 |
|--------|------|--------|
| 启用本插件 | ✅ | 斜杠命令、弹窗、后端接口全部失效 |
| 允许一键安装 | ✅ | 安装接口返回 403 |
| 允许卸载插件 | ✅ | `/卸载` 候选为空、卸载接口返回 403 |
| 允许自动重启后端 | ✅ | 「立即重启后端」不可用 |
| 允许读取剪贴板 | ✅ | 后端不再读取系统剪贴板 |

### 🧭 首次部署自动探测

零配置:profile 目录取自 `ctx.baseUrl`(cordis 配置树锚点);pnpm 走 PATH(含 corepack 回退);重启命令 = 启动时记录的 `execPath + argv + cwd + env` 快照——**天然适配 DSH 官网所有安装方式**(npm 全局 / 源码 tsx / 二进制)。探测结果实时展示在插件配置卡。

### 🧩 能力随启用/禁用增减

所有扩展点(HTTP 路由、`shell.overlay` 弹窗、`/卸载` 触发源、设置卡、剪贴板拦截)全部通过 DSH 公开插槽/服务注册并随插件 fiber 卸载:**不修改 DSH 与其他插件的任何代码**,禁用即消失、启用即恢复。

## 🚀 安装

> 要求:DSH web profile,Node ≥ 20,pnpm 可用(或 corepack)。

```bash
# npm(推荐)
dsh plugin --profile web add dsh-plugin-onekey

# GitHub
dsh plugin --profile web add github:lishLRF/dsh-plugin-onekey

# 本地开发
dsh plugin --profile web add link:<本仓库绝对路径>
```

安装后**重启 `dsh web`**,打开 **设置 → 插件 → 插件配置**,确认「dsh-plugin-onekey」已启用并检查权限勾选。

## 📖 使用指南

**一键安装**

1. 打开 设置 → 插件中心,点任意插件的「复制」;
2. 弹窗确认「是否直接配置到 DSH?」→ 点「确认安装」;
3. 等进度条走完 → 点「立即重启后端」→ 页面自动恢复。

**一键卸载**

1. 工作区输入框输入 `/卸载`;
2. 在候选列表中选择要卸载的插件;
3. 确认卸载 → 自动卸载并重启 → 页面自动恢复。

**出错求助**

失败弹窗点「复制到工作区询问LLM」→ 在输入框直接按发送。

## 🔐 安全模型

1. **命令白名单**:正则 + 首字符规则双重约束;
2. **无 shell 拼接**:参数数组 spawn(Windows 与官方 CLI 相同的信任边界,参数已被白名单净化);
3. **权限网关**:每次操作前后读取实时配置;
4. **确认弹窗**:执行前展示命令与操作对象;
5. **能力可逆**:所有注册随插件卸载,禁用即能力消失。

## 🧭 工作原理

```
插件中心「复制」按钮
        │ navigator.clipboard.writeText 包裹 / document copy 捕获(信号)
        ▼
确认弹窗(展示命令 + 权限提醒)
        │ POST /plugins/onekey/install
        ▼
后端读系统剪贴板 → 白名单解析 → 权限复核
        │ pnpm add(profile 目录,参数数组)
        ▼
bundles reconcile → 进度轮询 → 成功 / 失败红条
        │ 成功 → POST /plugins/onekey/restart
        ▼
detached 重启动器(等旧进程退出 → 按原 argv 拉起)
        │ 前端每 2s 探测 /plugins/onekey/ping
        ▼
后端就绪 → 自动刷新页面
```

`/卸载` 走同一条管线:`inputTriggers` 斜杠源 → 候选(profile 依赖 − 自身 − 插件中心)→ `pnpm remove` → reconcile → 自动重启。

## 🧪 开发

```bash
pnpm install
pnpm run test        # vitest,129 个测试(红绿 TDD)
pnpm run typecheck   # 宿主 + 客户端双 tsconfig
pnpm run build       # tsdown 双产物:lib/index.js + lib/client.js
pnpm run check       # 全量门禁(CI 同款)
```

```
src/                    宿主半侧(路由 / 剪贴板 / pnpm 执行 / 重启动器 / 设置命名空间)
src/client/             客户端半侧(弹窗 / 进度条 / 斜杠命令 / 设置卡 / 输入桥)
src/*.spec.ts           宿主纯逻辑测试(解析白名单 / reconcile / 重启脚本 / 权限网关…)
src/client/*.spec.ts    客户端状态机与控制器测试
docs/design.md          设计文档
```

## ❓ FAQ

**git 插件安装被 pnpm 拦截?** pnpm ≥ 10 会拦截 git 依赖的 `prepare` 构建脚本。失败弹窗点「复制到工作区询问LLM」即可获得针对性的 `allowBuilds` 配置步骤。

**提示 pnpm 未找到?** 安装 pnpm 或启用 corepack 后重试。

**重启后页面没自动刷新?** 重启弹窗内有「手动刷新页面」按钮兜底。

**卸载后弹窗显示失败?** v0.1.0 起卸载过程中的后端断连会被识别为「重启中」并自动接管轮询;若仍失败请提 issue 附上错误详情。

## 📄 相关项目

- [deepseek-ai/deepseek-harness](https://github.com/deepseek-ai/deepseek-harness) — DSH 本体
- [dshplugin/dsh-plugin-hub](https://github.com/dshplugin/dsh-plugin-hub) — DSH 插件中心

## 许可

[MIT](LICENSE) © dsh-plugin-onekey contributors

Install

dsh plugin --profile web add github:lishLRF/dsh-plugin-onekey

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