为 DeepSeek Harness 内置分支缺失的上游 cordis 修复做回溯移植
30.8/100
综合分
1
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/3 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
自动兼容检查未通过:仓库根目录及浅层子目录均无 dsh 插件清单,无法用 dsh 插件安装命令安装。以下命令仍可尝试,但可能失败。
无法用 dsh 插件命令安装(仓库内无 dsh 插件清单)
git clone https://github.com/173787247/dsh-cordis-backport.git按该仓库 README 的原生方式安装;若作者另行发布了 DSH 插件包,请以其文档为准
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:需留意
是什么
dsh 原生插件 · other
装得上吗
作者未把包发布到 npm,只能用源码安装
插件本身没问题,是分发方式不同
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 32 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查需源码安装仓库根目录及浅层子目录均无 dsh 插件清单,无法用 dsh 插件安装命令安装
展开查看检查明细 ↓
以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。
✗npm 包dsh-cordis-backport(未发布到 npm,仅可源码安装)
✓Node 引擎未声明 engines.node
✓dsh CLI 依赖未声明 dsh 版本约束
✗入口文件缺少入口声明
源码安装时若 pnpm 拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑。
验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/11 22:22:34
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
可执行外部命令读写/删除本地文件
查看扫描证据(共 33 处,展示前 30 条)
- 写入本地文件dsh-plugins/_shared/gen-docs.mjs:42
writeFileSync(join(d, "README.md"), `# ${d} - 写入本地文件dsh-plugins/_shared/gen-docs2.mjs:40
writeFileSync(join(d, "README.md"), `# ${d} - 写入本地文件dsh-plugins/_shared/gen-simple.mjs:226
writeFileSync(join(p.dir, "lib", `${p.mod}.js`), js); - 写入本地文件dsh-plugins/_shared/gen-simple3.mjs:36
writeFileSync(join(p.dir, "lib", `${p.mod}-exec.js`), `import { runPowerShell } from "./wsl-host.js"; - 写入本地文件dsh-plugins/_shared/gen-simple3.mjs:94
writeFileSync(join(p.dir, "index.js"), `import { detectWsl } from "./lib/wsl-host.js"; - 读取本地文件dsh-plugins/_shared/gen-zh.mjs:36
for (const d of readdirSync(".").filter((n) => n.startsWith("dsh-wsl-"))) { - 读取本地文件dsh-plugins/_shared/gen-zh.mjs:37
let zh = readFileSync(`${d}/README.md`, "utf8"); - 写入本地文件dsh-plugins/_shared/gen-zh.mjs:40
writeFileSync(`${d}/README.zh.md`, zh); - 写入本地文件dsh-plugins/_shared/scaffold.mjs:47
for (const d of ["lib", "test", "docs"]) mkdirSync(join(dir, d), { recursive: true }); - 写入本地文件dsh-plugins/_shared/scaffold.mjs:48
writeFileSync(join(dir, "package.json"), JSON.stringify(pkg(p), null, 2) + "\n"); - 写入本地文件dsh-plugins/_shared/scaffold.mjs:49
writeFileSync(join(dir, "cordis.patch.yml"), patch(p)); - 写入本地文件dsh-plugins/_shared/scaffold.mjs:50
for (const f of ["LICENSE", "wsl-host.js"]) copyFileSync(join(HERE, f), join(dir, f === "wsl-host.js" ? "lib/wsl-host.js" : f)); - 写入本地文件dsh-plugins/_shared/scaffold.mjs:51
writeFileSync(join(dir, ".gitignore"), "node_modules/\n*.log\n"); - 写入本地文件dsh-plugins/_shared/scaffold.mjs:53
writeFileSync(join(dir, "docs/awesome-entry.yml"), `url: https://github.com/173787247/${p.name} - 读取本地文件dsh-plugins/_shared/verify-entries.mjs:16
const DIRS = readdirSync(".").filter((n) => n.startsWith("dsh-wsl-") && existsSync(join(n, "package.json"))); - 读取本地文件dsh-plugins/_shared/verify-entries.mjs:16
const DIRS = readdirSync(".").filter((n) => n.startsWith("dsh-wsl-") && existsSync(join(n, "package.json"))); - 读取本地文件dsh-plugins/_shared/verify-entries.mjs:25
const pkg = JSON.parse(readFileSync(join(dir, "package.json"), "utf8")); - 读取本地文件dsh-plugins/_shared/verify-entries.mjs:26
const entry = readFileSync(join(dir, "docs", "awesome-entry.yml"), "utf8"); - 读取本地文件dsh-plugins/_shared/verify-entries.mjs:28
const index = readFileSync(join(dir, "index.js"), "utf8"); - 读取本地文件dsh-plugins/_shared/verify-entries.mjs:29
const libs = readdirSync(join(dir, "lib")).map((f) => readFileSync(join(dir, "lib", f), "utf8")).join("\n"); - 读取本地文件dsh-plugins/_shared/wsl-host.js:56
return readFileSync("/proc/sys/kernel/osrelease", "utf8"); - 执行外部命令来自配置/变量invariants/run.mjs:35
const p = spawn(cmd, args, { cwd, stdio: ['ignore', 'pipe', 'pipe'] }) - 读取本地文件invariants/run.mjs:66
if (!existsSync(line.root)) { - 写入本地文件invariants/run.mjs:72
await mkdir(join(dir, 'lib'), { recursive: true }) - 读取本地文件invariants/run.mjs:74
const src = (await readFile(join(HERE, file), 'utf8')) - 写入本地文件invariants/run.mjs:77
await writeFile(join(dir, file), src) - 读取本地文件invariants/run.mjs:79
if (existsSync(join(HERE, 'mockloader.mjs'))) { - 删除本地文件递归invariants/run.mjs:85
await rm(dir, { recursive: true, force: true }) - 读取本地文件reading-status.mjs:14
const prog = JSON.parse(readFileSync(FILE, 'utf8')) - 写入本地文件reading-status.mjs:20
writeFileSync(FILE, JSON.stringify(prog, null, 1) + '\n')
扫描于 2026/11/4(0 天前) · 范围 全包扫描 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
功能亮点
- 回溯移植上游修复
- 补齐内置分支缺失修复
README
由 DeepSeek 最新模型翻译生成dsh-cordis-backport
对 DeepSeek Harness 里 vendor 的那条 cordis 线做的一次审计,以及它尚未跟进的上游修复的回移补丁。
背景与讨论:https://github.com/deepseek-ai/deepseek-harness/discussions/7922
这是什么
DeepSeek Harness 用的是 @deepseek-ai/cordis@4.0.4 及其插件包,而不是 npm 上公开的 cordis。这条线不是把 cordis@4.0.0-rc.10 改了个版本号——它是一条独立演进的线,有自己的 config/diff.ts、自己的 volatile 概念、自己对 disabled 里 !!js 的处理。两条线各有取舍。
由此带来一个后果,也是本仓库的主题:上游修过的一些 bug,vendor 这条线里还在,而这些代码 DSH 每天都在跑。
十二条,每条都复现过
每一行都用同一份探针在 vendor 包和上游 cordis@4.0.0-rc.10 上各跑一次得到,除此之外没有任何其他改动。探针在 probes/。
展开完整文档(README 剩余 1 节)
dsh-cordis-backport
对 DeepSeek Harness 里 vendor 的那条 cordis 线做的一次审计,以及它尚未跟进的上游修复的回移补丁。
背景与讨论:https://github.com/deepseek-ai/deepseek-harness/discussions/7922
这是什么
DeepSeek Harness 用的是 @deepseek-ai/cordis@4.0.4 及其插件包,而不是 npm 上公开的 cordis。这条线不是把 cordis@4.0.0-rc.10 改了个版本号——它是一条独立演进的线,有自己的 config/diff.ts、自己的 volatile 概念、自己对 disabled 里 !!js 的处理。两条线各有取舍。
由此带来一个后果,也是本仓库的主题:上游修过的一些 bug,vendor 这条线里还在,而这些代码 DSH 每天都在跑。
十二条,每条都复现过
每一行都用同一份探针在 vendor 包和上游 cordis@4.0.0-rc.10 上各跑一次得到,除此之外没有任何其他改动。探针在 probes/。
| 上游 | 位置 | 补丁前 → 补丁后 |
| eb5604d (#32) | cordis/src/logger.ts | LoggerLevel 里 INFO 和 WARN 顺序反了,而导出器的默认阈值就是这个 INFO——所以默认级别下 ctx.logger.warn() 被静默丢弃 |
| be7d36e (#37) + 4cfd19a | cordis/src/utils.ts, reflect.ts | 可调用服务的 shadow 丢失,ctx.foo.bar 归属错上下文——服务能访问没声明的服务,声明了反而在嵌套上下文访问不到 |
| 988df36 (#68) | cordis/src/context.ts | 可选属性没加 | undefined,开了 exactOptionalPropertyTypes 的使用者无法赋 undefined——纯类型层,无运行时变化 |
| 10194de (#98) | cordis/src/fiber.ts | FAILED 的 fiber 在依赖刷新时重新进入生命周期——已经抛过错的插件 apply 被反复执行 |
| 752dbee (#40) | cordis/src/fiber.ts | plugin() 返回的是 Object.create(fiber) wrapper;通过 this 写生命周期字段会在 wrapper 上多出一份,遮蔽真 fiber 的那份——配置更新后两者分叉,卸载后 wrapper 仍报 ACTIVE |
| 2ceea23 (#109) | cordis/src/fiber.ts | Fiber.update() 返回 undefined;被丢弃时产生 unhandledRejection: 'boom' → 返回 task,可被 await 捕获,不再泄漏 |
| 1b7d0f2 | loader/src/config/{entry,group,isolate}.ts | await loader.update() 返回时新子条目还没有 fiber → 返回时已协调完毕 |
| 5b195b3 (#44) | cordis/src/events.ts | 监听器二次 next() 会静默把下游整条链再跑一遍 → 抛 next() called multiple times |
| cb77029 (#53) | timer/src/index.ts | 并发 2~3 个 next() 等待者全部超时 → 全部按序结算 |
| 1c1a10e (#51) | cordis/src/events.ts | ctx.on('toString', …) 抛 hooks[method] is not a function → 正常注册 |
| fd96b0a (#36) | cordis/src/logger.ts | 外部持有的 ctx.logger.buffer 持续增长、超出上限 → 稳定在有界范围内 |
对上游没有的那部分代码的验证
verify/ 覆盖这个代码树里唯一没有上游对应物的部分:volatile 配置机制(cosmokit/src/volatile.ts、schemastery 的支持、loader/src/config/diff.ts)。
上游一样都没有——所以和上面的回移补丁不同,这部分从没被写它的人之外的人读过。
简短结论:equalExceptVolatile——那个决定配置变更要不要重挂载的函数——经得起 5000 组定种子配置对加定向边界用例。发现一处缺失的守卫;它在 verify/README.zh.md 里被论证为不可达,而这个论证比缺陷本身更重要,因为两处缺失的守卫互相遮蔽,只修任何一处都会让另一处变成活的。
对核心做模糊测试
fuzz/ 用定种子的随机生命周期驱动 fiber 状态机,检查那些无论如何都该成立的不变量:静默后状态落定、effect 记账精确、ctx.get() 永不返回已死提供者的值、嵌套 fiber 的级联释放。
四个 fuzzer,最后一个连发操作、中间不 settle。
#175 就是这么找到的——*在激活前被 dispose 的 fiber 永远不释放它的 disposables,这是把两个版本对着读多少遍都看不出来的。
它也抓出了我自己两条不变量的错,记在 fuzz/README.md 里。
回移补丁
backport/ 里有三个补丁——cordis@4.0.4、cordis-plugin-loader@1.0.5、cordis-plugin-timer@1.1.6——覆盖上面全部六条。它们能干净应用于未改动的 4.0.4 源码,验证方式与审计相同:补丁前跑一次探针,补丁后再跑一次。
注意每个补丁同时改了 src/.ts 和 lib/index.js。因为这些包的 exports 指向打包产物,只改 src 不会改变实际运行行为;两半都给,你们不重新构建就能直接验证。
动手前值得知道的两件事
① "看起来没变"的那几行,恰恰是关键。
1b7d0f2 里有这样一处,读起来像格式调整:
- ctx.on('internal/update', (config) => {
- this.update(config)
- })
+ ctx.on('internal/update', config => this.update(config))
它不是。 前者返回 undefined,后者隐式返回了 promise——而 waterfall 会把监听器的返回值一路传到 Fiber.update 的调用方。等待链真正断裂的地方就在这里。
我一开始把它当格式调整跳过了,结果只改 entry.ts 和 isolate.ts 时探针仍然失败;补上这一处才通。
②"上游新增的行在本地找不到" ≠ "这个修复缺失"。
两条线都经历过重构。我第一遍用行匹配扫上游提交日志,跑出十二个"基本全缺";逐个核实后,有几个只是同一个功能换了个写法(be7d36e #37)。
但其中一条我判错了: 752dbee(#40)被我标成"已有",因为它涉及的标识符在本地全都能找到。可它改的是赋值的接收者——this.assertActive() 变成 const fiber = this.ctx.fiber; fiber.assertActive()——任何基于名字的检查都看不见。
它最后是靠模糊测试找出来的,就是上面第七条。更正说明写在 backport/README.md。所以这里每条都必须落到可观测的行为差异上才算数——这也是为什么每条都配探针,而不是只贴 diff。
刻意没有包含的:
- 8abd903(#35,caller 追踪)——symbols.caller 在本地完全不存在,这属于加新功能而不是修 bug,不适合夹在回移里。
- c594d1a(#121)和 c2835d8(#123)——本地的 include 是有意分叉:它主动否决 fiber restart 并自行持久化配置,代码里有注释说明原因。要不要跟上游,属于产品决策,不是 bug 回移。
跑探针
探针需要两套模块树:一套解析 @deepseek-ai/(vendor 包),一套解析 cordis / @cordisjs/(上游)。搭建方式、以及让同一份探针跑在两边的模块名替换命令,见 probes/README.md。预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
173787247/dsh-cordis-backport
为 DeepSeek Harness 内置分支缺失的上游 cordis 修复做回溯移植
相关插件 · 其他
模型破甲清洗HunYiSage/dsh-purge
⚔️ DeepSeek Harness 网络安全红队工具dsh-purge
★ 16,993已汉化DeepSeek 客户端
73
女娲蒸馏alchaincyf/nuwa-skill
输入名人名字,提炼其思维模型与决策方式供你调用
★ 37,308已汉化DSH
72
逆向分析桥接Fanqi89/dsh-rea
REA(Reverse Engineer Anything)MCP 桥接,用来把 REA 逆向工具接入 DSH 插件
★ 51已汉化DSH
72
语音女友beiyege-01/dsh-voice-ai-girlfriend
语音 AI 女友Voice AI girlfriend for DeepSeek Harness:Whisper…
★ 888已汉化DSH
71.6
红队越狱测试套件Minglink/dsh-infinite-gen-5
DeepSeek v4.1 flash 逆向工具无限五代 求 Star 收藏 ⭐欢迎大家提交项目的改进
★ 3,759已汉化DSH
71.4
协同办公空间dream-num/univer-workspace
一个让人类与 AI Agent 共同创作、协作和审阅的开源 Office 工作空间。
★ 2,269已汉化DSH
70.8
这是你的仓库?认领条目