前言¶
CI 红了之后,常见动作是打开 GitHub Actions,点进失败的 job,在几千行日志里找真正的报错。时间戳、容器 id、重试序号会把同一类失败拆成看起来完全不同的几段文字,翻完一轮还不一定分得清是测试挂了、依赖拉不下来,还是基础设施超时。
DeepSeek Harness(dsh)的架构是「一切皆插件」:工具、会话、技能都可以以外挂形式接到智能体循环里。社区站点 DeepSeek Harness 插件库 收录了大量这类插件,它是独立目录,与 DeepSeek / 幻方没有官方从属关系。其中 dsh-ci-doctor 做的事情很具体:监视 GitHub Actions 上新出现的失败,把原始构建日志收成对话里的诊断卡,并给错误做归一化签名。
本文依据插件目录页、GitHub 仓库 README(含中文版)、npm 页面和 DeepSeek Harness 官方仓库 交叉核对后整理。
这是什么¶
dsh-ci-doctor 是一款 DeepSeek Harness 插件,由 jkrandom-sudo 维护,许可证为 MIT,主要语言是 TypeScript。社区目录把它归在「会话与消息」分类;截至 2026-08-18,GitHub 星标为 3。npm 上当前版本是 0.1.2(2026-08-14 发布)。
它解决的是「日志还没打开,先把失败说清楚」这件事。插件向智能体注册两个工具:ci_watch 负责盯新失败,ci_diagnose 负责出诊断卡。底层只通过本机已登录的 GitHub CLI(gh)调用 gh api 读取状态,不另配一套 GitHub Token。
核心功能¶
监视新失败:ci_watch¶
ci_watch 会启动一个后台作业,按间隔轮询 GitHub Actions。第一次轮询只建立基线,历史上已经红掉的运行不会当成新告警。可以显式传入 repo,也可以省略,监视当前工作目录所在仓库。
README 给出的调用参数形如:
{ "repo": "owner/name", "branch": "main", "intervalSeconds": 30, "timeoutMinutes": 60 }
目录页和 README 对行为边界写得很清楚:
- 状态行随时可读,作业可以随时取消。
- 瞬时错误指数退避;连续 5 次失败则放弃;认证错误立即失败。
- 发现新失败后,会给出下一步:对对应
repo和runId调用ci_diagnose。
结构化诊断:ci_diagnose¶
ci_diagnose 可以指向某一次运行,也可以默认取最近一次失败运行。返回的是一张 markdown 诊断卡,出现在对话里,而不是让你自己去 Actions 页面翻日志。
参数示例:
{ "repo": "owner/name", "runId": 31782742089 }
诊断卡里会包含这些已核实的内容:
- 归一化错误签名:掩码时间戳、十六进制 id 和数字,同一类失败在不同运行里得到同一个 id。
- 失败类别:test / build / lint / typecheck / dependency / network / permission / timeout / infra。
- 嫌疑文件:从日志里挖路径,并自动剔除 vendor 路径。
- 日志摘录:按预算裁剪,用
… (skipped N lines) …标明跳过了多少行,文档写明不会编造内容。
仓库 README 里的示例卡如下(示例仓库是 cli/cli,来自项目文档,不是笔者实测):
## CI diagnosis: cli/cli run #31782742089
**Conclusion:** failure · [run](https://github.com/cli/cli/actions/runs/31782742089)
### Job: Issue Triage (skills-driven)
**Failed steps:** triage
**Signatures:**
- `81a0edf32878` (timeout, first time seen) — server:http_server Session timeout configured…
**Suspect files:** `script/triage.ts`
失败签名账本¶
每个诊断过的签名会被记住:见过几次、首次和最近出现时间、最近一次所在仓库和运行链接。复发时报告里会写成 seen 3×,而不是当成全新问题。
持久化依赖宿主是否提供 storage domain:有的话写入 DSH 存储目录下的 ci_doctor 单元;没有则只放在内存里。配置项 ledgerEnabled 默认开启。
只读契约¶
两个工具按文档约定只读 GitHub 状态,不会 push、合并、取消、重跑,也不会改仓库内容。每条结果带 repositoryWrites: false。包里还导出可选伴随插件 dsh-ci-doctor/invariant:在提供 invariants 服务的宿主上,如果这个标记丢了会直接报错。仓库的 cordis.patch.yml 注明,默认 web/base profile 没有该服务,所以 invariant 没有写进默认补丁,以免卡住启动。
安装与启用¶
社区目录页给出的安装命令如下,在 DeepSeek Harness 终端里运行:
dsh plugin add github:jkrandom-sudo/dsh-ci-doctor
需要可复现安装时,按目录页说明固定 commit 哈希(把 commit 换成实际哈希):
dsh plugin add github:jkrandom-sudo/dsh-ci-doctor#commit
仓库 README 另外写了一种按 npm 包名、指定 web profile 的装法:
dsh plugin --profile web add dsh-ci-doctor
两种写法都能在公开资料里找到。目录页命令以页面原文为准;若你平时用 web profile 装 npm 插件,可以对照 README。
前置条件:本机已安装并登录 GitHub CLI:
gh auth login
插件复用这次登录会话,README 写明没有其他必填配置。
可调选项(README 与源码 src/config.ts 一致):
| 选项 | 默认值 | 含义 |
|---|---|---|
pollIntervalSeconds |
30 | 监视轮询间隔(秒,最小 5) |
watchTimeoutMinutes |
60 | 单次监视存活时长(分钟,最小 1) |
maxLogLines |
200 | 每个失败 job 的日志摘录行数(最小 20) |
ghBin |
gh |
GitHub CLI 可执行文件 |
ledgerEnabled |
true | 是否把签名写入账本 |
典型用法¶
装好后用自然语言即可,README 给出的对应关系是:
- 「帮我盯着这个仓库的 CI,挂了告诉我」→ 启动
ci_watch后台作业。 - 「nightly 构建为什么挂了?」→ 对最近一次失败运行跑
ci_diagnose。 - 「诊断一下 cli/cli 的 31782742089 这次运行」→ 针对指定 run 做定向诊断。
监视发现新失败后,作业会收尾成调用 ci_diagnose 的下一步,智能体可以接着把诊断卡贴进对话。
适用场景与注意事项¶
比较适合这些情况:
- 日常在 dsh 里写代码,希望 CI 红灯先变成结构化摘要,而不是先打开 Actions。
- 同一类失败反复出现,需要靠归一化签名和账本判断是不是老问题。
- 只想读日志、定位类别和嫌疑文件,不希望插件去改远程仓库。
使用前要注意:
- 权限与安全。 目录页写明:插件以当前 dsh 进程的权限运行,安装时可能执行代码。安装前应检查 GitHub 源码仓库和许可证(本插件为 MIT)。
- 只覆盖 GitHub Actions。 文档描述的是通过
gh api读 GitHub 状态,不要把它理解成通用的 Jenkins / GitLab CI 诊断器。 - 它不负责修代码。 工具是只读的,不会重跑 workflow,也不会自动提交修复;后续改代码仍由智能体或开发者完成。
- 依赖本机
gh登录。 认证失败会立即退出监视,没有登录就谈不上轮询。 - 账本不一定落盘。 没有 storage domain 时只在内存里,进程重启后复发统计会丢。
- 社区插件,不是官方应用商店货架。 DeepSeek Harness 官方仓库强调一切皆插件;本插件由社区维护者发布,目录站也是独立站点。
小结¶
dsh-ci-doctor 把「盯 CI」和「读日志」收成两个工具:ci_watch 只报告基线之后的新失败,ci_diagnose 把原始日志收成带签名、类别、嫌疑文件和诚实摘录的诊断卡。对经常在 GitHub Actions 上翻红灯的 dsh 用户,它省掉的是打开日志之前那一轮检索,而不是替你改仓库。
目录页:https://deepseek-harness-plugin.com/zh-CN/plugins/dsh-ci-doctor/
GitHub:https://github.com/jkrandom-sudo/dsh-ci-doctor
npm:https://www.npmjs.com/package/dsh-ci-doctor