mcpField
C
codeprobe

codeprobe

github.com/machineroom-dev其他5126 次安装6 天前更新
代码仓库

关于 codeprobe

codeprobe 是面向开发者的只读代码审查技能,可执行专项审计或相对基准分支检查变更。它将分析分派给领域子技能,并生成分级问题及可复制的修复提示词。

主要功能

  1. 01完整审计与评分仪表板
  2. 02按类别执行专项审计
  3. 03审查相对基准分支的变更
  4. 04检测技术栈与配置
  5. 05生成分级问题和修复提示词
  6. 06输出 Markdown 报告

适用场景

  1. 01跨质量类别检查代码库
  2. 02拉取请求前检查变更文件
  3. 03审计安全性或性能
  4. 04快速获取优先处理的问题

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/machineroom-dev/codeprobe --skill codeprobe

安装后在 Claude Code 中输入/codeprobe确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

shared-preamble.md
verification-rubric.md
references/
api-design.md
javascript-typescript.md
php-laravel.md
python.md
react-nextjs.md
sql-database.md
scripts/
complexity_scorer.py
dependency_mapper.py
file_stats.py
render_dashboard.py
templates/
full-audit-report.md
pr-review-comment.md
quick-review-summary.md

详细介绍

代码审查编排器

只读约束

对于正在审查的代码库,此技能严格只读。 切勿修改、写入、编辑或删除用户源代码树中的任何文件。切勿运行会对被审查项目产生副作用的命令(不得运行 npm install、pip install、不得进行 git 提交、不得修改数据库)。如果需要修复,请生成一段可复制粘贴的修复提示词,供用户单独运行。

一个有文档记录的例外——报告产物: /codeprobe audit、/codeprobe diff 或单类别命令(/codeprobe security、solid……)完成后,编排器会在当前工作目录的 ./codeprobe-reports/<project>-<cmd>-<timestamp>.md 中写入一份 Markdown 报告(例如 ./codeprobe-reports/growth-engine-audit-2026-04-23-221047.md);/codeprobe quick 不会保存任何内容。这是此技能自身的输出,不属于修改被审查代码。其他位置一律不得写入。

Git 也必须只读: /codeprobe diff 可以运行只读 git 命令(git diff、git merge-base、git ls-files、git rev-parse、git status)。切勿运行会修改仓库或工作树的 git 命令——不得提交、检出、暂存、重置、获取或拉取。

无论用户提出什么要求,违反此约束都绝不可接受。


1. 命令路由

解析用户输入,提取子命令和目标路径。输入格式为:

/codeprobe [subcommand] [path]
路由表
命令行为调用的子技能
/codeprobe audit <path>完整审计——先展示可视化健康仪表板(类别评分、代码库统计数据、热点),随后列出详细的 P0-P3 级问题,并附上修复提示词所有可用子技能 + file_stats.py
/codeprobe solid <path>仅分析 SOLID 原则codeprobe-solid
/codeprobe security <path>仅进行安全审计codeprobe-security
/codeprobe smells <path>仅检测代码异味codeprobe-code-smells
/codeprobe architecture <path>仅进行架构分析codeprobe-architecture
/codeprobe patterns <path>仅分析设计模式codeprobe-patterns
/codeprobe performance <path>仅进行性能审计codeprobe-performance
/codeprobe errors <path>仅进行错误处理审计codeprobe-error-handling
/codeprobe tests <path>仅进行测试质量审计codeprobe-testing
/codeprobe framework <path>仅分析框架最佳实践codeprobe-framework
/codeprobe quick <path>列出最重要的 5 个问题——以扫描模式运行所有子技能,然后为这 5 个问题生成完整详情所有可用子技能
/codeprobe diff [base]以 PR 审查的方式,对比基准分支与已更改文件(默认值:main,回退至 master)——参见第 4A 节所有 9 个子技能,仅审查已更改文件
默认行为
  • 未提供子命令:询问用户想要执行什么,并列出可用命令。
  • 未提供路径:使用当前工作目录。
  • 未知子命令:说明这不是 codeprobe 命令,并列出上面的路由表。

2. 自动检测技术栈

在路由到任何子技能之前,检测目标路径下的技术栈。这有助于确定要加载哪些参考指南并传递给子技能。

检测流程
  1. 使用 Glob 扫描目标路径中的文件扩展名(递归扫描,深度适中)。
  2. 应用以下检测规则——可同时匹配多个技术栈:
信号检测到的技术栈要加载的参考文件
.php 文件PHP / Laravelreferences/php-laravel.md
.js、.ts、.jsx、.tsx 文件JavaScript / TypeScriptreferences/javascript-typescript.md
.py 文件Pythonreferences/python.md
.jsx、.tsx 文件 + 存在 next.config.*React / Next.jsreferences/react-nextjs.md
.sql 文件或 migrations/ 目录SQL / 数据库references/sql-database.md
routes/ 目录或 API 路由模式API 设计references/api-design.md
  1. 对每个检测到的技术栈,确认对应的参考文件存在。如果不存在,则静默跳过。
  2. 收集所有适用参考文件的绝对路径,以传递给子技能。不要将参考文件内容读入协调器自身的上下文——子代理会直接读取与其领域相关的参考文件,从而使每个上下文窗口保持精简。
参考文件解析

参考文件位于此技能自身目录中的 references/ 目录。请根据此 SKILL.md 文件的位置解析路径,而非用户的项目,并在传递给子代理(其工作目录为用户项目)之前将其转换为绝对路径:

{this-skill's-directory}/references/{reference-file}.md

如果参考文件不存在,则继续处理。切勿因缺少参考文件而中止审查。


3. 配置加载

检查项目根目录(目标路径或其祖先目录)中是否存在 .codeprobe-config.json 文件。

配置架构
{
  "severity_overrides": {
    "long_method_loc": 50,
    "large_class_loc": 500,
    "deep_nesting_max": 4,
    "max_constructor_deps": 6
  },
  "skip_categories": ["codeprobe-testing"],
  "skip_rules": ["SPEC-GEN-001"],
  "framework": "laravel",
  "extra_references": [],
  "report_format": "markdown",
  "verify": true
}
配置行为
  • 如果不存在:应用所有默认值。不报错。
  • severity_overrides:传递给子技能,以便它们相应调整阈值。
  • skip_categories:不要调用列出的子技能,即使处于 audit 或 quick 模式也是如此。
  • skip_rules:传递给子技能,使其抑制 ID 匹配的发现项。
  • framework:如果已设置,则跳过该框架的自动检测,并强制加载对应的参考文件。其他自动检测仍照常进行。
  • extra_references:要加载并传递给子技能的其他参考文件路径。
  • report_format:输出格式偏好(默认为:markdown)。
  • verify:默认为 true。当设为 false 时,完全跳过验证环节(第 4B 节),并省略仪表板中的“验证未通过”行和报告章节。

4. 子技能执行

上下文准备(在任何子技能运行前执行一次)

在调用任何子技能之前,编排器会准备共享上下文。编排器不会自行读取源文件内容——每个子 Agent 都会读取其所属领域所需的文件。这样可以让编排器保持精简的上下文,并避免在每个 Agent 的提示词中重复整个代码库。

  1. 读取共享前言:从 shared-preamble.md(位于此技能目录中)读取。该文件包含所有子技能共用的输出约定、执行模式和约束。

  2. 为目标路径构建文件清单:

    • 首选:运行 python3 scripts/file_stats.py <target_path> 一次(相对于此 SKILL.md 解析脚本路径),并根据其逐文件输出生成清单。
    • 后备方案(Python 3 不可用时):使用 Glob 查找源文件(.ts、.tsx、.js、.jsx、.py、.php、.vue、.sql、.css、.scss)和配置文件,例如 next.config.*、package.json、composer.json、requirements.txt、.env.example,再使用 wc -l 获取行数。
    • **排除项(两种路径均适用):**跳过 node_modules、vendor、.git、__pycache__、.next、dist、build、.venv、venv、env 和 codeprobe-reports/——与捆绑脚本中的 SKIP_DIRS 保持一致。
    • 清单应逐行列出 {filepath} ({LOC} lines),并附上检测到的技术栈。
  3. 收集参考文件路径(已在第 2 节的技术栈检测期间解析)。仅提供路径,不提供内容。

  4. 解析每个子技能的 SKILL.md 路径。 子技能位于同级目录中:相对于此 SKILL.md 的位置解析 ../codeprobe-{name}/SKILL.md,并记录其绝对路径。不要自行读取子技能文件,也不要内联其内容:每个子 Agent 都会读取自己的文件(调用协议步骤 2)。每种模式(包括 scan/quick)下,都必须在 === SUB-SKILL: … === 标记块中传递该路径——切勿依赖子 Agent 根据名称解析子技能,因为该 Agent 可能没有注册此技能。

Bash 使用规范。 每次 Bash 调用只能执行一个命令:一个 python3 …、一个 mkdir -p …、一个 wc -l … 或一个 date …。绝不使用 &&、; 或管道将命令串联起来执行循环;绝不设置 shell 变量;绝不使用 Bash 读取文件(cat、head、for … cat)——请使用 Read 工具。受限环境每次只允许一种 Bash 命令模式,因此整条串联命令会被一并拒绝;拒绝操作绝不能改变子 Agent 收到的内容。

调用协议

对于要运行的每项子技能,启动一个 Agent,并在提示词中包含:

  1. 共享前言路径——shared-preamble.md 的绝对路径,并附上:“先使用 Read 工具读取此文件。它规定了你的输出契约、执行模式和只读约束。”同时将前言中的只读约束句子原样复制到提示词中,确保即使在读取文件之前,该约束也同样有效。
  2. 子技能标记块,注明子技能名称及其 SKILL.md 的绝对路径:
    === SUB-SKILL: codeprobe-{name} ===
    Read the file at {absolute path of ../codeprobe-{name}/SKILL.md} with the Read tool before doing anything else. It is the sub-skill you are executing: its detection tables are the product, and every rule in it applies. Ignore its Standalone Mode section — the orchestrator has already provided everything it would load. If the Read fails, stop and reply with exactly `SUB-SKILL UNREADABLE: {path}` and nothing else.
    === END SUB-SKILL ===
    
    切勿在提示词中用概述、缩写或转述来代替路径——转述会悄然遗漏规则。如果 Agent 回复 SUB-SKILL UNREADABLE,请自行读取该文件,然后只重新启动该 Agent 一次,并在相同标记之间原样内联文件内容(去除 frontmatter);只有在这种情况下才能内联内容。
  3. 模式——full 或 scan。
  4. 文件清单——路径、行数和检测到的技术栈。指示 Agent:“使用 Read/Grep/Glob 检查与你的检测表相关的文件。不要盲目读取每个文件——应针对你的领域选择目标文件。”
  5. 参考文件路径——适用参考指南的绝对路径,并附上:“在最终确定严重性和修复提示词之前,先阅读与发现结果相关的参考资料。”
  6. 配置覆盖项——.codeprobe-config.json 中的严重性覆盖项和跳过规则。
  7. 目标路径——让子技能知道项目根目录,以便进行针对性查找。
  8. 适用时提供子技能专属的预计算脚本输出:
    • 对于 codeprobe-architecture:启动 Agent 之前,通过 Bash 运行 python3 scripts/dependency_mapper.py <target_path> 并捕获 JSON 输出。将其作为额外的上下文块传入,标记为 === DEPENDENCY_GRAPH === ... === END DEPENDENCY_GRAPH ===。子技能将其作为循环依赖检测的事实依据。如果 Python 3 不可用或脚本运行失败,则省略此上下文块——子技能会改用基于 LLM 的导入关系追踪。
    • 对于 codeprobe-performance:如果 scripts/complexity_scorer.py 的输出可用(可选),则将其作为 === COMPLEXITY_SCORES === ... === END COMPLEXITY_SCORES === 传入。
  9. Bash 使用规范,一行:“每次 Bash 调用只能包含一条命令——绝不使用 &&、;、循环或 shell 变量;使用 Read 读取文件。”

子技能自己的 SKILL.md 只包含其领域专属的检测逻辑。所有其他共享上下文(输出格式、模式、文件清单、参考路径、预计算脚本数据)均由编排器的提示词提供;子 Agent 会自行读取源文件。

收集发现结果,格式须符合标准输出契约(第 5 节)。

执行模式
模式使用场景行为
full/codeprobe audit、/codeprobe diff、/codeprobe solid 等执行完整分析,返回所有发现结果
scan/codeprobe quick执行相同的完整分析,但仅返回各类别的严重性计数 + 前 5 个候选发现结果,并包含所有输出契约字段(分析成本完全相同——扫描模式只精简输出,让编排器能够跨类别对候选结果排序,而无需进行第二轮分析)
执行顺序
  • **并行执行:**各子技能 Agent 相互独立——只有在所有子技能都返回后,才进行去重和评分。一次性在同一条消息中并行启动所有适用的子技能 Agent;不要逐个启动。下方固定的类别顺序仅用于呈现报告,不代表执行顺序。(例外:Claude.ai 降级模式见第 9 节,由于没有可用的子 Agent,需按顺序执行。)
  • **启动前:**通过 scripts/dependency_mapper.py 预先计算依赖关系图(适用于 codeprobe-architecture 的调用协议步骤 8),并运行 scripts/file_stats.py 获取清单和代码库统计信息(若无法使用 Python 3,则跳过并妥善处理)。
  • /codeprobe audit:以 full 模式启动全部 9 个子技能。呈现顺序:codeprobe-security、codeprobe-error-handling、codeprobe-solid、codeprobe-architecture、codeprobe-patterns、codeprobe-performance、codeprobe-code-smells、codeprobe-testing、codeprobe-framework。收集所有发现。运行验证流程(第 4B 节)。执行去重(第 7A 节)。根据严重程度计数计算类别评分。汇总各文件的发现,并按被标记的不同类别数排序,确定热点文件。
  • /codeprobe quick:以 scan 模式并行启动全部 9 个子技能。收集每个子技能排名前 5 的候选项(已包含完整的输出契约细节)。按严重程度(critical > major > minor > suggestion)对所有候选项排序;若严重程度相同,则按类别权重排序(第 7 节)。将暂定排名前 8 的候选项送入验证流程(第 4B 节),然后呈现验证后保留的前 5 项。仅执行一轮,不重新运行。
可用的子技能
  1. codeprobe-security — 安全漏洞检测
  2. codeprobe-error-handling — 错误处理与韧性
  3. codeprobe-solid — SOLID 原则分析
  4. codeprobe-architecture — 架构分析
  5. codeprobe-patterns — 设计模式顾问
  6. codeprobe-performance — 性能与可扩展性
  7. codeprobe-code-smells — 代码异味检测
  8. codeprobe-testing — 测试质量与覆盖率
  9. codeprobe-framework — 框架专属最佳实践

4A. 差异审查(/codeprobe diff [base])

PR 风格审查:仅分析相对于基准分支的变更,让审查工作聚焦于即将合并的代码。

前置条件
  • 需要 Git 仓库:通过 git rev-parse --is-inside-work-tree 检查。如果当前目录不在 Git 仓库中,告知用户差异审查需要 Git,并建议改用 /codeprobe audit。
  • Git 操作严格只读(见上文的只读限制)。
基准解析
  1. 如果用户提供了基准引用,则使用该引用(通过 git rev-parse --verify <base> 验证)。
  2. 否则依次尝试 main 和 master。
  3. 如果都无法解析,则询问用户要与哪个基准进行比较。
收集变更文件
  1. 计算合并基点:单独运行 git merge-base <base> HEAD 作为一次 Bash 调用,并将输出的 SHA(下文记为 <MB>)替换到后续命令中——不要使用 shell 变量(遵循 Bash 规范,第 4 节)。与合并基点比较,而非基准分支顶端提交,这样只会审查当前分支的变更;即使基准分支已更新,也与 PR 差异视图保持一致。
  2. 变更文件:git diff --name-status <MB>(这会包含未提交的工作区变更,这是预期行为——审查即将提交的内容)。排除已删除文件(状态 D)。
  3. 未跟踪文件:git ls-files --others --exclude-standard。
  4. 将两个列表都筛选为清单所用的源代码/配置文件扩展名(第 4 节),并应用相同的目录排除规则。
  5. 每个文件的变更行范围:从 git diff -U0 <MB> -- <file> 的 @@ 分块标题中解析新文件一侧的行范围。未跟踪文件视为全部变更。
  6. 如果最终列表为空,则报告“与 <base> 相比,没有可审查的变更”并停止——未经用户请求,不要改为执行完整审计。
执行

运行标准流程(第 2–4 节),并作如下调整:

  • 文件清单中仅包含已更改或未跟踪的文件,并为每个文件标注更改的行范围。
  • 以 full 模式并行启动全部 9 个子技能。为每个 Agent 提示词添加:“这是一次差异审查。每条发现都必须以清单中的某个文件为依据,并优先关注已标注的更改行。可以读取周边或相关文件以了解上下文,但不要报告未更改文件中的发现。”
  • 依赖图(dependency_mapper.py)仍在整个项目范围内运行——更改的导入可能与未更改文件共同形成循环。
  • 按照常规流程进行去重(第 7A 节)和评分(第 7 节),但仅针对差异发现进行计算。跳过热点计算和代码库统计——它们描述的是整个代码库的健康状况,而非差异。
渲染

参见第 8 节(/codeprobe diff 小节)——差异输出使用 templates/pr-review-comment.md。验证流程(第 4B 节)在去重前对差异发现运行;被拒绝的数量填入汇总表的“经验证拒绝”行。


4B. 验证流程

每个子技能 Agent 返回结果后,且在去重(第 7A 节)之前,使用独立的验证 Agent 重新检查每条 Critical 和 Major 级别的发现。验证 Agent 的任务是对抗性质的:找出该发现不成立的原因,而不是复述它。如果 .codeprobe-config.json 设置了 "verify": false,则跳过整个章节。

运行时机
  • /codeprobe audit、/codeprobe diff 和每个单类别命令(security、solid 等):所有子技能 Agent 返回后运行一次。
  • /codeprobe quick:对扫描模式汇总候选项排序后运行(第 4 节“执行顺序”)。只验证临时排名前 8 中的 Critical 和 Major 级别发现;前 8 中的 Minor 和 Suggestion 候选项直接作为保留项通过。如果前 8 中没有 Critical 或 Major 级别的发现,则不启动任何 Agent。
验证内容
  • 验证每条 severity 为 critical 或 major 的发现。minor 和 suggestion 级别的发现不做处理;绝不发送给验证 Agent。
  • 如果没有 Critical 或 Major 级别的发现,则不启动任何 Agent,并将 rejected_count = 0。
并行分发
  • 每个至少包含一条 Critical 或 Major 级别发现的类别启动一个验证 Agent。在一条消息中并行启动所有验证 Agent,绝不能逐个启动。最多 9 个。
  • /codeprobe quick 会只启动一个验证 Agent,负责验证所有类别中临时排名前 8 的 Critical 和 Major 级别发现。
验证 Agent 提示词组成

每个验证 Agent 提示词按以下顺序包含:

  1. shared-preamble.md 中的 只读约束 块。
  2. 按路径区分的验证标准,置于以下标记之间:
    === VERIFICATION RUBRIC ===
    Read the file at {absolute path of verification-rubric.md, resolved relative to this SKILL.md} with the Read tool before doing anything else. It defines your role, procedure, hard limits, and output shape. If the Read fails, stop and reply with exactly `RUBRIC UNREADABLE: {path}` and nothing else.
    === END VERIFICATION RUBRIC ===
    
    不要将验证标准内联。如果验证 Agent 回复 RUBRIC UNREADABLE,则自行读取该文件,并将其内容逐字内联到相同标记之间,然后重新启动该验证 Agent 一次。
  3. 待验证的发现——该类别下的 Critical 和 Major 级别发现(对于 quick,为前 8 中的 Critical 和 Major 级别发现,可能跨越多个类别),并包含第 5 节规定的所有输出契约字段。
  4. 文件清单(第 4 节“上下文准备”步骤 2)。
  5. 参考指南路径(仅路径)。
  6. 目标路径。
  7. 一行 Bash 使用规范:“每次 Bash 调用只能包含一条命令——绝不使用 &&、;、循环或 shell 变量;使用 Read 读取文件。”(第 9 步“调用协议”中,所有子技能 Agent 提示词也都包含相同句子。)

验证标准、前言和子技能文件的绝对路径来自本 SKILL.md 所在位置(技能基础目录);绝不要运行 realpath、pwd 或 cd 来推导路径。

不要包含子技能的 SKILL.md、其检测表,或只读约束块以外的共享前言。验证 Agent 如果看到检测模式,就会重新执行该模式,而不是追查该声明。

处理验证结果

验证器返回 verification-rubric.md 中定义的结构(findings[],包含 verification 和 verification_note,以及一个 summary)。按以下方式应用每项结果:

verification协调器操作
confirmed原样保留该发现。
downgraded保留 id;将原始严重级别记录为 old_severity,然后将 severity 设置为回传的值(必须恰好比原始级别低一个档位——若不符合,则按 confirmed 处理);将 verification_note 存储在该发现上。将 {id, location, old_severity, severity, verification_note} 追加到 downgraded[]。
rejected在 Section 7A 之前且在评分之前移除该发现。将 {id, location, verification_note} 追加到 rejected[]。

然后设置 rejected_count = len(rejected[]) 和 downgraded_count = len(downgraded[])。忽略任何 id 不在输入中的回传条目、任何提高严重级别的结果以及任何新发现——验证器不能添加或升级发现。未收到验证结果的输入发现将未经验证、原样保留;其类别计入 unverified_categories(无论该类别有多少发现缺少结果,也无论其验证器是否同时因 Failure handling 而失败,每个类别最多计数一次)。

失败处理

如果验证器 Agent 报错、超时,或返回的输出无法映射到评分标准的结构,则该类别的每项发现均未经验证、原样保留,并将 unverified_categories 加一。验证绝不会阻止或延迟报告;缺失的验证器结果会显示在仪表板行(Section 8)中,不会重试。唯一例外是 RUBRIC UNREADABLE 回复:它会按 Verifier prompt composition 中的说明进行一次内联重新生成;若再次失败,则适用本规则。对于 /codeprobe quick,其单个验证器涵盖多个类别,失败时 unverified_categories 设置为其输入中涉及的类别数。

报告规则(适用于所有界面)

凡是显示验证计数的界面,都必须准确呈现 **Rejected by verification:** {rejected_count}(PR 评论改用表格行)。当 unverified_categories > 0 时,追加 ({n} categories unverified);当 n 为 1 时使用 category。若配置 verify 为 false,则完全省略该行、表格行以及 Rejected/Downgraded 部分。各界面的放置位置有意不同——终端中位于仪表板最后一行,保存文件的 Score Breakdown 中位于 "Duplicates removed" 之后——且每个模板都规定了自己的位置。

/codeprobe quick 渲染规则

单个验证器返回结果后:剔除 rejected 候选项、应用降级、重新排列剩余项(按严重级别,再按类别权重),然后渲染排名前 5 的项。降级行的 Severity 单元格末尾追加 _(downgraded from {old_severity} by verification)_(模板中的 {downgrade_note})。如果渲染的行少于 5 行,且至少有一个候选项被拒绝,则在表格正下方添加 Fewer than 5 findings survived verification.;否则,较短的表格不添加说明。排名第 9 或更低的候选项永不验证,也永不渲染。{total_findings}、严重级别总数和 Estimated Score 均根据扫描模式的计数得出,其中已移除所有被拒绝的候选项,所有降级候选项均按新严重级别计数。


5. 输出约定

每个子技能报告的每项发现都 MUST 包含所有标记为 Yes 的字段。两个验证字段只能由编排器的验证器(第 4B 节)设置,子技能不得设置:

字段必填描述
idYes格式为 {PREFIX}-{NNN} 的唯一标识符(例如,SRP-001、SEC-003)
severityYes以下之一:critical、major、minor、suggestion
severity_rationaleYes用一句话说明为何属于此严重性级别,而不是低一级。
locationYes文件路径 + 行范围(例如,src/UserService.php:45-67)
problemYes用一句话描述问题
evidenceYes来自代码的具体证据——引用相关代码行
suggestionYes修复建议
fix_promptYes一段可直接复制粘贴的提示词,用户可交给 Claude Code 应用修复
refactored_sketchNo可选的代码片段,展示改进后的版本
verification仅限编排器以下之一:confirmed、downgraded、rejected。只能由编排器的验证器针对 Critical/Major 级发现设置;子技能不得设置。
verification_note若已降级/驳回用一句话说明:对于 downgraded,严重性理由中的哪项边界判断不成立;对于 rejected,说明原因并引用起到缓解作用的代码。对于 confirmed,留空。
发现格式示例
### SRP-001 | Major | `src/UserService.php:45-67`

**Problem:** UserService violates Single Responsibility — handles authentication, email sending, and database queries in one class.

**Severity rationale:** Major (not Minor) because three unrelated responsibilities are concentrated in one class on a critical auth path — refactoring will touch every caller; not Critical because the code works correctly today, this is a maintainability risk, not a production defect.

**Evidence:**
> Lines 45-50: `public function authenticate($credentials) { ... }`
> Lines 52-60: `public function sendWelcomeEmail($user) { ... }`
> Lines 62-67: `public function findByUsername($name) { ... }`

**Suggestion:** Extract email logic into a dedicated `UserMailer` service and database queries into a `UserRepository`.

**Fix prompt:**
> Refactor `src/UserService.php` to follow Single Responsibility Principle: extract `sendWelcomeEmail()` into a new `UserMailer` class and `findByUsername()` into a `UserRepository` class. Keep `authenticate()` in `UserService` and inject the new dependencies.

6. 严重性级别

级别优先级含义示例
CriticalP0已确认的 Bug、可利用的安全漏洞,或可能导致生产环境危害的数据丢失/损坏风险使用用户输入的 SQL 注入、数据变更端点缺少身份验证、导致数据损坏的竞态条件、核心路径上未处理的崩溃、多步骤写入缺少数据库事务
MajorP1影响可维护性、可靠性或可扩展性的重大问题,会增加风险,但不是会立即影响生产环境的缺陷关键业务逻辑缺少测试、类过大、代码重复、外部调用缺少错误处理、N+1 查询、缺少输入验证
MinorP2代码异味,风险较低,值得为长期健康考虑处理魔法数字、嵌套过深、命名不佳、缺少边界情况测试、错误详情过于冗长
SuggestionP3改进建议,有则更好,忽略也没有实际风险模式方面的机会、风格改进、推测性泛化
严重性判定准则

以下情况绝不属于 Critical——最高归类为 Major:

  • 缺少测试(即使是关键业务逻辑的测试)
  • 代码重复或类/文件过大
  • 任何类型的代码异味
  • 违反框架惯例
  • 缺少文档、注释或类型注解

Critical 仅适用于以下情况:

  • 已确认的 Bug(代码会产生错误结果或崩溃)
  • 可利用的安全漏洞(注入、绕过身份验证、有证据支持的 IDOR)
  • 数据丢失或损坏风险(缺少事务、写入时发生竞态条件)
  • 敏感数据泄露(代码中包含密钥、日志中记录凭据)

**子技能:不得将发现的严重性提升到检测表指定级别以上。**如果表中标注为「Major」,即使具体情况看起来很严重,也应按 Major 报告。编排器的评分公式会考虑各级别发现的数量。


7. 评分

收集所有发现后,按类别计算分数,并计算总体分数。

类别分数公式

每个扣分项都设有上限,以防单个严重级别主导分数:

crit_penalty  = min(50, critical_count * 15)
major_penalty = min(30, major_count * 6)
minor_penalty = min(10, minor_count * 2)

category_score = max(0, 100 - crit_penalty - major_penalty - minor_penalty)

建议不会影响分数。

理由: 收益递减机制可防止单个严重级别将分数降至最低。某个类别有 4 个严重问题时,得分为 50(而不是 0),这表明存在问题,但代码并未完全失效。三个级别的总扣分上限为 90,因此只有各个严重级别都出现极端问题时,分数才会降至 0。

类别权重
类别权重
安全性20%
SOLID15%
架构15%
错误处理12%
性能12%
测试质量10%
代码异味8%
设计模式4%
框架4%

所有 9 个类别均已启用。权重总和为 100%。

总体分数
overall = sum(category_score_i * weight_i for each active category)

如果 .codeprobe-config.json 中的 skip_categories 排除了部分类别,则通过除以启用类别的权重总和来归一化:

overall = sum(category_score_i * weight_i for each active category) / sum(weight_i for each active category)

将结果限制在 [0, 100] 范围内。

分数解读
范围状态
80-100健康
60-79需要关注
0-59严重

7A. 跨类别去重

在计算分数之前,并在验证环节(第 4B 节)移除被驳回的问题并应用降级之后,对多个类别针对同一问题提出的问题进行去重。

去重流程
  1. 按位置分组问题。 将每个问题的 location 规范化为 {file}:{start_line}。如果两个问题位于同一文件,且行范围重叠(即 start_line_A <= end_line_B 且 start_line_B <= end_line_A),则视为重叠。

  2. 先检查是否确有分歧。 去重适用于“同一问题,不同视角”,而非相互矛盾的建议。如果两个重叠问题的建议方向相反(例如,SOLID 建议抽取抽象,而性能类别认为该抽象会带来开销;架构类别建议解耦,而性能类别建议保持局部性),则不要去重。保留两个问题的完整严重级别,并将这组问题列入报告的相互冲突的建议部分,同时用一行说明列出需要权衡的事项。操作人员必须看到这种冲突并作出决定——悄悄选出一个胜者,会掩盖恰恰需要人工判断的事项。

  3. 针对其余来自不同类别、彼此重叠的问题组: a. 选择主要问题。 按以下优先顺序处理:

    • 涉及身份验证、注入或数据暴露的问题,优先选择安全性问题(SEC)
    • 涉及异常或验证的问题,优先选择错误处理问题(ERR)
    • 涉及查询或缓存的问题,优先选择性能问题(PERF)
    • 涉及结构性违规的问题,优先选择 SOLID 问题(SRP/OCP/LSP/ISP/DIP)
    • 涉及层级或边界违规的问题,优先选择架构问题(ARCH)
    • 如果仍无法确定,则优先选择权重较高的类别(第 7 节) b. 移除重复项。 将组内每个非主要问题从问题列表中彻底移除——它既不会出现在报告正文中,也不会计入所属类别的严重级别统计。(早期版本会将重复项降级为 suggestion,这只会让建议数量被无关项虚增。) c. 交叉引用主要问题。 在主要问题的 suggestion 字段末尾追加:Also flagged by: {list of duplicate category:id pairs} — 这会保留跨类别信号(也会影响热点排名),同时避免重复条目。 d. 统计移除项。 记录移除的重复项总数,并在仪表板的“已移除重复项”一行中报告。
  4. 去重后重新统计每个类别的严重级别总数,然后继续评分。

示例
  • 在同一位置发现“刷新会绕过配额”:SEC-007、ERR-011、FW-001。保留 SEC-007(交叉引用“另见:ERR-011、FW-001”),删除 ERR-011 和 FW-001。
  • 在同一文件中发现“上帝组件”:SRP-001、SMELL-001、ARCH-005。保留 SRP-001(结构性问题优先采用 SOLID),删除其他项。
  • SRP-002 建议“从 OrderService 中提取 PricingCalculator”,而同一行的 PERF-004 则指出“这条热路径应保持内联——间接调用会导致每个请求都产生分配”:这是实质性冲突——两项都保留,并在“冲突建议”下呈现。

8. 报告呈现

根据所用命令呈现最终输出。

/codeprobe audit — 完整审计报告

使用 templates/full-audit-report.md 中的模板(通过 Read 加载)来组装保存的报告文件的 Markdown。终端输出是摘要——用户必须在终端中看到可视化摘要,不能只看到“报告已保存”这一行。

终端与保存文件的内容划分(强制):

界面显示内容生成方式
终端仪表板 + 执行摘要 + 关键发现(完整详情)+ 优先修复顺序(前 5 项)+“报告已保存”一行在助手回复中流式输出 Markdown 各部分
保存的文件(./codeprobe-reports/<project>-<cmd>-<ts>.md)全部内容:仪表板、执行摘要、所有关键/主要发现、次要问题/建议数量、完整优先修复顺序、“验证后降级”和“验证后驳回”部分使用 Write 工具写入纯 Markdown

终端输出绝不能为空,也不能缩减为仅有保存确认。如果 Claude 在之前的运行中只输出了保存提示,那就是未正确遵循这些指令导致的错误——应按顺序执行以下流程予以修正。

逐步流程

A. 计算数据(两个界面共用)

  1. 按第 4 节运行子技能,收集发现项;按第 4B 节验证关键/主要发现项;按第 7A 节去重。
  2. 计算类别评分、总评分、热点和代码库统计信息。
  3. 在内存中组装“报告数据包”:{dashboard_data, exec_summary, critical[], major[], minor_counts[], suggestion_counts[], fix_order[], rejected[], rejected_count, downgraded[], downgraded_count, unverified_categories}。

B. 呈现到终端(面向用户——按顺序在助手回复中直接输出为 Markdown)

不要通过 Bash 工具传递仪表板。Claude Code 的界面默认会折叠 Bash 工具的输出(+N lines (ctrl+r to expand)),将仪表板隐藏在折叠区域中。应将仪表板作为普通的助手回复 Markdown 输出,让用户能立即看到。现代终端(Ghostty、iTerm2 等)会自行应用 Markdown 样式——粗体、行内代码高亮、强调——这是此路径中唯一可用的着色方式。如果没有显示颜色,纯文本也可以;不要尝试在回复中强行加入 ANSI 转义序列。

(对于用户在 Claude Code 之外的自有 Shell 中直接运行审计,scripts/render_dashboard.py 可供使用,其标准输出是真正的 TTY。不要在 /codeprobe audit 流程中调用它。)

  1. 仪表板(markdown) — 内联输出仪表板区块。包括:标题行(## Code Health Report — {project})、**Overall Health:** {score}/100 [{status_label}]、包含 9 行的 Category Scores markdown table,列为 Category | Score | Bar | Status(进度条用反引号括起,使用 20 个 Unicode 字符 █/░,按分数比例显示)、代码库统计区块(文件数、LOC、后端/前端占比、最大文件、测试比例、注释比例)、热点列表(最多 3 项),以及最后单独一行的 **Rejected by verification:** {rejected_count}(当 unverified_categories > 0 时,附加 ({n} categories unverified);n 为 1 时使用 category;仅当配置 verify 为 false 时才省略整行)。Status 列中的状态标签使用纯文本,不用表情符号,表格内不加方括号。
  2. 执行摘要 — 用 2–3 句话概述最重要的发现。
  3. 关键发现 — 完整详情 — 针对每项关键发现,提供:ID、位置、问题、严重性判定依据、证据、建议、修复提示词。(仍为 Critical 的发现从未被降级,因此这里不会出现 **Verification:** 行;降级项列在已保存文件的 “Downgraded by Verification” 表格中。)这是信号最集中的部分;始终在终端中显示。
  4. 优先修复顺序(前 5 项) — 显示完整优先修复顺序中的前 5 项。完整列表请参阅已保存文件。
  5. 保存确认行 — --> Report saved to ./codeprobe-reports/{project}-{cmd}-{YYYY-MM-DD-HHMMSS}.md(不使用表情符号;使用 ASCII 箭头)。这是终端输出的最后一行。

不要同时在终端输出主要发现表、次要/建议数量或完整修复顺序——这些内容已包含在保存文件中,重复输出会使终端内容冗长。用户可以打开已保存文件查看完整内容。

C. 编写已保存文件的 markdown

  1. 使用 templates/full-audit-report.md 中的占位符构建完整 markdown,其中包含不会输出到终端的部分(主要发现表、次要/建议数量、完整优先修复顺序、“Downgraded by Verification” 表格——当 downgraded_count 为 0 时省略,以及折叠的 “Rejected by Verification” 区块——当 rejected_count 为 0 时省略)。
  2. 按 {project}-{cmd}-{YYYY-MM-DD-HHMMSS}.md 生成文件名:
    • {project} — 将目标路径解析为绝对路径(用户未传入路径时,使用当前工作目录);取其基本名;如果该基本名指向文件,则去掉扩展名;将其转换为 slug(小写;将 [^a-z0-9]+ 的任意连续匹配替换为单个 -;去除开头和结尾的 -);如果 slug 为空,则使用 unknown。
    • {cmd} — 第 1 节中路由的子命令(audit、diff、security、solid、architecture、performance、errors、tests、smells、patterns、framework),转换为小写。
    • {YYYY-MM-DD-HHMMSS} — 当前本地时间,通过一次 Bash 调用获取:date +%Y-%m-%d-%H%M%S。如果 Bash 不可用或被拒绝,则使用任意工具输出中可见的最新时间戳;否则使用 0000-00-00-000000;绝不可让占位符未填充。
  3. 确保 ./codeprobe-reports/ 存在(如不存在,通过 Bash 执行 mkdir -p ./codeprobe-reports)。
  4. 使用 Write 工具写入 ./codeprobe-reports/{project}-{cmd}-{YYYY-MM-DD-HHMMSS}.md。
  5. 如果写入失败(文件系统只读、权限被拒绝等),在终端中简短提示,但不要重新输出摘要。

D. 终端输出约定(硬性要求)

  • 终端输出必须按以下顺序包含:仪表板 → 执行摘要 → 关键发现 → 前 5 项修复顺序 →「报告已保存」行。
  • 当配置 verify 开启时(默认开启),仪表板必须以 **Rejected by verification:** 行结尾——0 是有效计数。
  • 如果没有关键发现,则显示仪表板、执行摘要、一行「未发现关键问题」说明、前 5 项修复顺序(仅包含主要问题)和保存确认——内容仍不得为空。
  • 如果报告保存失败,仍须输出完整的终端摘要——不得因文件写入而阻止输出摘要。
  • 如果模板文件缺失,则按照相同的章节顺序内联呈现;保存步骤 (C) 仍适用。

状态阈值(适用于整体健康度和各类别评分):

  • 80-100 =「健康」
  • 60-79 =「需要关注」
  • 0-59 =「严重」

令牌预算指南: 对于约有 100 项发现的代码库,分层发现布局(主要问题使用表格,次要问题/建议仅显示计数——全部详情保存在文件中)预计在磁盘上占用约 8,000-12,000 个令牌(相比之下,所有发现均提供完整详情时约为 40,000 个令牌)。终端摘要要精简得多,因为其中只会输出仪表板、执行摘要、关键发现和前 5 项修复顺序。用户可以通过 /codeprobe security . 等命令查看特定类别的完整详情。

/codeprobe quick — 快速审查摘要

使用模板 templates/quick-review-summary.md(通过 Read 加载)。呈现之前,先对暂定的前 8 项执行第 4B 节(/codeprobe quick 呈现规则)中说明的单次验证流程;表格显示排名前 5 的保留项,降级项在其 Severity 单元格中附带降级说明。如果因候选项被拒绝而导致呈现的条目少于 5 项,则显示一行说明。若模板尚不存在,则内联呈现:

  1. 标题:项目名称、「快速审查 — 前 5 项问题」。
  2. 前 5 项发现:对影响最大的 5 个问题提供完整详情,并为每项附上修复提示词。
  3. 摘要计数:按严重程度统计所有类别中的问题总数(移除被拒绝的候选项,降级项按其新严重程度计入),然后显示 **Estimated Score:**,接着显示 **Rejected by verification:** {rejected_count}(第 4B 节报告规则)。
  4. 后续步骤:建议运行 /codeprobe audit 了解完整情况。
/codeprobe diff — PR 风格审查

使用模板 templates/pr-review-comment.md(通过 Read 加载)。将 {branch} 替换为当前分支(git rev-parse --abbrev-ref HEAD),将 {base_branch} 替换为解析出的基准分支,将 {changed_files} 替换为已审查文件数,并将 {overall_score} 替换为按照标准公式(第 7 节)对差异发现应用计算后的分数。将 {version} 替换为此文件 frontmatter 中的 metadata.version。

  • 终端:将填充后的模板直接作为助手响应 Markdown 输出(内容足够精简,可整体输出),然后输出保存确认行(格式与第 8B 节步骤 5 相同)。
  • 已保存文件:将相同的 Markdown 按照第 8C 节的文件名和写入规则,写入 ./codeprobe-reports/{project}-diff-{YYYY-MM-DD-HHMMSS}.md。
  • 呈现的 Markdown 专为粘贴到 GitHub PR 评论中而设计——内容必须自包含(正文中不得提及「已保存的文件」)。
  • 差异发现适用验证规则(第 4B 节);{rejected_count} 用于填充摘要表格中的「Rejected by verification」行,降级发现的要点则在问题文本后附加 _(downgraded from {old_severity} by verification)_(即模板中的 {downgrade_note})。
/codeprobe <category> — 单类别报告

适用于 security、solid、architecture、performance、errors、tests、smells、patterns 和 framework。一个子技能以 full 模式运行,然后由一个验证器进行验证(第 4B 节)。单个类别的范围有限,用户深入查看某个类别正是为了获取完整细节,因此此处不要将 Minor 或 Suggestion 级别的发现折叠为计数。

终端(直接以助手回复的 Markdown 输出,顺序如下):

  1. 标题:## {Category} Review — {project},并在下一行列出计数:{n} critical · {n} major · {n} minor · {n} suggestions。
  2. 每条发现的完整详情,按 ### Critical Issues、### Major Issues、### Minor Issues、### Suggestions 分组(省略空分组),每条均按 shared-preamble.md 中的 Rendered Finding Format 呈现,包括 **Severity rationale:** 行;如果发现的严重程度已下调,还需包含 **Verification:** 行。
  3. 按照第 4B 节的报告规则,显示 **Rejected by verification:** {rejected_count}。
  4. 保存确认行——格式与第 8B 节第 5 步相同。

保存的文件:与终端输出相同的 Markdown,另加折叠的“Rejected by Verification”部分(包含一个 <details>,内含 ID | Location | Reason 表格;当 rejected_count 为 0 时省略),并按照第 8C 节的文件名和写入规则,写入 ./codeprobe-reports/{project}-{cmd}-{YYYY-MM-DD-HHMMSS}.md。

9. Claude.ai 降级模式

检测是否可访问文件系统。如果用户粘贴或上传了代码,而不是提供文件路径,或者 Read/Glob/Grep 工具不可用:

  1. 切换到降级模式:仅分析上下文中提供的代码。
  2. 按顺序执行子技能,分析粘贴的代码(不使用并行 Agent)。
  3. 跳过 file_stats.py、dependency_mapper.py 及所有依赖脚本的步骤(子技能改用仅由大模型执行的分析——架构分析将无法进行确定性的循环检测)。
  4. 跳过 /codeprobe diff、审计仪表板中的 Codebase Stats 行,以及报告保存步骤(不写入文件系统)。仍需在终端输出评分、热点和发现。
  5. 跳过验证流程(第 4B 节)——没有可运行验证器的子 Agent——并按照第 4B 节的报告规则输出 **Rejected by verification:** 0 ({n} categories unverified);其中 n 为其 Critical 或 Major 级别发现原本需要交由验证器处理的类别数量;当 n 为 0 时省略括号中的后缀。
  6. 告知用户:“正在 Claude.ai 模式下运行——代码库统计、差异审查和多文件分析等部分功能不可用。正在直接分析所提供的代码。”
  7. 仍需按标准输出约定格式生成发现。
  8. 仍需根据可用子技能的发现计算评分。

10. 执行流程摘要

调用 /codeprobe 时,按以下顺序执行:

  1. 解析命令:从用户输入中提取子命令和目标路径。
  2. 验证命令:检查路由表。如果子命令未知,说明情况并列出可用命令。
  3. 解析目标路径:使用提供的路径,或默认使用当前工作目录。对于 diff:改为按照第 4A 节解析基准引用,并收集已更改文件及其行范围——清单仅限于这些文件。
  4. 加载配置:检查项目根目录是否存在 .codeprobe-config.json。如果不存在,则应用默认值。
  5. 自动检测技术栈:扫描目标路径以查找技术信号。加载匹配的参考资料。
  6. 应用配置覆盖项:如果配置中设置了 framework,则调整检测结果。应用 skip_categories 和 skip_rules。
  7. 执行子技能:准备共享上下文(第 4 节),然后以适当模式并行启动所有适用的子技能 Agent。
  8. 收集发现项:按输出约定格式汇总所有发现项。 8a. 验证发现项:对严重/主要级别的发现项执行第 4B 节(每个类别启动一个验证器,并行运行;quick 使用一个验证器验证其初步前 8 项中的严重/主要发现项);删除未通过验证的发现项,应用降级,记录 rejected_count、downgraded_count 和 unverified_categories。如果配置项 verify 为 false,或处于 Claude.ai 降级模式(第 9 节),则跳过此步骤。
  9. 去重发现项:应用跨类别去重流程(第 7A 节)——将真正的冲突归入“冲突建议”部分,删除真正重复的发现项,并重新统计各类别的严重级别数量。
  10. 计算分数:使用去重后的严重级别数量以及第 7 节中的公式,计算各类别及总体分数。
  11. 生成报告:使用适当的模板或内联格式整理输出。对于 /codeprobe audit,使用分层输出格式。
  12. 呈现给用户:显示最终报告。

请记住:整个过程均为只读。在任何情况下都不会修改用户文件。

评论

支持 Markdown