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

社区插件指南 HubaKing/dsh-community-plugins

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

DeepSeek Harness(dsh)插件包:一个技能加两个审计工具。dsh_plugin_audit 离线检查已安装插件与本机 dsh 构建是否匹配;dsh_plugin_inspect 在安装前判断 tarball 是否可用…

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

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

自动兼容检查有告警:未发布到 npm registry,仅可从源码安装。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add HubaKing/dsh-community-plugins
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么
dsh 原生插件 · market
装得上吗
本站已真实安装成功
非静态推断
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 17 天前
档位由哪些信号合成

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

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查⚠ 装前注意

未发布到 npm registry,仅可从源码安装

展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✗npm 包@hubaking/dsh-community-plugins(未发布到 npm,仅可源码安装)
✓Node 引擎未声明 engines.node
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/31 04:50:30

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

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

读写/删除本地文件
查看扫描证据(共 38 处,展示前 24 条)
  • 读取本地文件
    lib/skills.js:57
    const entries = await readdir(SKILLS_ROOT, { withFileTypes: true, signal })
  • 读取本地文件
    lib/skills.js:64
    const parsed = parseSkill(await readFile(skillFile, 'utf8'), directory, skillFile)
  • 读取本地文件
    lib/skills.js:71
    const entries = readdirSync(SKILLS_ROOT, { withFileTypes: true })
  • 读取本地文件
    lib/skills.js:77
    const parsed = parseSkill(readFileSync(skillFile, 'utf8'), directory, skillFile)
  • 读取本地文件
    lib/audit.js:174
    return JSON.parse(readFileSync(file, 'utf8'))
  • 读取本地文件
    lib/audit.js:231
    return statSync(file).mtimeMs
  • 读取本地文件
    lib/audit.js:275
    const sourceTreeAvailable = root !== undefined && existsSync(join(root, 'packages'))
  • 读取本地文件
    lib/audit.js:395
    return readFileSync(file, 'utf8')
  • 读取本地文件
    lib/audit.js:417
    if (existsSync(file)) notes.push(`${PROFILE_COMPATIBILITY_FILENAME} could not be parsed; treating the profile as having no version exemptions`)
  • 读取本地文件
    lib/audit.js:575
    return existsSync(join(directory, 'packages', 'core', 'tools', 'package.json'))
  • 删除本地文件递归
    lib/inspect.js:191
    if (temporary !== undefined) rmSync(temporary, { recursive: true, force: true })
  • 读取本地文件
    lib/inspect.js:432
    entries = readdirSync(directory, { withFileTypes: true })
  • 读取本地文件
    lib/inspect.js:438
    if (statSync(manifestPath).isFile()) {
  • 读取本地文件
    lib/inspect.js:439
    const manifest = JSON.parse(readFileSync(manifestPath, 'utf8'))
  • 读取本地文件
    lib/inspect.js:477
    const installed = JSON.parse(readFileSync(manifestPath, 'utf8'))
  • 读取本地文件
    lib/symbols.js:192
    if (!existsSync(candidate)) continue
  • 读取本地文件
    lib/symbols.js:201
    return statSync(path).isDirectory()
  • 读取本地文件
    lib/symbols.js:385
    text = readFileSync(file, 'utf8')
  • 读取本地文件
    lib/symbols.js:442
    if (existsSync(candidate) && !isDirectory(candidate)) {
  • 读取本地文件
    lib/symbols.js:459
    if (existsSync(candidate) && !isDirectory(candidate)) {
  • 读取本地文件
    lib/symbols.js:462
    const text = readFileSync(candidate, 'utf8')
  • 写入本地文件
    lib/tar.js:128
    else mkdirSync(directory, { recursive: true })
  • 写入本地文件
    lib/tar.js:151
    mkdirSync(dirname(target), { recursive: true })
  • 写入本地文件
    lib/tar.js:152
    writeFileSync(target, body)
扫描于 2026/11/3(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

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

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

功能亮点

  • 发现社区插件
  • 评估社区插件
  • 安装社区插件

README

由 DeepSeek 最新模型翻译生成
dsh-community-plugins 一个 DeepSeek Harness(dsh)插件,教智能体如何发现、评估并安装社区插件,同时给它们两个工具,用来对照本机实际运行的 dsh 构建检查这些插件:一个全程离线,另一个在安装之前先拉取包。 English · 中文 适用范围 本插件完全适配 DSH Desktop(DeepSeek Harness Desktop),也能在 dsh web 和其他宿主下运行:它的技能和两个工具都通过官方公开接口注册,不使用任何桌面端专属 API。 安装与判断默认跟随实际运行的配置档(运行时从官方 profileContext 服务的 name / dir 读取)。desktop 和 web 是平级配置档,各自的 dsh.profile.bundles、依赖和 compatibility.json 相互独立;安装必须指向正在运行的那个,否则磁盘上的文件是对的,界面和运行时却毫无变化。实测(2026-09-30,Windows,dsh 0.2.0-rc.2):桌面应用组合的是 desktop 配置档,把皮肤装进 web 配置档没有任何可见效果。 本文中每一处 --profile web 都只是示例;在 DSH Desktop 上请换成 --profile desktop。 插件何时生效 bundle 层只在进程启动时组合一次。
展开完整文档(README 剩余 1 节)
dsh-community-plugins

一个 DeepSeek Harness(dsh)插件,教智能体如何发现、评估并安装社区插件,同时给它们两个工具,用来对照本机实际运行的 dsh 构建检查这些插件:一个全程离线,另一个在安装之前先拉取包。

English · 中文

适用范围

本插件完全适配 DSH Desktop(DeepSeek Harness Desktop),也能在 dsh web 和其他宿主下运行:它的技能和两个工具都通过官方公开接口注册,不使用任何桌面端专属 API。

安装与判断默认跟随实际运行的配置档(运行时从官方 profileContext 服务的 name / dir 读取)。desktop 和 web 是平级配置档,各自的 dsh.profile.bundles、依赖和 compatibility.json 相互独立;安装必须指向正在运行的那个,否则磁盘上的文件是对的,界面和运行时却毫无变化。实测(2026-09-30,Windows,dsh 0.2.0-rc.2):桌面应用组合的是 desktop 配置档,把皮肤装进 web 配置档没有任何可见效果。

本文中每一处 --profile web 都只是示例;在 DSH Desktop 上请换成 --profile desktop。

插件何时生效

bundle 层只在进程启动时组合一次。dsh plugin add 只改写配置档的 dsh.profile.bundles 及其依赖,不会改变正在运行的进程的依赖图。因此「安装成功」和「界面可见」是两件独立的事,插件的行为只有完全退出应用并重新启动之后才能判断。

三种状态彼此独立,只有第三种才能证明插件处于活动状态:

| 状态 | 位置 | 含义 |
| 已列出 | 配置档的 dsh.profile.bundles | 由 dsh plugin add / remove 维护 |
| 已组合 | 配置档的 cordis.yml | 启动时的组合产物 |
| 已加载 | 运行进程的实时依赖图 | 插件处于活动状态的唯一证据 |

dsh_plugin_audit 会把调用进程的启动时刻与配置档配置、每个已安装包逐一比对,在报告开头给出激活提示,并在受影响的插件下打印一行 activation::在该时刻之后写入的 bundle 层不在这个进程的依赖图里,只有重启后才生效。这项检查仅供参考,绝不改变兼容性结论。

完整判定标准见技能的 §7(插件何时生效)和 §8(皮肤与主题插件的适配线)。

本 bundle 为每个会话增加三样东西:

1. 一个技能(dsh-community-plugins)——如何通过 GitHub 的 dsh-plugin topic、精选索引和 npm 找到插件;安装前如何审查;如何通过官方 dsh plugin 机制安装;如何验证结果。
2. 离线工具(dsh_plugin_audit)—— 把已安装的插件与本机 dsh 构建做对比,逐个插件报告:哪些坏了、哪些只是有风险、哪些无法判断。它不拉取任何东西。
3. 联网工具(dsh_plugin_inspect)—— 下载包已发布的 tarball,对照注册表公布的哈希校验,解压到临时目录,在安装之前就做出判断。它从不安装任何东西,也从不运行包的生命周期脚本。

两个工具刻意分开。审计的承诺是不碰网络;加一个偶尔让它联网的开关,承诺就变成有条件的,而有条件的承诺不算承诺。两个工具,两份保证,各自说清自己是哪一种。

为什么需要这个插件

DeepSeek Harness 通过两种互补机制提供插件能力:工具和技能。

| | 工具(例如 market_search) | 技能(由本插件注册) |
| 本质 | 能力通道:可调用的函数 | 上下文知识:何时、为何、如何调用 |
| 单独使用效果 | 工具存在,但智能体不认识它 | 没有可调用的市场接口 |

只有市场工具不够,因为智能体的行为由上下文知识驱动。web_search 描述直观,是任何模型的默认做法;market_search 是 DSH 专有的。没有这个技能,智能体不知道它存在,不会把它和安装插件联系起来,也不了解本地配置档布局、bundle 机制、审查工作流和重启要求。

只有知识也不够:生态里最硬的实际问题 —— 「升级 dsh 会不会弄坏我装的东西?」 —— 靠手工无法可靠回答,因为下面的 rc 预发布规则让肉眼判断失效。

为什么用实时探测,而不是兼容性数据集

上游刻意声明 API 面不稳定:

- README.md —— 「THERE WILL BE COMPATIBILITY-BREAKING CHANGES.」
- AGENTS.md —— 「Public APIs are pre-stable; update every consumer.」

因此,API 面的缓存快照从写下的那一刻起就开始腐烂。实测:一个月内 16 个 0.x 预发布 —— 大约每周一个破坏性变更。数据集需要持续维护,两次更新之间就是错的,而一个自信地给出错误答案的验证工具,比没有工具更糟。

所以本插件不存任何东西。dsh_plugin_audit 每次调用都读取 dsh 安装根目录和配置档,回答的是这台机器、此刻的情况;dsh_plugin_inspect 读取刚下载的 tarball,对照同一份构建作答。没有遥测,没有缓存,没有需要保鲜的数据 —— 真查不了的时候,两个工具都说 unknown 并给出原因,而不是猜。
与约 75 个市场插件、生态里已有的 3 个以上静态审计器、乃至官方运行时检查器的区别就在这里:它们要么列出插件、给插件排名、扫描安全问题,要么描述当前正在运行的东西。它们都不拿插件的声明范围与实际 API 用法去对照你的 dsh 构建,也做不到对一个尚未安装的插件做这种对照。

与官方运行时检查器互补。 @deepseek-ai/dsh-tool-cordis 提供 cordis_inspect_,精确查询实时运行时(Service.listService、Event.listEvents、Tool.listTools,以及用 Slots.listSubTree 取真实的客户端 slot props)。要问「运行时现在长什么样」,那严格来说是更好的工具。本插件回答的是另一个问题——「磁盘上的声明是否仍与这里安装的构建对得上」——而且在检查器无能为力的地方照样能用:加载失败的插件不在实时运行时里,检查器根本看不到它。 静态检查读磁盘,检查器读进程。两者都需要。

两者都不预测未来的升级。它们只能看到本机安装的构建;对「升级后什么会坏」这个问题,诚实的答案是升级后再跑一遍。

离线审计工具

dsh_plugin_audit({}) # every third-party plugin in the profile
dsh_plugin_audit({ target: 'dsh-llm-local-token' }) # one package (name or directory)

对每个插件,它报告:

| 检查项 | 事实来源 |
| 它的 bundle 层能否挂载? | 磁盘上是否存在 dsh.bundle.patch,以及包名是否出现在 dsh.profile.bundles 中 |
| peerDependencies 范围是否满足? | 本机实际安装的各包版本,包括 vendor/ |
| dsh 自己的版本门禁会不会加载它? | evaluatePluginCompatibility 的规则:只看 @deepseek-ai/dsh 这类 peer,用 includePrerelease 与正在运行的 dsh 版本比较,再由 compatibility.json 中的精确版本授权放行 |
| 导入的 @deepseek-ai/ 包是否还存在? | dsh 安装根目录(packages/、vendor/、node_modules/@deepseek-ai) |
| 这些导入需要的具名导出是否仍被导出? | 包的声明入口,沿 export 重导出逐层遍历,再与其运行时入口取并集 |
| 注册的客户端 slot 是否仍有定义? | 从官方 packages/client + packages/core 源码中提取的 slot 契约 |
| inject 的服务名能否解析? | 实时 Cordis 上下文 |
| 安装期风险信号? | npm 生命周期脚本,按安装来源分级——preinstall / install / postinstall 在从 registry 安装时运行,prepare / prepublishOnly 只在 git 或本地安装时运行——外加 child_process、eval、远程导入、网络 |
| 它是否处于活跃状态,而不只是已安装? | 用调用进程的启动时刻,对照配置档配置和每个已安装包:在这个时刻之后写入的 bundle 层不在运行图中(仅供参考;从不改变判定结果) |

判定结果是分级的,不是二元的:

| 判定 | 含义 |
| compatible | 这个工具能做的每一项检查都通过了 |
| at-risk | 声明的范围不再匹配,它所在的层没有组合进来,或者 dsh 的版本门会拒绝加载这一行,除非将它豁免——这是这个生态的常态。版本门拒绝不等于启动失败:预检会禁用那一行,配置档仍然能启动 |
| incompatible | 硬证据:它需要的包、导出或槽位在这个构建里已经没了,或者它的 bundle 层无法挂载 |
| unknown | 某项检查需要离线做不了;原因总会写明 |

输出契约,以及为什么在代码里强制执行

工具的返回值必须是无损 JSON:每个可达的值都要在 JSON.parse(JSON.stringify(x)) 之后原样存活。只要有一个属性值是 undefined,就违反了这条,宿主的反应是丢弃整个结果——工具跑了、下载了、解包了、判定了,最后什么都没交付。

这种事发生过两次,来自同一类缺陷,出现在两个地方:github 解析器没有 latestVersion/ageMinutes/skippedByAge,这几个字段却被无条件合并进报告;实时服务探测可能返回 undefined,这个值被直接存进 runtimeServices[].present。第一种情况下 registry 规格不受影响,所以故障只出现在需要 GitHub release 的那条路径上。

两处都在源头修好了,契约现在靠强制执行,而不是靠信任:lib/serialize.js 在两个工具输出报告时都会清洗,修过的报告会在底部说明,而不是被悄悄改正。isLosslessJSON() 也放在同一个模块里——它正是能抓住第一次事故的那项检查,所以它该待在代码里,而不只是待在测试里。

符号级检查,以及为什么「包还在」不够

插件写了 import { PiAiAdapter } from '@deepseek-ai/dsh-llm',只有那个包仍然导出 PiAiAdapter 时它才能继续工作。改名或拆分之后,包还在,绑定没了——而对模块并不提供的绑定做 ESM 具名导入,是链接期抛错,不是功能降级。

确认这一点比 grep 一个文件难,因为包的导出面是一张图。官方声明是 barrel,TypeScript 会输出源文件扩展名:

export * from './attribution.ts'; // the file shipped beside it is attribution.d.ts
export { BlockAssembler } from './assembler.ts';
单文件扫描会把每个再导出的符号都报成缺失。所以这项检查要遍历依赖图——相对路径说明符、.ts/.js → .d.ts 的映射、指向其他包的裸说明符——并把两件事严格分开:

- 它已确认的符号集合,以及
- 这个集合是否完整。

只有完整的依赖图才有资格用「已移除」这个词。不完整的图只能给出 unknown,因为「我解析不了」不等于「它没了」。声明类型面会和运行时入口自身的导出列表取并集,这样过期的声明就不会凭空造出失败。

在本机验证过(2026-09,dsh 0.1.5-rc.1):检查了 279 个官方包,276 个声明图完整解析,核对了 1,874 个运行时导出名,0 个未确认。 三个不完整的图报成 unknown,绝不报成移除。测试套件在运行它的任何机器上都会重跑这轮扫描。

一个坏插件能让 dsh 起不来

这就是为什么先做层级检查。下面三种情况会直接抛错,而不是降级,导致整个配置档启动失败:

| 情况 | 上游行为 |
| 声明了 dsh.bundle.patch,但包里没有这个文件 | failed to read overlay —— 抛错(packages/boot/app-boot/src/index.ts:315-323) |
| 声明了 dsh.bundle,却没给 patch 路径 | declares no dsh.bundle —— 抛错(packages/boot/app-boot/src/profile.ts:792-797) |
| dsh.profile.bundles 指向的包解析不了 | 层级解析失败 —— 抛错(同一文件) |

还有一种静默失败:补丁能读,但它的包不在 dsh.profile.bundles 里——这一层永远不会被应用,插件也就什么都不做。常见原因是在配置档里用 pnpm add 安装,而不是用 dsh plugin add,后者才会同步那个列表(apps/cli/src/plugin.ts:59-91)。

工具会为每个插件打印一行 layer …,其余问题作为阻塞项抛出,所以你重启 dsh 之前就能看到全部情况。这些判断是精确的——它们读 package.json 和文件系统,不靠源码启发式。

这个功能专门要抓的 rc 预发布陷阱

^0.1.0-rc.5 展开为 >=0.1.0-rc.5 <0.2.0-0。它能匹配 0.1.5-rc.1 吗?

不能。 只有当某个比较符锁定相同的 major.minor.patch、且自身就是预发布版本时,预发布版本才满足范围。这里的比较符是 [0,1,0] 和 [0,2,0];版本是 [0,1,5]。两者都不匹配,所以预发布规则会拒绝它。

| 范围 | 版本 | 结果 |
| ^0.1.0-rc.5 | 0.1.5-rc.1 | ✗ 不满足 |
| ^0.1.0-rc.6 | 0.1.5-rc.1 | ✗ 不满足 |
| ^0.1.0-rc.5 | 0.1.0-rc.6 | ✓ 满足 |
| ^0.1.0-rc.5 | 0.1.5 | ✓ 满足 |

已对照 npm 自带的 semver 验证。这一点很重要,因为 pnpm 默认不会因 peer 依赖不满足而阻止安装——所以「装上了」从来不代表「范围匹配」,Issues with peer dependencies found 警告说的是实话。

安装前工具

dsh_plugin_inspect({ spec: 'dsh-llm-local-token' }) # npm, latest
dsh_plugin_inspect({ spec: '@scope/pkg@^1.2' }) # npm, a range
dsh_plugin_inspect({ spec: 'github:owner/repo#v1.2.0' }) # a repository
dsh_plugin_inspect({ spec: 'https://host/pkg.tgz' }) # a tarball URL
dsh_plugin_inspect({ spec: ['pkg-a', 'pkg-b', 'pkg-c'] }) # screen many candidates at once

spec 传数组就是筛查模式,这种模式完全不下载任何包字节:只读 registry 文档,判断声明的 peer 范围、dsh 的版本门槛和 manifest 里的生命周期脚本,并说明自己看不到什么。它存在的理由:以前问「这四十个候选里,哪些能在这台机器上装?」要花四十次下载。挑出幸存者之后,再用单个 spec 字符串做完整审计。

筛查出来的行标的是 METADATA-OK,绝不会标 COMPATIBLE,而且每一行都带 · package contents not audited。两套结论词汇故意分开:COMPATIBLE 是完整审计里最强的词,借给一个从不打开包的模式,正好会招来最糟的误读——曾有十四行 COMPATIBLE,意思被读成「这十四个都能安全安装」,而其中一个带了 install.cmd,完全绕开 dsh plugin。

名字撞车单独报告,不并入结论。 这个生态里同一个想法会在好几个 scope 下重新发布,所以两种模式都会找同名兄弟并点名(! this name has N other publisher(s))。它回答的是「这是我想装的那个包吗?」,这个问题任何 manifest 分析都答不了:dsh-reasoning-effort 有五个发布者,裸名是 AT-RISK,而大多数人想要的那个包根本没发布到 npm。这项检查从不改变结论,只读 registry 元数据,registry 不响应时它什么都不报,而不是让审计失败。

这是插件里唯一用网络的部分,它的名字、描述和输出都写明了这一点。 它做的事:

| 步骤 | 细节 |
| 解析 | 读 registry 文档,挑出一个具体版本,这样报告能说清判的是哪个版本 |
| 下载 | 流式拉取 tarball,上限 64 MiB |
| 校验 | 解包前核对 registry 公布的 integrity(sha512/sha384/sha256)或 shasum——对不上就中止审计 |
| 解包 | 解到 mkdtemp 目录,每条退出路径上都删掉 |
| 判定 | 和离线审计同一套结论引擎,跑在同一个本地 dsh 构建上 |

它不做的事:不安装任何东西,不写配置档,不运行包的生命周期脚本。postinstall 钩子只作为高危发现上报,不会执行。

因为它要处理本仓库之外的人产出的字节,解包器是手写并加固过的,没有直接引第三方:

| 攻击 | 行为 |
| ../escape.txt、package/../../escape.txt | 拒绝并上报 |
| /absolute.txt、C:\… | 拒绝并报告 |
| symlink / hardlink 条目 | 跳过,绝不创建 —— 这样后续条目就无法通过该链接写入 |
| 头部谎报自身大小 | 读取器直接停止,不会越过末尾继续读 |
| 解压炸弹 | 单文件、总大小、条目数三重上限,超限即大声报错 |

报告还会标出安装期风险,包括 SKILL.md 警告的那一类:仓库自带的 install.sh / setup.ps1 直接改配置档,并手工把包链接进 node_modules,绕过 dsh plugin 的依赖管理 —— 此后 dsh plugin update 和 remove 就管不到它了。

定位:轻量是设计出来的

| 属性 | 取值 |
| 运行时依赖 | 1 个(yaml,只用来解析 bundle 补丁)—— tar 读取器是手写的,不算依赖 |
| 构建步骤 | 无 —— 纯 JavaScript,没有 prepare 脚本,不需要 allowBuilds 授权 |
| 插件形态 | bundle + 两个宿主工具;没有 dsh.client,没有 UI 界面 |
| 网络 / 遥测 | dsh_plugin_audit:无,只读本地文件。dsh_plugin_inspect:只读 GET,仅在调用时发起;无遥测,无凭据 |

工具定义是手写的普通对象,没有用 @deepseek-ai/dsh-tools 的 defineTool 构建。ctx.tools.register 只要求 { name, description, parameters, output: { schema, render }, execute } —— 上游重命名或挪走导出符号时,普通对象不会坏,而「pre-stable」策略明说这种事会发生。测试套件把两种写法都跑过 dsh 自己的 assertSupportedJsonSchema 和 validateJsonSchemaValue,证明都可用。

两个工具都通过 ctx.get('tools') 挂载,而不是 inject = ['tools']。声明成依赖的话,任何没有组合 tools 服务的部署都会让整个插件 —— 包括技能 —— 进入 waiting 状态。技能必须始终能加载;工具则安静地降级,一个注册被拒不会把另一个工具也拖下水。

两个工具都声明了 timeoutMs 预算,并且真的遵守。这个字段是承诺,不是装饰:dsh 的契约规定,声明 timeoutMs 就等于断言该工具会转发 exec.signal,并在预算中止时能到达静止状态。因此 execute 把 signal 一路传进扫描和下载,中止会以 AbortError 浮出,而不是悄悄超时。(预算从不发给模型;schemas() 只白名单 name、description、parameters。)

中立性

这个插件刻意不做推荐引擎。它教方法、报事实;不排名、不背书、不推荐任何第三方插件或市场。候选插件只附可验证的事实(形态、许可证、活跃度、已知风险),选择权在用户。工具只报兼容性,从不说「更好」。

安装

前置条件:dsh 命令行(或从 dsh 安装根目录调用 apps/cli/lib/bin.js)。

GitHub direct install (pure JS, no build scripts, no build authorization)
dsh plugin --profile web add github:HubaKing/dsh-community-plugins

Gitee mirror (faster in mainland China)
dsh plugin --profile web add https://gitee.com/HubaKing/dsh-community-plugins.git

tarball (works offline)
curl -LO https://github.com/HubaKing/dsh-community-plugins/releases/download/v0.4.0/hubaking-dsh-community-plugins-0.4.0.tgz
dsh plugin --profile web add ./hubaking-dsh-community-plugins-0.4.0.tgz

source + link (development mode, edits to SKILL.md take effect immediately)
git clone https://github.com/HubaKing/dsh-community-plugins.git "${DSH_HOME:-~/.dsh}/plugins/dsh-community-plugins"
dsh plugin --profile web add link:${DSH_HOME:-~/.dsh}/plugins/dsh-community-plugins

⚠️ npm 形式务必带上 @hubaking/ 作用域。 npm 上不带作用域的名字 dsh-community-plugins 属于另一个项目(funcodingdev/dsh-community-plugins,TypeScript 编写,带构建脚本),所以 dsh plugin add dsh-community-plugins 会悄悄装上那个包。

⚠️ 带作用域的包还没发布到 npm。 截至 2026-09,dsh plugin add @hubaking/dsh-community-plugins 返回 404;配好 NPM_TOKEN 后,发布工作流会在打 v 标签时发布它。在那之前,请用上面任意一种形式。

安装完成后重启 dsh(bundle 层在启动时组合)。<available_skills> 里出现 dsh-community-plugins,并且工具列表里同时出现 dsh_plugin_audit 和 dsh_plugin_inspect,就说明安装成功。

dsh 不在 PATH 上时,有两种形态要记,而不是一条路径:

- 打包安装 —— 命令行在 asar 内部,由应用管理的 shim 启动:& "<install root>\resources\runtime\cli\bin\dsh.cmd" plugin --profile web add <spec>。注意 <install root>\resources\app.asar.unpacked\dsh 里只有 node_modules,所以那里没有 apps/cli/lib/bin.js。
- 源码检出 —— node <checkout>/apps/cli/lib/bin.js plugin --profile web add <spec>。

安装根目录的查找顺序:$DSH_ROOT → 从运行进程入口向上找,直到某个目录同时含 packages/ 和 apps/cli/ → ~/work/deepseek-harness、~/deepseek-harness、~/dsh。只有源码检出能作为安装根目录,供审计的 API 面检查使用;纯打包安装会把这类检查降级为 unknown,并在 limits of this run: 下说明。

工作原理

| 文件 | 职责 |
| index.js | 插件入口:注册技能服务商,再通过 ctx.get('tools') 挂上两个工具 |
| lib/skills.js | 解析 skills/<name>/SKILL.md 包,注册到 ctx.skills |
| lib/tool.js | 离线工具定义,以及人类可读报告的渲染器 |
| lib/inspect-tool.js | 联网工具的定义及其渲染器 |
| lib/audit.js | 定位 dsh 根目录与配置档,扫描插件,给出判定结果 |
| lib/symbols.js | 沿 export 桶文件遍历声明图,确认具名导出 |
| lib/semver.js | 无依赖的 semver 匹配,行为对齐 node-semver,含预发布规则 |
| lib/registry.js | 解析 registry/仓库,校验完整性,限制下载大小 |
| lib/inspect.js | 拉取、解包并判定尚未安装的包,随后删除临时目录树 |
| lib/tar.js | 手写的加固 tar 读取器:拒绝路径穿越、链接条目和压缩炸弹 |
| cordis.patch.yml | 打包补丁层:- insert: 行在配置档启动时挂载插件 |

开发

npm install # only yaml
npm test # semver + symbols + live audit + fixtures + tar + pre-install + contract + integration

这些测试套件在任何机器上都应能派上用场:

- test/semver.test.mjs — 在能访问到 npm 的 semver 时,用它交叉验证 lib/semver.js(930 组范围/版本对和 900 组排序对,目前零不一致,另有显式断言)。
- test/symbols.test.mjs — 用合成包测试导出图解析器:带 .ts 后缀的 export *、带别名的再导出、桶文件里的私有类、无法解析的图,以及过去会被错误归属的 import 形式。
- test/audit.test.mjs — 针对本机真实安装运行审计并打印报告;机器相关的值只打印,不做断言。它还会把上面描述的整个导出面扫描再跑一遍,作为自洽性校验。
- test/fixtures.test.mjs + test/fixtures.mjs — 在临时目录里搭建合成的 dsh 主目录(配置档、已安装插件、回退、可选的源码树),断言精确的判定结果,覆盖每条启动失败路径和每种符号检查结果。
- test/tar.test.mjs — 用本不该接受的归档测试解包器。
- test/inspect.test.mjs — 针对本地 HTTP 服务器(不是 npm)端到端测试预安装工具:版本选择、完整性校验、拒绝路径穿越与链接条目、临时目录清理,以及「什么都没装」的保证。
- test/plugin.test.mjs — 检验 apply 契约、所有优雅降级路径,并用 dsh 自带的 schema 校验器验证两个手写工具定义。
- test/integration.test.mjs — 通过真实的 Cordis Context 和真实的 ToolRuntime 加载插件,然后检查两个工具确实对模型可见,并在卸载时被释放。

目录结构

dsh-community-plugins/
├── index.js # Plugin entry
├── lib/
│ ├── audit.js # Environment probe + verdicts
│ ├── semver.js # rc-aware range matching (no deps)
│ ├── skills.js # SKILL.md provider
│ ├── symbols.js # Export-graph resolution
│ ├── tool.js # 离线工具 + 渲染器 │ ├── registry.js # 仓库访问 + 完整性校验 │ ├── inspect.js # 安装前审计 │ ├── inspect-tool.js # 联网工具 + 渲染器 │ └── tar.js # 加固的 tar 读取器 ├── test/ # Node 原生测试,不用框架 ├── cordis.patch.yml # 打包补丁层 ├── package.json # dsh.bundle 清单 ├── README.md # 英文 ├── docs/lang/README_zh.md # 中文 └── skills/dsh-community-plugins/SKILL.md

修改技能内容

编辑 skills/dsh-community-plugins/SKILL.md,保存即生效(服务商每次发现都会从磁盘重新读取),然后 git push 分享出去。改动 index.js 或 lib/ 需要重启 dsh —— patchReload: live 只重新读取 cordis.patch.yml,不会替换源码模块。

相关文档

- DeepSeek Harness 官方仓库
- 官方文档(英文)
- 官方文档(简体中文)
- 打包与安装插件
- 插件与生命周期
- GitHub dsh-plugin 话题

许可证

MIT
预览分享卡片长什么样 ↓HubaKing/dsh-community-plugins
分享 · DeepSeek Harness Hub
HubaKing/dsh-community-plugins

DeepSeek Harness(dsh)插件包:一个技能加两个审计工具。dsh_plugin_audit 离线检查已安装插件与本机 dsh 构建是否匹配;dsh_plugin_inspect 在安装前判断 tarball 是否可用…

这是你的仓库?认领条目

回到顶部