8.3 KiB
8.3 KiB
name, description, disable-model-invocation
| name | description | disable-model-invocation |
|---|---|---|
| review-rules | 根据项目的所有 coding rules 检查代码合规性,列出违规项并提供修复建议。 当用户要求检查代码是否违反 rules、做代码合规审查、或写完代码后要求自查时使用。 触发词:review-rules、规则检查、合规审查、检查 rules、违反规则。 | true |
代码规则合规审查
对照项目 .agents/rules/ 中的全部规则文件,逐条检查用户提供的代码,输出违规清单和修复指导。
执行流程
Step 1 — 加载规则
读取所有 .agents/rules/ 下的 .md 规则文件。如果本次对话中这些规则已在上下文中,则直接引用,无需重新读取。
Step 2 — 确认审查目标
用户通常以以下方式之一提供代码:
- 直接在消息中粘贴代码块
- 引用文件路径(
@path/to/file.cs) - 要求审查"刚才生成的代码"或"当前 diff"
确认目标后开始检查。如果目标不明确,追问用户。
Step 3 — 逐规则检查
按文件逐一比对。将每个 .md 中的约束转化为可检查项,系统性地检查:
| 规则文件 | 核心检查维度 |
|---|---|
csharp-syntax.md |
大括号、var 禁用、null 模式匹配、字符串插值、Debug.WriteLine(ex)、集合表达式、field 关键字、namespace、JSON 库选择、await/async、接口注释 |
wpf-xaml.md |
BindingProxy、UpdateSourceTrigger、Mode=OneWay、输入框必须显式 MaxLength、颜色 hex、布局注释、XAML 头部 |
wpf-core.md |
MVVM 属性写法(GetProperty/SetProperty)、AppFileHelper.PickFolder、LoadingStatus、输入限长、路径片段 vs 完整路径 |
icon-usage.md |
禁止 Windows 内置字体图标、禁止 Unicode 魔术数、必须用 Image 而非 TextBlock、必须用已有枚举 |
architecture.md |
优先使用内部库、编译后校验、文件锁定处理 |
editor-conventions.md |
换行符/编码(仅新建文件触发) |
Step 4 — 输出报告
使用以下格式输出:
## 规则合规检查报告
共发现 **N** 项违规。
| # | 严重度 | 规则文件 | 位置 | 问题 | 修复 |
|---|--------|---------|------|------|------|
| 1 | 🔴 高 | csharp-syntax | L45 | catch 中缺少 `Debug.WriteLine(ex)` | 在 `NLogger.Error` 之前加 `Debug.WriteLine(ex);` |
| 2 | 🔴 高 | wpf-client | L55 | MVVM 属性使用了 `ref` 模式 | 改为 `GetProperty(()=>...)` / `SetProperty(()=>..., value)` |
| 3 | 🟡 中 | csharp-syntax | L38 | 日志未使用字符串插值 | 改为 `$"保存失败: {ex.Message}"` |
严重度定义:
- 🔴 高:编译不会报错但明显违反强制约束(如
ref模式、缺少Debug.WriteLine(ex)、使用被禁 API) - 🟡 中:风格违规,不影响功能但不符合项目规范(如
var、字符串插值、null 比较) - 🟢 低:代码坏味道、可优化项(如空 if 块、缺少注释、未使用集合表达式)
每个违规项都应包含具体的修复代码(before/after)。
Step 5 — 询问是否修复
报告输出后,询问用户:
是否需要我自动修复以上违规项?
如果用户同意,逐项修复。修复过程中严格遵守以下安全约束:
5a — 仅修改语法与格式,不得改变功能
绝大多数规则违规是纯粹的语法/格式问题(见下表),修复时只改写法,不改行为。这条是修复的核心铁律。
| 违规类型 | 纯格式? | 示例 |
|---|---|---|
var → 显式类型 |
✅ | 不改变运行时行为 |
== null → is null |
✅ | 语义等价 |
string.Format(...) → $"" |
✅ | 语义等价 |
SetProperty(ref _x, v) → SetProperty(() => X, v) |
✅ | DevExpress 内部行为一致 |
new List<T>() → [] |
✅ | 编译结果可能不同但语义等价 |
补充 Debug.WriteLine(ex) |
✅ | 仅增加副作用,不改控制流 |
Task.FromResult(x) → await Task.CompletedTask; return x |
⚠️ | 方法签名从同步包装变为真正 async,需确认调用方不受影响 |
System.Text.Json → Newtonsoft.Json |
⚠️ | 行为可能不同(默认值处理、命名策略等),需确认 |
补 Mode=OneWay |
✅ | WPF 绑定行为不因 OneWay/TwoWay 而改变已有的数据流方向 |
5b — 有功能变更风险时必须先问
当一个修复不是纯格式替换时(上述标记为 ⚠️ 的项目,或任何你拿不准的改动),不要直接修改。先向用户说明:
- 当前写法与目标写法的差异
- 可能导致的功能变化(即使概率很低)
- 提供 2~3 个方案供选择(如"保持现状"、"改为推荐写法并补充测试"、"改为带兼容代码的折中写法")
用户确认后再动手。
5c — 修复后编译验证
所有修复完成后,如果改动涉及 C# 文件,按 architecture.md 的编译要求执行 dotnet build 验证。如遇到文件锁定按对应规则处理。
检查要点速查
csharp-syntax.md 高频违规
- catch (Exception ex) 中有无
Debug.WriteLine(ex)(log/MessageBox 之前) - 是否使用了
var(必须显式类型) - null 检查是否用了
is null/is not null(禁用== null) - 字符串拼接/日志是否用了
$""插值 - 是否使用了
System.Text.Json(应用 Newtonsoft.Json) - 是否用
Task.FromResult(应用await Task.CompletedTask) - 集合初始化是否用了
[](禁用new List<T>()) - 是否在代码中写了全限定名
- 接口成员是否有
///XML 文档注释 - 是否省略了 if/else/for 的大括号
- 文件级 namespace 是否正确
wpf-core.md / wpf-xaml.md 高频违规
- MVVM 数据绑定属性是否用了
GetProperty/SetProperty(禁用ref和field) field关键字是否仅用于 Command(未滥用)- 文件夹选择是否使用
AppFileHelper.PickFolder(禁用 WinForms 引用) - IsReadOnly 控件是否加了
Mode=OneWay - Run 绑定是否加了
Mode=OneWay - XAML 布局是否有分块注释
d:DataContext和DataContext="{core:DISource...}"是否都存在- 异步操作是否使用
LoadingStatus管理状态 - 输入框是否显式写了
MaxLength(见下方专项)
输入框 MaxLength(专项,🔴 高)
审查 XAML 时必须把下列标签全部找出来,缺 MaxLength 即违规:
TextBox、PasswordBoxhc:TextBox、hc:PasswordBox、hc:SearchBar- DataGrid 文本列的
EditingElementStyle里的编辑框
检查步骤:
- 在目标 XAML 中搜索上述标签。
- 用户能打字的控件必须有
MaxLength=。没有 → 🔴 高,补上。 - 值必须是
{x:Static shared:InputLimits.Path}或Text。写成MaxLength="250"这类裸数字 → 🟡 中,改成常量。 - 按绑定属性名判断档位:
- 文件名、文件夹名、项目名、会拼进路径的名称 →
InputLimits.Path(100) - 其余名称、描述、备注、密码、搜索关键字 →
InputLimits.Text(250)
- 文件名、文件夹名、项目名、会拼进路径的名称 →
- 完整路径例外:
IsReadOnly且绑定的是选择器选出的目录/文件路径 → 不要求MaxLength(不要用数字去卡系统路径)。可编辑的完整路径输入框 → 🔴 高,改成选择器。 NumericUpDown跳过。日志 / JSON 大段文本不限长时,旁边必须有注释说明原因,否则仍算违规。
修复示例:
<!-- ❌ -->
<TextBox Text="{Binding ProjectName, UpdateSourceTrigger=PropertyChanged}"/>
<!-- ✅ -->
<TextBox MaxLength="{x:Static shared:InputLimits.Path}"
Text="{Binding ProjectName, UpdateSourceTrigger=PropertyChanged}"/>
补 MaxLength 属于本规则要求的标准修复,审查发现后应直接改,不必再问是否改变输入行为。
icon-usage.md 高频违规
- 是否用了 Segoe Fluent Icons / Segoe MDL2 Assets / Segoe UI Symbol 等 Windows 内置字体
- 是否在代码或 XAML 中写了
\uExxx或...;的 Unicode 硬编码图标 - 图标是否用
Image.Source绑定而非TextBlock.Text - 图标枚举值是否来自
IconNameEnum(非自行编造) - 是否尝试通过
Foreground修改图标颜色 IconText/HorizontalIconText.IconSize的FontSize是否 < 16(禁止 12~14)- Button / RadioButton 内嵌
IconText时是否过小或未设Padding="0"导致裁切