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

插件工具箱 LBurny/dsh-plugin

DeepSeek Harness
LBurny21 天前有提交已提供中文文档扫描:含敏感能力

DeepSeek Harness 插件。

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

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

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add LBurny/dsh-plugin
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:需留意
是什么[目录]—
dsh 原生插件 · other
暂无时间戳·判据 →
装得上吗[实装验证]!
实装验证未通过(unknown),装前请到仓库确认最近更新与 issue
L4 · 真实安装等级说明 →
数据截至 2026/11/02·判据 →
安全吗[自动扫描]—
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
数据截至 2026/11/04·判据 →
还在维护吗[仓库]✓
活跃:最近一次提交在 21 天前
暂无时间戳·判据 →
图例:✓ 通过! 需注意— 未判定 / 无数据· 「未判定」= 本站尚无数据,不代表插件有问题
档位由哪些信号合成

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

验证判据与等级说明 →
⚠︎ 实装验证未通过(unknown · 2026/11/2) ——可能是验证环境差异,装前建议到 GitHub 仓库确认最近更新与 issue。
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

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

可执行外部命令读写/删除本地文件写入剪贴板(不计风险)发起外部网络请求
查看扫描证据(共 96 处,展示前 90 条)
  • 发起网络请求
    dsh-doctor/lib/client.js:150
    const response = await fetch(path, { credentials: "same-origin" });
  • 发起网络请求
    dsh-doctor/lib/client.js:156
    const response = await fetch(path, {
  • 写入剪贴板
    dsh-doctor/lib/client.js:490
    await navigator.clipboard.writeText(text);
  • 读取本地文件
    dsh-doctor/lib/diagnostics.js:58
    info = await stat(path);
  • 读取本地文件
    dsh-doctor/lib/diagnostics.js:98
    names = await readdir(dir);
  • 读取本地文件
    dsh-doctor/lib/diagnostics.js:107
    const info = await stat(join(dir, name));
  • 读取本地文件
    dsh-doctor/lib/index.js:283
    sendText(res, 200, await readFile(join(LIB_DIR, file), "utf8"), type);
  • 读取本地文件
    dsh-doctor/lib/patches.js:78
    return normalizePatchState(JSON.parse(await readFile(path, "utf8")));
  • 发起网络请求
    dsh-features/lib/client.js:515
    void fetch(`${API}/order`, {
  • 发起网络请求
    dsh-features/lib/client.js:679
    const answer = await fetch(`${API}/features`, { credentials: "same-origin" }).then((response) => response.json());
  • 发起网络请求
    dsh-features/lib/client.js:755
    answer = await fetch(`${API}/updates`, { credentials: "same-origin" }).then((response) => response.json());
  • 发起网络请求
    dsh-features/lib/client.js:779
    answer = await fetch(`${API}/update`, {
  • 读取本地文件
    dsh-features/lib/index.js:61
    const manifest = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8"));
  • 读取本地文件
    dsh-features/lib/inventory.js:43
    return await readdir(dir, { withFileTypes: true });
  • 读取本地文件
    dsh-features/lib/inventory.js:52
    return JSON.parse(await readFile(join(path, "package.json"), "utf8"));
  • 读取本地文件
    dsh-features/lib/order.js:53
    return normalizeOrder(JSON.parse(await readFile(path, "utf8"))?.[FIELD]);
  • 读取本地文件
    dsh-features/lib/updates.js:176
    manifest = await readFile(join(layout.profileDir, "package.json"), "utf8");
  • 读取本地文件
    dsh-features/lib/updates.js:182
    const lock = await readFile(join(layout.profileDir, "pnpm-lock.yaml"), "utf8").catch(() => "");
  • 读取本地文件
    dsh-features/lib/updates.js:194
    const parsed = JSON.parse(await readFile(path, "utf8"));
  • 发起网络请求
    dsh-mcp/lib/client.js:110
    const response = await fetch(path, { credentials: "same-origin" });
  • 发起网络请求
    dsh-mcp/lib/client.js:116
    const response = await fetch(path, {
  • 读取本地文件
    dsh-mcp/lib/index.js:99
    sendText(res, 200, await readFile(join(LIB_DIR, file), "utf8"), type);
  • 读取本地文件
    dsh-mcp/lib/mcp.js:100
    before = await readFile(layout.patchPath, "utf8");
  • 读取本地文件
    dsh-mcp/lib/mcp.js:117
    text = await readFile(layout.patchPath, "utf8");
  • 读取本地文件
    dsh-mcp/lib/mcp.js:351
    text = await readFile(source.path, "utf8");
  • 读取本地文件
    dsh-mcp/lib/mcp.js:413
    await stat(path);
  • 发起网络请求
    dsh-notify/lib/client.js:86
    const response = await fetch(path, { credentials: "same-origin" });
  • 发起网络请求
    dsh-notify/lib/client.js:92
    const response = await fetch(path, {
  • 读取本地文件
    dsh-notify/lib/index.js:227
    sendText(res, 200, await readFile(join(LIB_DIR, file), "utf8"), type);
  • 读取本地文件
    dsh-notify/lib/settings.js:93
    return normalizeConfig(JSON.parse(await readFile(path, "utf8")));
  • 读取本地文件
    dsh-notify/lib/sounds.js:30
    files = await readdir(SOUNDS_DIR);
  • 读取本地文件
    dsh-notify/lib/sounds.js:48
    return await readFile(join(SOUNDS_DIR, `${id}.wav`));
  • 写入本地文件
    dsh-remote/lib/atomic.js:44
    await mkdir(directory, { recursive: true });
  • 写入本地文件
    dsh-remote/lib/atomic.js:46
    await writeFile(temp, content, { mode, flag: "wx" });
  • 写入本地文件
    dsh-remote/lib/atomic.js:50
    await rename(temp, filename);
  • 删除本地文件
    dsh-remote/lib/atomic.js:61
    await rm(temp, { force: true });
  • 发起网络请求
    dsh-remote/lib/client.js:121
    const response = await fetch(path, { credentials: "same-origin" });
  • 发起网络请求
    dsh-remote/lib/client.js:127
    const response = await fetch(path, {
  • 写入剪贴板
    dsh-remote/lib/client.js:256
    await navigator.clipboard.writeText(text);
  • 读取本地文件
    dsh-remote/lib/cloudflared.js:172
    for await (const chunk of createReadStream(path)) hash.update(chunk);
  • 执行外部命令来自配置/变量
    dsh-remote/lib/cloudflared.js:196
    child = spawn(exe, args, { windowsHide: true, stdio: ["ignore", "pipe", "pipe"] });
  • 写入本地文件
    dsh-remote/lib/cloudflared.js:366
    await chmod(from, 0o755).catch(() => {
  • 写入本地文件
    dsh-remote/lib/cloudflared.js:369
    await rename(from, to);
  • 写入本地文件
    dsh-remote/lib/cloudflared.js:424
    await mkdir(dirname(target), { recursive: true });
  • 读取本地文件
    dsh-remote/lib/cloudflared.js:435
    const executable = extractExecutable(await readFile(archive));
  • 写入本地文件
    dsh-remote/lib/cloudflared.js:437
    await writeFile(unpacked, executable, { mode: 0o755 });
  • 删除本地文件
    dsh-remote/lib/cloudflared.js:456
    await rm(leftover, { force: true }).catch(() => {
  • 读取本地文件
    dsh-remote/lib/index.js:205
    sendText(res, 200, await readFile(join(LIB_DIR, file), "utf8"), type);
  • 读取本地文件
    dsh-remote/lib/picker.js:275
    return { path, text: await readFile(path, "utf8") };
  • 读取本地文件
    dsh-remote/lib/project.js:63
    const text = await readFile(workspaceStorePath, "utf8");
  • 读取本地文件
    dsh-remote/lib/project.js:96
    rootReal = await realpath(root);
  • 读取本地文件
    dsh-remote/lib/project.js:101
    candidateReal = await realpath(join(rootReal, ...segments));
  • 读取本地文件
    dsh-remote/lib/project.js:121
    info = await stat(dir);
  • 读取本地文件
    dsh-remote/lib/project.js:128
    dirents = await readdir(dir, { withFileTypes: true });
  • 读取本地文件
    dsh-remote/lib/project.js:141
    meta = await stat(join(dir, dirent.name));
  • 读取本地文件
    dsh-remote/lib/remote.js:89
    readFile(join(ASSETS_DIR, "mobile.css"), "utf8"),
  • 读取本地文件
    dsh-remote/lib/remote.js:90
    readFile(join(ASSETS_DIR, "mobile.js"), "utf8"),
  • 读取本地文件
    dsh-remote/lib/remote.js:91
    readFile(join(ASSETS_DIR, "splash.css"), "utf8"),
  • 读取本地文件
    dsh-remote/lib/remote.js:92
    readFile(join(ASSETS_DIR, "splash.js"), "utf8"),
  • 读取本地文件
    dsh-remote/lib/remote.js:93
    readFile(join(ASSETS_DIR, "project.html"), "utf8")
  • 执行外部命令来自配置/变量
    dsh-remote/lib/remote.js:268
    child = spawn(exe, ["tunnel", "--url", target, "--no-autoupdate", "--protocol", "http2"], {
  • 读取本地文件
    dsh-remote/lib/remote.js:316
    text = readFileSync(logPath, "utf8").slice(-8192);
  • 执行外部命令固定命令
    dsh-remote/lib/remote.js:446
    const killer = spawn("taskkill", ["/PID", String(pid), "/T", "/F"], { windowsHide: true, stdio: "ignore" });
  • 发起网络请求
    dsh-remote/lib/remote.js:499
    const response = await fetch(`${url}/?token=${encodeURIComponent(token)}`, {
  • 发起网络请求
    dsh-remote/lib/remote.js:654
    const response = await fetch(`http://127.0.0.1:${String(port)}/?token=${encodeURIComponent(token)}`, { redirect: "manual" });
  • 读取本地文件
    dsh-remote/lib/settings.js:81
    return normalizeConfig(JSON.parse(await readFile(path, "utf8")));
  • 执行外部命令来自配置/变量
    dsh-remote/lib/tailnet.js:159
    child = spawn(exe, args, { windowsHide: true, stdio: ["ignore", "pipe", "ignore"] });
  • 发起网络请求
    dsh-skills/lib/client.js:85
    const response = await fetch(path, { credentials: "same-origin" });
  • 发起网络请求
    dsh-skills/lib/client.js:91
    const response = await fetch(path, {
  • 发起网络请求
    dsh-skills/lib/client.js:315
    const response = await fetch(`${API}/skills/zip?name=${encodeURIComponent(file.name)}`, {
  • 读取本地文件
    dsh-skills/lib/index.js:130
    sendText(res, 200, await readFile(join(LIB_DIR, file), "utf8"), type);
  • 读取本地文件
    dsh-skills/lib/skills.js:68
    return (await stat(join(path, SKILL_MARKER))).isFile();
  • 读取本地文件
    dsh-skills/lib/skills.js:79
    description = parseFrontmatter(await readFile(join(dir, SKILL_MARKER), "utf8")).description ?? "";
  • 读取本地文件
    dsh-skills/lib/skills.js:94
    entries = await readdir(root, { withFileTypes: true });
  • 写入本地文件
    dsh-skills/lib/skills.js:133
    await mkdir(targetRoot, { recursive: true });
  • 写入本地文件
    dsh-skills/lib/skills.js:136
    await rename(found.dir, target);
  • 删除本地文件递归
    dsh-skills/lib/skills.js:144
    await rm(found.dir, { recursive: true, force: true });
  • 读取本地文件
    dsh-skills/lib/skills.js:155
    entries = await readdir(source.dir, { withFileTypes: true });
  • 写入本地文件
    dsh-skills/lib/skills.js:191
    await mkdir(layout.skillsDir, { recursive: true });
  • 写入本地文件
    dsh-skills/lib/skills.js:197
    await mkdir(staged, { recursive: true });
  • 写入本地文件
    dsh-skills/lib/skills.js:212
    await rename(holder, old);
  • 读取本地文件
    dsh-skills/lib/skills.js:223
    info = await stat(old);
  • 写入本地文件
    dsh-skills/lib/skills.js:232
    await rename(old, holder);
  • 删除本地文件递归
    dsh-skills/lib/skills.js:244
    await rm(staging, { recursive: true, force: true });
  • 写入本地文件
    dsh-skills/lib/zip.js:277
    await mkdir(dirname(target), { recursive: true });
  • 写入本地文件
    dsh-skills/lib/zip.js:278
    await writeFile(target, readEntry(buffer, entry));
  • 发起网络请求
    dsh-zoom/lib/client.js:77
    const response = await fetch(path, { credentials: "same-origin" });
  • 发起网络请求
    dsh-zoom/lib/client.js:83
    const response = await fetch(path, {
  • 读取本地文件
    dsh-zoom/lib/index.js:83
    sendText(res, 200, await readFile(join(LIB_DIR, file), "utf8"), type);
  • 读取本地文件
    dsh-zoom/lib/settings.js:90
    return normalizeConfig(JSON.parse(await readFile(path, "utf8")));
扫描于 2026/11/4(0 天前) · 范围 全包扫描 · 来源 GitHub 仓库

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

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 按需安装独立小插件
  • 扩展dsh能力

README

由 DeepSeek 最新模型翻译生成
dsh-plugin 给 deepseek-harness(dsh)用的小插件合集:一个功能一个包,每个都能单独安装,包与包互不依赖。所有功能都跑在 dsh 本体里,不用装额外的壳,也不用多养一个进程。 有哪些插件 一共八个,想用哪个装哪个。 | 包 | 做什么 | 命令 | | dsh-features | 侧栏的功能入口,位置在插件与自动化任务之间。它把已装的功能插件列成一排卡片,样式照 dsh 自己的插件页,点开进设置页,可拖拽排序。装了它,各面板角落里的浮动按钮就收进这个页面 | 无 | | dsh-skills | 技能管理:启停、删除、导入,支持本地 ZIP 压缩包 | 无 | | dsh-mcp | 管理当前 profile 的 MCP 服务:增删改、启停、导入 | 无 | | dsh-doctor | 给插件排障:进程内读 harness 自己的日志记录,逐行显示每个插件的激活状态,附实际存在的日志文件 | /doctor | | dsh-zoom | 页面缩放,快捷键可以自己改 | 无 | | dsh-notify | 任务提醒:页面弹窗、随包音效、系统通知 | 无 | | dsh-remote | 在手机上用 dsh:带鉴权的反向代理加二维码链接,可走局域网、Tailscale 组网或 Cloudflare 隧道,附移动端界面改写和项目浏览 | 无 |
展开完整文档(README 剩余 1 节)
dsh-plugin

给 deepseek-harness(dsh)用的小插件合集:一个功能一个包,每个都能单独安装,包与包互不依赖。所有功能都跑在 dsh 本体里,不用装额外的壳,也不用多养一个进程。

有哪些插件

一共八个,想用哪个装哪个。

| 包 | 做什么 | 命令 |
| dsh-features | 侧栏的功能入口,位置在插件与自动化任务之间。它把已装的功能插件列成一排卡片,样式照 dsh 自己的插件页,点开进设置页,可拖拽排序。装了它,各面板角落里的浮动按钮就收进这个页面 | 无 |
| dsh-skills | 技能管理:启停、删除、导入,支持本地 ZIP 压缩包 | 无 |
| dsh-mcp | 管理当前 profile 的 MCP 服务:增删改、启停、导入 | 无 |
| dsh-doctor | 给插件排障:进程内读 harness 自己的日志记录,逐行显示每个插件的激活状态,附实际存在的日志文件 | /doctor |
| dsh-zoom | 页面缩放,快捷键可以自己改 | 无 |
| dsh-notify | 任务提醒:页面弹窗、随包音效、系统通知 | 无 |
| dsh-remote | 在手机上用 dsh:带鉴权的反向代理加二维码链接,可走局域网、Tailscale 组网或 Cloudflare 隧道,附移动端界面改写和项目浏览 | 无 |
| dsh-init | 为当前工作区生成或更新 AGENTS.md,dsh 会把它注入这里的每一个会话 | /init |

其中两个的位置有点特殊。

dsh-features 不是功能,是其余功能挂靠的基座,也是唯一带浏览器客户端的包,因为真正的侧栏入口只能由 dsh 客户端插件加。装了它,功能面板搬进它的页面;卸载它,浮动按钮原样回来。

dsh-init 是命令,不是功能:没有面板,基座也不会列它。它的提示词按 harness 真实的指令文件规则写,结果以一条折叠的上下文行进入会话,不占用户消息。

每个包都是普通的 dsh 插件:声明了 dsh.bundle.patch,dsh plugin add 会自动挂载。包之间互不 import,所以随便挑几个装都能用。

安装

两条路,同一套规格:桌面版的 插件 页,或终端里的 dsh plugin add。装完重启 dsh,插件没有热更新。

在桌面版里装

打开 插件 页,点 添加插件,粘一条规格,安装,再粘下一条。输入框接受包名、git 地址或本地目录路径。

github:LBurny/dsh-plugin#path:/dsh-features
github:LBurny/dsh-plugin#path:/dsh-skills
github:LBurny/dsh-plugin#path:/dsh-mcp
github:LBurny/dsh-plugin#path:/dsh-doctor
github:LBurny/dsh-plugin#path:/dsh-zoom
github:LBurny/dsh-plugin#path:/dsh-notify
github:LBurny/dsh-plugin#path:/dsh-remote
github:LBurny/dsh-plugin#path:/dsh-init

#path:/<包名> 是 pnpm 指仓库子目录的写法;八个包同在同一个仓,所以每条都带。安装顺序无所谓。

这个页面有两件事值得知道。升级就是先卸载再装一遍:没有自动更新,想装到可复现的版本就在规格里钉上 commit(#<sha>&path:/<包名>)。GitHub 拉不动时,用页面的 安装源 换源重试:默认、npm 官方、中国大陆镜像或自定义。

在命令行里装

dsh plugin add github:LBurny/dsh-plugin#path:/dsh-skills
钉 commit:
dsh plugin add github:LBurny/dsh-plugin#<sha>&path:/dsh-skills
dsh plugin remove dsh-skills

用桌面版的话注意:它的 profile 叫 desktop,应用运行时由应用独占。先退出桌面版,再给上面的命令加上 --profile desktop。一般还是走上面的插件页更省事。

在 Windows 上钉 commit。 dsh plugin 走应用自带的 dsh.cmd 垫片,cmd.exe 会吃掉 #<sha>&path:/… 里的 &,pnpm 只收到 #<sha> 就拒绝安装。钉版本请走应用的插件页,规格原样到达 pnpm;或者直接装不钉版本的分支规格。

pnpm 拉不到 github.com 时。 pnpm 用自己的 TLS 栈,不认系统代理,遇到拦 TLS 的网络会报 TypeError: fetch failed。在 $DSH_HOME/profiles/<profile>/.npmrc 里写上你的代理:

https-proxy=http://127.0.0.1:7890
proxy=http://127.0.0.1:7890

也可以离线装:把包目录拷进 $DSH_HOME/profiles/plugins/<包名>/,再 add 那个目录路径。

约定

几条规矩让这套插件能凑在一起又不互相牵连。

- 天生独立。 任何包都不 import 别的包,各自复制需要的那点辅助代码,某个包没装或版本落后都不影响别人。
- DOM 层的唯一约定。 角落的启动按钮停靠进共用的 #dsh-launchers 容器,面板靠发布的 --dsh-launcher-stack 高度避开它。
- 基座契约。 功能插件把 { title, order, mount(host) } 发布到 window.__dshFeatures,并在 package.json 里声明 dsh.ui.feature;基座据此就地挂载面板,并隐藏 #dsh-launchers。两个方向都没有 import。
- 双语面板,配色跟随主题。 语言取自 navigator.language;配色优先用 dsh 自己的 --dsw-alias-* 令牌,取不到就回落到硬编码值,按 prefers-color-scheme 切换。

要改代码?先看 AGENTS.md,坑都写在那里。

测试

都是纯 Node,没有构建步骤。每个包自带一套测试,仓根另有五套跨包测试检查包之间的约定:

cd <包名> && node tests/<包名>.test.mjs # 单个包自己的套件
node tests/hub-contract.test.mjs # 仓级:基座契约
node tests/panel-embed.test.mjs # 仓级:每个面板在有基座和没基座时都能起
node tests/mobile-layer.test.mjs # 仓级:手机层的 DOM 行为
node tests/manifest.test.mjs # 仓级:目录名即包名,裸导入都有声明
node tests/host-half.test.mjs # 仓级:每个宿主半边都能挂载,路由、资产、命令都对

每套测试自己打印总数,要求是全过。

想把整套装在一起跑,用沙箱:一条命令在 .sandbox/(已被 gitignore,且拒绝碰你真实的 ~/.dsh)起一个真 dsh,把本仓八个包都装上:

node tools/sandbox/sandbox.mjs up # 首次:建目录、安装、启动并打印 URL
node tools/sandbox/sandbox.mjs up --restart # 改完代码:重启正在跑的实例
node tools/sandbox/sandbox.mjs url # 打印 URL(含令牌)
node tools/sandbox/sandbox.mjs down # 停止

详见 tools/sandbox/README.md。界面长什么样测试断言不了,tools/visual/ 里有截图工具,见其 README。

License

MIT。dsh-notify/lib/sounds/ 下的提示音来自 opencode 项目,原样随包分发。
预览分享卡片长什么样 ↓LBurny/dsh-plugin
分享 · DeepSeek Harness Hub
LBurny/dsh-plugin

DeepSeek Harness 插件。

这个插件是你维护的吗?
作者本人可认领并核对本条目;认领通过后,详情页会显示「作者已认领」标记。
认领条目 →
回到顶部