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

插件开发套件 caparisen/dsh-plugin-dev

DeepSeek 客户端
caparisen13 天前有提交已提供中文文档扫描:高危兼容 / 相关生态

组合配置档、启动影子实例并截图验证插件

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

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

相关生态插件(非 dsh 原生,按其对应运行时安装)
git clone https://github.com/caparisen/dsh-plugin-dev.git

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:仅索引
是什么
生态应用
桌面端 / Web 外壳,不以 dsh plugin add 安装
装得上吗
本站尚未做安装检查
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 13 天前
档位由哪些信号合成

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

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
🔴 安全扫描发现高危能力自动 · 静态分析源码
v2.7.0
🔴 扫描:高危尚无人工评估

静态扫描发现安装期即执行代码,或命令参数由运行时变量拼接(参数来源无法静态判定,从严处理)。

命令参数由运行时变量拼接读写/删除本地文件发起外部网络请求
查看扫描证据(共 34 处,展示前 34 条)
  • 读取本地文件
    src/index.js:54
    content: await readFile(SKILL_FILE, 'utf8'),
  • 读取本地文件
    bin/dsh-plugin-dev.mjs:51
    const manifest = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'))
  • 写入本地文件
    src/lib/report.mjs:32
    writeFileSync(path, value, 'utf8')
  • 读取本地文件
    src/commands/doctor.mjs:55
    dshHomeExists: existsSync(home),
  • 写入本地文件
    src/commands/shadow.mjs:50
    const log = createWriteStream(logPath, { flags: 'a' })
  • 执行外部命令表达式求值
    src/commands/shadow.mjs:51
    const child = spawn(
  • 发起网络请求
    src/commands/shadow.mjs:157
    const response = await fetch(url, { redirect: 'manual', signal: AbortSignal.timeout(5000) })
  • 执行外部命令固定命令
    src/commands/shadow.mjs:173
    execFileSync('taskkill', ['/pid', String(child.pid), '/t', '/f'], { stdio: 'ignore' })
  • 读取本地文件
    src/commands/shot.mjs:59
    if (existsSync(candidate)) return candidate
  • 执行外部命令来自配置/变量
    src/commands/shot.mjs:62
    const probe = spawnSync(candidate, ['--version'], { stdio: 'ignore' })
  • 写入本地文件
    src/commands/shot.mjs:82
    ? (mkdirSync(options.profileDir, { recursive: true }), options.profileDir)
  • 执行外部命令来自配置/变量
    src/commands/shot.mjs:87
    const child = spawn(browser, [
  • 发起网络请求
    src/commands/shot.mjs:113
    const version = await (await fetch(`http://127.0.0.1:${port}/json/version`)).json()
  • 写入本地文件
    src/commands/shot.mjs:172
    mkdirSync(dirname(options.out), { recursive: true })
  • 写入本地文件
    src/commands/shot.mjs:173
    writeFileSync(options.out, Buffer.from(shot.data, 'base64'))
  • 执行外部命令固定命令
    src/commands/shot.mjs:227
    if (process.platform === 'win32') execFileSync('taskkill', ['/pid', String(child.pid), '/t', '/f'], { stdio: 'ignore' })
  • 删除本地文件递归
    src/commands/shot.mjs:234
    try { rmSync(profileDir, { recursive: true, force: true }) } catch { }
  • 读取本地文件
    src/commands/shot.mjs:242
    if (existsSync(portFile)) {
  • 读取本地文件
    src/commands/shot.mjs:243
    const port = Number(readFileSync(portFile, 'utf8').split('\n')[0])
  • 读取本地文件
    src/commands/snapshot.mjs:121
    return readdirSync(dir, { withFileTypes: true })
  • 读取本地文件
    src/lib/cli.mjs:30
    return readdirSync(profilesDir(), { withFileTypes: true })
  • 执行外部命令来自配置/变量
    src/lib/cli.mjs:93
    const child = spawn(buildCommandLine(cli, argv), {
  • 读取本地文件
    src/lib/cli.mjs:137
    if (candidate.source === 'desktop' && !existsSync(candidate.command)) {
  • 写入本地文件
    src/lib/fsx.mjs:8
    mkdirSync(path, { recursive: true })
  • 写入本地文件
    src/lib/fsx.mjs:16
    writeFileSync(temp, data)
  • 写入本地文件
    src/lib/fsx.mjs:19
    renameSync(temp, path)
  • 删除本地文件
    src/lib/fsx.mjs:24
    rmSync(temp, { force: true })
  • 读取本地文件
    src/lib/fsx.mjs:41
    if (!existsSync(from)) return false
  • 写入本地文件
    src/lib/fsx.mjs:43
    copyFileSync(from, to)
  • 读取本地文件
    src/lib/fsx.mjs:49
    return lstatSync(path).isDirectory()
  • 读取本地文件
    src/lib/fsx.mjs:56
    return existsSync(path)
  • 删除本地文件递归
    src/lib/fsx.mjs:61
    rmSync(path, { recursive: true, force: true })
  • 读取本地文件
    src/lib/fsx.mjs:78
    return JSON.parse(readFileSync(path, 'utf8'))
  • 读取本地文件
    src/lib/fsx.mjs:87
    return readFileSync(path, 'utf8')
扫描于 2026/11/1(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

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

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

DeepSeek Harness 插件开发套件:组合配置档、启动一次性影子环境、验证宿主端、捕获客户端、回滚损坏的配置档

README

由 DeepSeek 最新模型翻译生成
@citisen/dsh-plugin-dev DeepSeek Harness(dsh)插件的开发套件:一部分是小型命令行,负责必须确定的那部分;另一部分是随包附带的智能体技能,负责中间的判断。 dsh 插件出问题,多数不是代码问题,而是组合问题(某一行解析不出来、某个补丁把整个 config 换掉了、某个服务商 id 撞了),或者客户端那一半的问题(某个 bundle 根本没挂载)。这些在单元测试里都看不出来,而一旦唯一的反馈是应用坏了,每一样都要耗掉你一下午。 dsh-plugin-dev doctor # what this machine can test dsh-plugin-dev compose --profile desktop --json # the tree the launcher would mount dsh-plugin-dev shadow --from desktop --hold # boot a throwaway copy, print url + token dsh-plugin-dev shot --url "$URL" --out shot.png # render it, capture console errors
展开完整文档(README 剩余 1 节)
@citisen/dsh-plugin-dev

DeepSeek Harness(dsh)插件的开发套件:一部分是小型命令行,负责必须确定的那部分;另一部分是随包附带的智能体技能,负责中间的判断。

dsh 插件出问题,多数不是代码问题,而是组合问题(某一行解析不出来、某个补丁把整个 config 换掉了、某个服务商 id 撞了),或者客户端那一半的问题(某个 bundle 根本没挂载)。这些在单元测试里都看不出来,而一旦唯一的反馈是应用坏了,每一样都要耗掉你一下午。

dsh-plugin-dev doctor # what this machine can test
dsh-plugin-dev compose --profile desktop --json # the tree the launcher would mount
dsh-plugin-dev shadow --from desktop --hold # boot a throwaway copy, print url + token
dsh-plugin-dev shot --url "$URL" --out shot.png # render it, capture console errors
dsh-plugin-dev snapshot save --profile desktop # something to go back to

为什么做成包,而不是脚本

开发 dsh 时,如果循环是「组合 → 对比 → 启动 → 看」,会轻松一个数量级。这个循环就是四条命令,而每条命令都有各自的坑,值得一次性解决:

- 命令行拒绝 desktop 配置档(「由 Electron 应用独占管理」),所以每次检查都得用一份副本;
- GUI 没有 token 就回 401,就绪判断靠的是 303 换 token,不是 200;
- chrome --headless --screenshot 在 SPA 上永远卡住;
- 包管理器替换掉的 link: 依赖,可能把链接的工作树删掉,连 .git 一起。

这些命令把上述坑都编码进去了;技能则说明什么时候用哪条命令,以及为什么。

安装

按 bundle 安装,智能体就能拿到技能(推荐):

dsh plugin --profile desktop add @citisen/dsh-plugin-dev

这个包会注册一个技能服务商,于是 dsh-plugin-dev 出现在智能体目录里。不会动配置档里的其他行,禁用 bundle 后它又会消失。

单独安装,只要命令行、不要技能:

npx @citisen/dsh-plugin-dev doctor
or
npm i -g @citisen/dsh-plugin-dev

命令

| 命令 | 作用 |
| doctor | 检测启动器及其版本,列出配置档,检查选中的配置档能否组合,找一个 Chromium |
| compose | 通过真实启动器组合配置档。--save 记录基线,--check 在出现漂移时以 1 退出,--json 列出条目和重复 id |
| shadow | 复制配置档(文件复制,node_modules 链接),在系统分配的端口上启动,等 URL 出现,探测它,打印 url/token/log |
| shot | 通过 CDP 在无头 Chromium 里渲染 URL:PNG、DOM 统计、控制台错误和未捕获异常。--fail-on-console-error 让它们变成致命错误 |
| snapshot | 保存、列出、恢复决定配置档组合的三个文件。restore 会先给当前状态做快照 |
常用参数:--dsh <path>、--json、--help。

环境要求

- dsh —— 桌面应用(会自动找到随附的命令行),或 PATH 上已发布的命令行,或 --dsh <path> / $DSH_CLI。
- 命令行需要 Node 20+。
- shot 需要 Chromium、Chrome 或 Edge(会自动找到;否则用 --browser <path> 或 CHROME_PATH)。
- 支持 Windows、macOS 和 Linux。桌面应用可选:任何 dsh 都能用。

工作原理

没有重写任何东西。compose 运行 dsh --profile --dump-config,再对比这段文本的差异;shadow 运行 dsh --profile <copy> --no-open --port 0,读取启动器打印的 URL;shot 通过 DevTools 协议驱动浏览器,仅此而已。启动器拒绝桌面配置档时,compose 和 shadow 会换个名字建一份临时副本 —— 就是人手动会做的同一个变通办法。

宿主那一半刻意做得很简单:读取 skills/dsh-plugin-dev/SKILL.md,注册一个技能服务商。它不会让配置档启动失败。

版本支持

在 Windows 11(Electron 44 / Node 24.21)上用 dsh 0.2.1-rc.2 测试过。这套工具会调用启动器,所以一旦某个版本改了 --dump-config、dsh web: 启动行或桌面配置档策略,doctor 会直接报错,而不是悄悄给出错误答案。请附上 doctor --json 的输出开 issue。

参与贡献

陷阱清单就是产品本身。见 CONTRIBUTING.md —— 简而言之:一个步骤第二次手动重复时就该写成脚本,一个 bug 报告就该变成 skills/dsh-plugin-dev/references/traps.md 里的一条记录。

许可证

MIT
预览分享卡片长什么样 ↓caparisen/dsh-plugin-dev
分享 · DeepSeek Harness Hub
caparisen/dsh-plugin-dev

组合配置档、启动影子实例并截图验证插件

回到顶部