Files
Store.Management/.agents/skills/review-rules/SKILL.md
T
2026-10-27 19:01:56 +08:00

8.3 KiB
Raw Blame History

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、PasswordBox
  • hc:TextBox、hc:PasswordBox、hc:SearchBar
  • DataGrid 文本列的 EditingElementStyle 里的编辑框

检查步骤:

  1. 在目标 XAML 中搜索上述标签。
  2. 用户能打字的控件必须有 MaxLength=。没有 → 🔴 高,补上。
  3. 值必须是 {x:Static shared:InputLimits.Path} 或 Text。写成 MaxLength="250" 这类裸数字 → 🟡 中,改成常量。
  4. 按绑定属性名判断档位:
    • 文件名、文件夹名、项目名、会拼进路径的名称 → InputLimits.Path(100)
    • 其余名称、描述、备注、密码、搜索关键字 → InputLimits.Text(250)
  5. 完整路径例外: IsReadOnly 且绑定的是选择器选出的目录/文件路径 → 不要求 MaxLength(不要用数字去卡系统路径)。可编辑的完整路径输入框 → 🔴 高,改成选择器。
  6. 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 或 &#xE...; 的 Unicode 硬编码图标
  • 图标是否用 Image.Source 绑定而非 TextBlock.Text
  • 图标枚举值是否来自 IconNameEnum(非自行编造)
  • 是否尝试通过 Foreground 修改图标颜色
  • IconText / HorizontalIconText.IconSize 的 FontSize 是否 < 16(禁止 12~14)
  • Button / RadioButton 内嵌 IconText 时是否过小或未设 Padding="0" 导致裁切