已针对 DSH 0.1.5-rc.1 验证会话格式 v3;dsh-session 定位覆盖 npx / 全局 /…
31.9/100
综合分
3
GitHub 星标
341
npm 周下载
—/5
用户评分
数据截至 2026/10/22 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add @moonquake2004/dsh-doctornpm 源 · @moonquake2004/dsh-doctor 的发布者账号已校验与本仓库一致
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:已验证
是什么
dsh 原生插件 · other
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 15 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查✓ 自动检查通过安装清单取自 plugin/package.json
展开查看检查明细 ↓
以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。
✓npm 包@moonquake2004/dsh-doctor @ 0.8.5
✓Node 引擎未声明 engines.node
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明
验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/11 22:10:33
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 223 处,展示前 28 条)
- 执行外部命令来自配置/变量lib/index.js:41
const child = spawn(process.execPath, [SCRIPT, ...args], { - 发起网络请求client/client.js:84
const res = await fetch('/dsh-doctor/run', { cache: 'no-store' }) - 读取本地文件dsh-doctor.mjs:101
if (!p || !existsSync(join(p, 'dsh'))) continue; - 读取本地文件dsh-doctor.mjs:117
if (existsSync(profiles)) { - 读取本地文件dsh-doctor.mjs:118
for (const name of readdirSync(profiles)) { - 读取本地文件dsh-doctor.mjs:122
if (existsSync(store)) { - 读取本地文件dsh-doctor.mjs:123
for (const d of readdirSync(store)) { - 读取本地文件dsh-doctor.mjs:129
return [...new Set(cands.filter((c) => existsSync(c)))]; - 执行外部命令来自配置/变量dsh-doctor.mjs:436
const find = (cmd) => { for (const w of process.platform === 'win32' ? ['where'] : ['which']) { const r = spawnSync(w, [cmd]); if (r.status === 0) { c - 执行外部命令固定命令dsh-doctor.mjs:446
const nv = spawnSync('node', ['-e', 'console.log(process.version)']); - 执行外部命令来自配置/变量dsh-doctor.mjs:479
const found = (() => { const r = spawnSync(whichCmd, ['dsh'], { encoding: 'utf8' }); return r.status === 0 ? String(r.stdout).split(/ ? /)[0].trim() - 执行外部命令来自配置/变量dsh-doctor.mjs:483
const r = spawnSync(process.platform === 'win32' ? 'dsh.cmd' : 'dsh', ['--version'], { encoding: 'utf8', timeout: 15000, shell: process.platform === ' - 执行外部命令来自配置/变量dsh-doctor.mjs:519
const r = spawnSync(process.execPath, ['-e', 'require("node:zlib").zstdDecompressSync(require("node:zlib").zstdCompressSync(Buffer.from("x")))'], { en - 执行外部命令固定命令dsh-doctor.mjs:633
const r = execFileSync('netstat', ['-ano'], { encoding: 'utf8', maxBuffer: 8 * 1024 * 1024 }); - 写入本地文件dsh-doctor.mjs:2349
try { mkdirSync(dirname(cachePath), { recursive: true }); writeFileSync(cachePath, JSON.stringify(data, null, 2)); } catch { } - 写入本地文件dsh-doctor.mjs:2349
try { mkdirSync(dirname(cachePath), { recursive: true }); writeFileSync(cachePath, JSON.stringify(data, null, 2)); } catch { } - 写入本地文件dsh-doctor.mjs:2598
try { mkdirSync(dirname(cachePath), { recursive: true }); writeFileSync(cachePath, JSON.stringify({ latest, checkedAt: new Date().toISOString() })); } - 写入本地文件dsh-doctor.mjs:2598
try { mkdirSync(dirname(cachePath), { recursive: true }); writeFileSync(cachePath, JSON.stringify({ latest, checkedAt: new Date().toISOString() })); } - 写入本地文件dsh-doctor.mjs:3039
try { writeFileSync(join(profileDir, SNAPSHOT_FILE), JSON.stringify(snap, null, 2) + '\n'); } catch { } - 写入本地文件dsh-doctor.mjs:3054
writeFileSync(`${manifestPath}.dsh-doctor.pre-add.${Date.now()}`, before); - 读取本地文件observer.mjs:273
const st = statSync(p); - 读取本地文件observer.mjs:276
for (const f of readdirSync(p)) { - 读取本地文件observer.mjs:278
try { out.push(JSON.parse(readFileSync(join(p, f), 'utf8'))); } catch { } - 读取本地文件observer.mjs:282
return JSON.parse(readFileSync(p, 'utf8')); - 执行外部命令来自配置/变量observer.mjs:287
const r = spawnSync(cmd, { input: prompt, encoding: 'utf8', shell: true, timeout: 30_000, maxBuffer: 4 * 1024 * 1024 }); - 写入本地文件observer.mjs:311
mkdirSync(dirname(filePath), { recursive: true }); - 写入本地文件observer.mjs:312
writeFileSync(filePath, JSON.stringify(catalog, null, 2) + '\n', 'utf8'); - 读取本地文件observer.mjs:318
const d = JSON.parse(readFileSync(filePath, 'utf8'));
扫描于 2026/11/2(1 天前) · 范围 入口闭包 + 全包扫描 · 来源 npm 发布包
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
功能亮点
- 扫描插件树
- 发现配置故障
README
由 DeepSeek 最新模型翻译生成dsh-doctor
已针对 DSH 0.1.5-rc.1 验证(会话格式 v3;dsh-session 定位覆盖 npx / 全局 / profile 三种布局;v0 旧事件按已装 dsh-session-format- 迁移链读取)。
DeepSeek Harness 的离线诊断工具——在启动前或安装插件前跑一次,它会告诉你社区反复报告的哪几类故障会在你机器上咬人。
零 npm 依赖。单文件。任何有 node 的环境都能跑(zstd 只在扫 .zstd 会话日志时需要,E1 会检查它)。
为什么
dsh 的插件树"装出来就是脆的":一个悬空引用、一个断掉的 file: 链接、一个重复的 entry id、一段损坏的会话日志,都能让 profile 在启动时直接挂掉或拖垮整个 web 服务器——而 --dump-config 从不挂载 loader,所以在坏配置上也"一切正常"。这类故障被汇总在 dsh discussion #1496(Advisory:插件安装路径需要护栏)。dsh-doctor 就是这个护栏——26 项内置检查(env 7 / profile 11 / session 8)映射到 18 个社区报告,每一项都用合成负样例验证过;外加一个自更新的远程检查目录(声明式规则,v0.2.0 起)。
展开完整文档(README 剩余 1 节)
dsh-doctor
已针对 DSH 0.1.5-rc.1 验证(会话格式 v3;dsh-session 定位覆盖 npx / 全局 / profile 三种布局;v0 旧事件按已装 dsh-session-format- 迁移链读取)。
DeepSeek Harness 的离线诊断工具——在启动前或安装插件前跑一次,它会告诉你社区反复报告的哪几类故障会在你机器上咬人。
零 npm 依赖。单文件。任何有 node 的环境都能跑(zstd 只在扫 .zstd 会话日志时需要,E1 会检查它)。
为什么
dsh 的插件树"装出来就是脆的":一个悬空引用、一个断掉的 file: 链接、一个重复的 entry id、一段损坏的会话日志,都能让 profile 在启动时直接挂掉或拖垮整个 web 服务器——而 --dump-config 从不挂载 loader,所以在坏配置上也"一切正常"。这类故障被汇总在 dsh discussion #1496(Advisory:插件安装路径需要护栏)。dsh-doctor 就是这个护栏——26 项内置检查(env 7 / profile 11 / session 8)映射到 18 个社区报告,每一项都用合成负样例验证过;外加一个自更新的远程检查目录(声明式规则,v0.2.0 起)。
用法
node dsh-doctor.mjs # 全部检查(env + profile + session)
node dsh-doctor.mjs --profile web # 仅 profile 检查
node dsh-doctor.mjs --session <path> # 仅会话检查(默认自动找最新会话)
node dsh-doctor.mjs --env # 仅环境检查
node dsh-doctor.mjs --json # 机器可读输出
node dsh-doctor.mjs --no-catalog # 不拉远程目录(只用内置副本)
退出码:0 = 全部通过 · 1 = 发现问题(内置检查 + 目录中 severity: error 的项)· warn 级目录失败不改退出码。
检查项(28 内置 + 5 目录)
env
| ID | 检查 | 对应讨论 |
| E1 | node/pnpm/zstd 在 PATH | #1270 |
| E2 | .env 是文件而非目录 | #71 |
| E3 | node 版本 / --expose-internals 可及性 | #113, #1313 |
| E4 | node-pty 原生二进制在位(prebuilds/<platform>-<arch>/pty.node) | #1219 |
| E5 | 存储 JSON 文件合法(严格 UTF-8 + 可解析) | #1357 |
| E6 | 锚点 tripwire:S6/S7/S10 依赖的契约仍在当前版本存放它的位置(npx / 全局 / profile 三布局;dsh-session 或 dsh-session-format- 迁移链) | anti-rot idea |
| E10 | 启动前 Web 端口 3080 可用性(dsh web 自身占用=正常;其他进程=FAIL;DSH_DOCTOR_PORT 可覆盖) | #1719 |
profile
| ID | 检查 | 对应讨论 |
| P2 | bundle 层与用户 patch 的 insert id 冲突(启动必崩) | #1404 |
| P3 | 用户 patch 的 insert name: 能从 profile 锚点解析 | #1197, #880 |
| P4 | file: 依赖完整 | #1197 |
| P5 | 顶层无 @deepseek-ai/ 重复(双模块实例) | #1486, #1697 |
| P7 | cordis.patch.yml 结构 lint(~ insert: null 字面量、tab 缩进、缺冒号、顶层映射+序列混排 → UI 打不开) | #1724 |
| P12 | profile 内 bundle 版本 vs 运行 CLI(发词汇名 installed_bundle,#1719 v1.1:未声明=skip / manifest 撒谎或分歧=warn / 一致=pass;web「诊断」面板 / /dsh-doctor/run API 跑的是 bundle) | #1719 |
| P13 | client 半 provide 服务名抢注核心客户端服务(chatFileMentions 等 @deepseek-ai/dsh-client-,warn)或跨 bundle 同名(浏览器端 service already registered → UI 白屏、服务端日志无感知) | #2752 |
| P14 | 声明 bin 可执行性(目标文件在位 + 文本 bin 必须带 shebang;仅可执行位不识别解释器 → 直接执行 ENOEXEC,#1846) | #1846 |
| P16 | 插件导入了已装包未提供的命名导出(warn;单条坏 entry 即 boot 硬失败) | #5864 |
| P17 | client 端 require() 的模块宿主模块表无法服务(平台种子 ∪ 已装图行 ∪ 声明的 external)——warn 级;抓浏览器 Failed to load plugins 白屏 | #5719 |
session
| ID | 检查 | 对应讨论 |
| S1 | 孤儿 tool_call(无对应 tool result) | #1363, #1544 |
| S2 | 未闭合 turn(会话卡"运行中") | #466, #1265 |
| S6 | seq == index 连续性(官方语义,chunk 行按 expandRow 展开) | #1333, #1452, #1469 |
| S7 | end-seed 后重放(重放已提交尾部) | #1497 |
| S8 | 未知事件类型且无 ignorable(整包拒绝)——可读集 = 当前表 ∪ 已装 dsh-session-format- 迁移包认的旧类型 | #1538 |
| S9 | zstd 容器帧数(单帧日志 → session.list 整体 500) | #1043 |
| S10 | sourceEventSeqs 引用非更早事件 | #1469 |
| S11 | 全会话扫描:损坏 → 隔离建议;超大 / 工作区估算物化堆(max(事件×600B, 字节×6),默认 1GiB,DSH_DOCTOR_HEAP_MB)→ 冷启动卡顿风险 | #1550 |
| S12 | 迁移拒载预检:会被已装 dsh-session-format- 迁移链拒绝的会话日志(v0 subagent/descriptor 版本门;v2→v3 source.kind 白名单)——列表里看着在、点开却打不开 | #6045, #6328, #6311 |
备注
- S 类检查复刻了 harness 自身的校验(如 SessionLogScanner 的 seq == events.length + expandRow chunk 展开),所以离线结论与 boot/resume 实际行为一致。
- 尊重 $DSH_HOME(默认 ~/.dsh),可以用临时 home 干跑,不碰真实数据。
- 当前活跃 turn 的尾部 in-flight 工具调用按警告而非错误处理,扫活会话不会误报。
- 同生态位兄弟实现:boyin111-1/dsh-doctor —— 两工具用同一批坏 fixture 交叉验证过。
相关社区工具
dsh-doctor/v1 词汇表 r5 兼容,v1.1 installed_bundle 待认领 —— 起草 @ciceroyang(ciceroyang/dsh-doctor),审阅 @sjh9714(dsh-win32)与 @moonquake2004(#1719)。我们的 node/pnpm 检查按 r5 语义输出词汇名(pass/warn/fail/skip;summary.skip 常驻);P12 直接发 v1.1 词汇名 installed_bundle(四态 skip/warn/pass/warn,r6 表待发)。
- zoahdev/dsh-plugin-doctor —— 发布前插件 bundle 健康检查(manifest/patch/entry/files/build/pack+全新 profile 安装)+ 宿主遮蔽 profile-shadow 哨兵(作者/CI 侧)。与本工具的用户侧 profile/session/env 诊断互补;它的 profile-shadow 与我们的 P5 从两个方向标记同一个宿主遮蔽前置条件。
- boyin111-1/dsh-doctor —— 同生态位离线诊断兄弟实现,用同一批坏 fixture 交叉验证。
Symptom → check quick-start (dsh-diagnose alignment)
If you're coming from a symptom (rather than from the machine), these are the checks to run first. Coverage is honest: ✅ = direct offline coverage, ⚠️ = partial (we see the log/profile effects, not the runtime internals), ❌ = gap (runtime-only, no offline probe today).
| Symptom family | dsh-doctor checks | What they catch |
| session log corruption / can't resume | S1, S2, S6, S7, S8, S9, S10 | orphan tool calls, unclosed turns, seq gaps, end-seed replay, unknown event types, zstd single-frame, sourceEventSeqs drift |
| oversized / cold-start stall | S11 | estimated materialization heap, corrupt-session quarantine |
| boot failure (UI won't open) | P1–P10, E10 | dangling bundles, id collisions, patch syntax, host shadowing, adapter conflicts, client-service injects, port 3080 |
| tool registry gaps (tools missing) | P1, P2, P8, P10, P9 | unresolved/conflicting/duplicated tool registrations, client-only service injects |
| compaction / history unavailable | S10, S6, S8 | sourceEventSeqs not remapped after compaction |
| agent-loop lifecycle (session stuck "running") | S2, S1, S6 | unclosed turns, orphan tool calls, broken seq |
| llm retry storms | S6, S11, S2 | retry traffic effects on log integrity/size |
| token metering off | S11, S1, S2 | metering derives from the event stream |
| workflow script failures | P7, S6, S8, S1 | patch syntax (boot), workflow event integrity |
| approval policy pending | S2, S1 | open turns / orphan calls from pending or rejected approvals |
| credentials resolution | E2, E5, P4 | .env shape, storage JSON, file: links |
| web internals | E10, P10, E5 | port, client half, workspace storage |
| subagent depth | S11, S8 | session size, subagent event types |
| sandbox denials | E4 | node-pty binary (infra only) — ❌ runtime policy not offline-checkable |
| approval internals | S2 | ⚠️ runtime policy; only the turn-level effect |
| credentials internals | E2, E5 | ⚠️ file-level only |
The dsh-doctor/v1 envelope (--json --envelope) is the machine-readable form of any of these runs, so a symptom tool can consume the verdict directly. --remediation(配合 --json --envelope)输出 v1.1 可选 remediation 数组——失败项的有序 [检查名] 修复 行;不带该 flag 时字段不存在,r5 消费者字节稳定。
自更新检查(v0.2.1,层 B)
工具也会盯着自己的 npm 版本:每次运行对比已装版本与 dist-tags.latest(与目录同样的 6h TTL 缓存 + 离线回退)。有新版时打印提示、JSON 里报 update: { current, latest, available }——未经你要求绝不改动你的安装。
- --update —— 立即执行更新:在宿主 profile 里跑 pnpm install(可用 DSH_DOCTOR_UPDATE_CMD 覆盖),然后提示重启 dsh web。
- DSH_DOCTOR_AUTO_UPDATE=1 —— 有新版时自动更新。
- 诚实边界:cordis 启动时加载插件,新引擎要重启才生效——层 B 是"换文件 + 提醒重启",不做热替换。
- --no-catalog 同时禁用更新检查(纯离线模式)。
远程检查目录(v0.2.0,层 A)
内置 26 项检查编译在工具里。目录是第二层、自更新的:本仓库的 plugin/checks.json 放声明式规则(规则是数据,不是代码),所有已装实例自动获取新规则——无需重装。
- 工作机制:每次运行尝试从 GitHub 拉 plugin/checks.json(3s 超时)→ 成功后缓存到 $DSH_HOME/.cache/dsh-doctor/checks.json(TTL 6h)→ 失败回退 last-known-good 缓存 → 再回退内置副本。新检查因此在上游提交后 ≤6h 内自动到达。
- 安全性:规则是只读探测原语,由内置引擎执行(command-exists、path-*、json-valid、text-contains / text-not-contains、file-size-above、glob-count)。远程内容永远无法执行代码——只能新增模式检查。
- 严重级别:error(默认,改退出码)或 warn(只报告,不影响退出码)。--no-catalog 关闭远程拉取。
- 加一条检查(这就是重点——无需发版):往 plugin/checks.json 追加一条并提交即可。目前已随目录发布的检查:
| ID | 探测 | 检查 | 对应讨论 |
| E7 | command-exists | dsh 在 PATH | #1270 家族 |
| E8 | text-contains(warn) | profile .npmrc 含 ignore-workspace-root-check=true | dsh-market #20 |
| E9 | json-valid | config/workspace.json 可解析 | #1357 家族 |
| P6 | text-not-contains | patch insert name: 含空格(Windows spawn lint) | #1420 |
目录检查的结果在 JSON 输出中标 src: "catalog",CLI 输出标 [目录]。
LLM 观察者(v0.3.0,层 C)
第三层把"现场信号 → 目录条目"的回路半自动化:从诊断运行产出候选检查提案,人做最后把关(认证门禁不变)。设计与细节见 docs/layer-c-observer.md。
- dsh-doctor --observe run.json —— 聚类诊断运行的 fail/warn 信号(--json / --envelope 输出,或含 JSON 的目录),按目录 schema 起草候选检查(确定性,默认 severity: warn)。
- --observe-llm "<cmd>"(或 DSH_DOCTOR_LLM_CMD)—— 用 LLM 富化草稿:cmd 从 stdin 收 prompt,stdout 回 JSON。回复被封闭探测词表约束,任何解析/词表违规静默回退草稿。
- --observe-apply proposals.json —— 把校验通过的提案并入本地覆盖层 plugin/checks.local.json(幂等)。覆盖层参与本地诊断直到你认证该检查,但永不随包分发——认证后的检查应进 plugin/checks.json。
安全不变量:封闭探测词表(LLM 输出永远是数据、不是代码)、提案默认 warn、不自动上目录、不依赖任何外部服务(不带 --observe-llm 即确定性模式)。
也可作为 dsh 插件安装
工具以标准 dsh bundle 形态发布(plugin/),可以在 web UI 里跑同样的检查(28 内置 + 5 目录规则):
装进 profile(checkout 或已发布路径均可)
dsh plugin --profile web add file:/path/to/dsh-doctor/plugin
装完你会得到:
- 设置 → 诊断面板:一键跑全部检查,按 env / profile / session 分组渲染结果,带逐项修复建议与隔离建议(只展示建议,绝不自动执行);
- HTTP API:GET /dsh-doctor/run 返回同样的 JSON(可选 ?profile= / ?session= 收窄范围)。
架构:插件的服务端路由 shell 出 plugin/dsh-doctor.mjs --json——与 CLI 同一份真相源(检查按设计是离线/文件系统导向的,不需要 harness 内部接口)。仓库根目录的 dsh-doctor.mjs 是兼容 node dsh-doctor.mjs 的薄封装。
License
MIT预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
moonquake2004/dsh-doctor
已针对 DSH 0.1.5-rc.1 验证会话格式 v3;dsh-session 定位覆盖 npx / 全局 /…
相关插件 · 其他
模型破甲清洗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,266已汉化DSH
70.7
这是你的仓库?认领条目