mcpField
C
candid-loop

candid-loop

github.com/ron-myers测试与质量2154 次安装8 周前更新
代码仓库

关于 candid-loop

candid-loop 是围绕 candid-review 的代码审查与修复循环技能,供希望迭代处理审查问题的开发者使用。它支持自动、逐项确认和交互模式,并可按类别、忽略规则及迭代上限控制流程。

主要功能

  1. 01重复运行 candid-review
  2. 02自动或逐项应用修复
  3. 03交互式跳过与忽略问题
  4. 04按类别筛选问题
  5. 05配置迭代上限与审查规则

适用场景

  1. 01持续修复代码审查发现的问题
  2. 02逐项确认高影响修改
  3. 03忽略已知误报并限制审查类别

安装

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

$npx skills add https://github.com/ron-myers/candid --skill candid-loop

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

详细介绍

Candid Loop

反复运行 candid-review,直到代码没有问题。此技能会自动执行修复-审查-修复循环,不断应用修复并重新运行审查,直到没有剩余问题(或达到最大迭代次数)。

工作流

按顺序执行以下步骤:

步骤 1:加载配置

从 CLI 标志和配置文件加载循环配置。

优先级(从高到低):

  1. CLI 标志
  2. 项目配置(.candid/config.json → loop 字段)
  3. 用户配置(~/.candid/config.json → loop 字段)
  4. 默认值
检查 CLI 参数

解析 CLI 参数中的循环选项:

标志说明默认值
--mode <auto|review-each|interactive>执行模式auto
--max-iterations <N>最大循环迭代次数5
--categories <list>要强制执行的类别(逗号分隔)all

有效模式:

  • auto - 自动应用所有修复
  • review-each - 逐一处理每项修复(每项都回答 Yes/No)
  • interactive - 完全掌控,可跳过、忽略并批量处理

有效类别: critical、major、standards、smell、edge_case、architectural、all

如果提供了 CLI 标志,则使用这些标志,并跳过对相应选项的配置文件检查。

检查配置文件并应用默认值

从 .candid/config.json 读取 loop 字段(jq -r '.loop // null' .candid/config.json 2>/dev/null);如果不存在,则尝试读取 ~/.candid/config.json。对于未通过 CLI 设置的 mode、maxIterations、enforceCategories,使用配置中的值;同时提取 ignored {categories, patterns, ids}。应用配置时,输出 Using loop settings from project config 或 Using loop settings from user config。

仍未设置的项目使用默认值:mode = "auto"、maxIterations = 5、enforceCategories = ["all"]、ignored = { categories: [], patterns: [], ids: [] }。

  • 将已知误报的模式添加到忽略列表。
  • 将 maxIterations 保持在 5-10。
步骤 2:初始化循环状态

设置跟踪变量:

iteration = 0
totalFixesApplied = 0
allFixedIssues = []
registerQuestionsRaised = 0
registerQuestionsResolved = 0
registerPriorDecisionsApplied = 0

显示模式横幅:[<Mode> Mode] Running candid-loop with max [N] iterations...,随后另起一行显示 review-each 模式说明("You will review each fix one by one.")或 interactive 模式说明("Full control: skip, ignore, or batch process fixes.")。

步骤 3:运行审查循环

执行主循环:

WHILE iteration < maxIterations:
    iteration++

    Execute Step 3.1 through Step 3.6

    IF exitLoop == true:
        BREAK

IF iteration >= maxIterations AND remainingIssues > 0:
    Output warning: "Max iterations ([N]) reached. [M] issues remain."
    List remaining issues
循环不变量 — 不得违反
  1. PASS 必须基于全新且无问题的审查。 仅当最后一次迭代在应用最后一项修复后运行了 candid-review,且发现筛选后的问题数为 0 时,状态才能为 PASS。确认 .candid/last-review.json 的时间戳晚于最后一次 Edit。切勿根据较早迭代推断为 PASS。
  2. 没有进展 → 停止。 如果某次迭代应用了 0 项修复,但筛选后的问题仍然存在,则立即以 INCOMPLETE 退出——重复相同的审查无法解决问题。
  3. 振荡检查。 如果某个已在 allFixedIssues 中的问题 ID 在后续迭代中再次出现,则停止:Oscillation detected: fix for [id] was undone or reintroduced. 列出这两次修复,以便手动处理。
  4. 不要再次询问已拒绝的问题。 将通过“No”/“Skip”跳过的问题 ID 添加到 sessionSkipped;在后续迭代的步骤 3.4 中筛除这些问题。它们计入 INCOMPLETE,而不是再次提示。
第 3.1 步:运行 candid-review

显示迭代标题:

[Iteration [N]/[MAX]]
Running candid-review...

调用 candid-review 技能分析当前代码:

  • 使用 Skill 工具运行 /candid-review
  • 如果已配置语气设置,则传递这些设置
  • 等待审查完成,并将状态保存到 .candid/last-review.json

注意: candid-review 会显示自己的修复选择提示。在自动模式下,我们需要通过选择“应用所有修复”来处理。在交互模式下,则由用户在 candid-review 中自行选择。

决策记录: 如果配置中启用了决策记录,每次 candid-review 迭代都会独立读取和更新记录文件。这意味着:

  • 第 1 次迭代提出的问题会记录在记录文件中
  • 从第 2 次迭代开始,candid-review 会先检查记录文件,避免再次提出相同问题
  • 如果问题已在之前的迭代中得到回答,则会自动沿用该答案
  • 在自动模式下,记录文件中已有答案的“需要澄清”问题会直接应用,无需提示
第 3.2 步:读取审查结果

candid-review 完成后,读取保存的审查状态:

cat .candid/last-review.json 2>/dev/null

解析 JSON,提取:

  • 包含所有已发现问题的 issues 数组
  • 每个问题包含:id、file、line、category、title、description

如果文件不存在或为空:

No review state found. candid-review may not have completed.

报错退出。

第 3.3 步:按类别筛选问题

如果 enforceCategories 不是 ["all"]:

筛选 issues 数组,仅保留与 enforceCategories 匹配的问题:

filteredIssues = issues.filter(issue =>
    enforceCategories.includes(issue.category)
)

输出:Enforcing categories: [list]. Filtered to [N] issues.

第 3.4 步:筛除忽略的问题

应用配置中的忽略筛选条件:移除类别属于 ignored.categories、标题匹配 ignored.patterns 中任一正则表达式(不区分大小写),或 ID 属于 ignored.ids 的问题。

如果有问题被筛除:

Filtered out [N] ignored issues ([M] remaining)
第 3.5 步:检查是否完成

如果 filteredIssues.length === 0:

[Iteration [N]/[MAX]] No issues found!

exitLoop = true

跳至第 4 步(摘要)。

第 3.6 步:根据模式处理问题

如果 mode == "auto":

显示发现的问题:

[N/MAX] Found [M] issues. Applying fixes...

如果用户在提示词中选择了“Apply all fixes”,candid-review 技能会先行应用修复。由于我们处于 auto 模式,因此应该已将 candid-review 配置为自动应用修复。

对于每个已修复的问题,记录:

      ✓ [icon] Fixed: [title] in [file]:[line]

跟踪修复:

totalFixesApplied += appliedCount
allFixedIssues.push(...appliedIssues)

auto 模式下的决策登记表:

如果启用了决策登记表,candid-review 会在第 6 步(提出“需要澄清”问题之前)处理登记表查阅。在 auto 模式下:

  • candid-review 会自动应用登记表中的先前决策——记录:Applied prior decision (#N) for [file]
  • 新的“需要澄清”问题(没有先前答案)不会自动应用——这些问题需要人工输入,并在登记表中记录为 open
  • 这些问题在循环中视为“已跳过”——不会被计为阻止循环完成的剩余问题
  • 输出:Applied [N] prior decisions, skipped [M] new questions requiring clarification

跟踪登记表活动:

registerPriorDecisionsApplied += priorDecisionsCount
registerQuestionsRaised += newQuestionsCount
registerQuestionsResolved += resolvedCount

其中,resolvedCount 来自 candid-review 第 10.5 步的输出——它包含用户在阶段 8b 中回答的问题,以及重新审查时自动解决的问题。每次迭代后读取登记表文件,并与上一次读取结果进行比较,以统计新解决的条目。

继续下一次迭代。

如果 mode == "review-each":

逐一处理每项修复,并使用简单的“是/否”提示。

显示发现的问题:

[N/MAX] Found [M] issues. Reviewing each...

对于每个问题,使用 AskUserQuestion:

[1/M] [icon] [title]
File: [file]:[line]
Problem: [description]

问题:“应用此修复吗?”

选项:

  1. “是,应用此修复”
  2. “否,跳过此修复”
  3. “显示确切差异”——将修复以统一的修改前/后差异形式展示,基于当前文件内容,然后仅用“是/否”选项重新提问

跟踪用户选择:

  • 如果选择“是”→ 应用修复,将 totalFixesApplied 加 1
  • 如果选择“否”→ 继续处理下一个问题

处理完所有问题后,如果应用了任何修复,则继续下一次迭代。

如果 mode == "interactive":

完全控制模式,提供跳过、忽略和批量处理等更多选项。

显示发现的问题:

Found [M] issues:

对于每个问题,使用 AskUserQuestion:

[1/M] [icon] [title]
File: [file]:[line]
Problem: [description]

问题:“你希望如何处理此问题?”

选项:

  1. “应用修复” - 应用此修复并继续
  2. “跳过” - 跳过此问题并继续处理下一个
  3. “添加到忽略列表” - 将此问题 ID 添加到 ignored.ids 并跳过
  4. “跳过所有剩余问题” - 退出循环,并列出剩余问题

跟踪用户选择:

  • 如果选择“应用修复”→ 应用修复,将 totalFixesApplied 加 1
  • 如果选择“跳过”→ 继续处理下一个问题
  • 如果选择“添加到忽略列表”→ 在配置中将 issue.id 添加到 ignored.ids,然后继续
  • 如果选择“跳过所有剩余问题”→ 将 exitLoop 设为 true,并跳出内层循环

在 interactive 模式下处理完所有问题后,如果应用了任何修复,则继续下一次迭代。

第 3.7 步:更新忽略列表(如有请求)

如果用户为任何问题选择了“添加到忽略列表”:

  1. 读取当前的 .candid/config.json(如果不存在,则创建)
  2. 将问题 ID 添加到 loop.ignored.ids 数组
  3. 将更新后的配置写回文件
# Read, modify, write
jq '.loop.ignored.ids += ["issue-id-1", "issue-id-2"]' .candid/config.json > tmp.json
mv tmp.json .candid/config.json

输出:Added [N] issues to ignore list in .candid/config.json

第 4 步:显示摘要

循环退出后(成功或达到最大迭代次数),显示最终摘要:

Candid Loop [Complete|Stopped|Cancelled]

Summary:
- Iterations: [N]
- Issues fixed: [M]
- Status: [PASS|INCOMPLETE|CANCELLED]

如果为 INCOMPLETE:添加 Issues remaining: [P],并按 [icon] [title] in [file]:[line] 的格式列出剩余问题,另附提示:增加 --max-iterations、为误报添加持久忽略规则、手动审查复杂问题。

如果为 CANCELLED:添加 Issues skipped: [P] 并列出已跳过的问题。

决策登记表部分(启用登记表时添加到所有摘要版本):

如果配置中的 decisionRegister.enabled == true,则将此部分追加到所显示的摘要中:

Decision Register:
- Prior decisions applied: [N]
- New questions raised: [M]
- Questions resolved: [P]
- Open questions: [Q]

如果仍有未解决的问题:

Open questions can be reviewed at: [registerPath]/review-decision-register.md

配置

配置文件架构

添加到 .candid/config.json:

{
  "version": 1,
  "tone": "harsh",
  "loop": {
    "mode": "auto",
    "maxIterations": 5,
    "enforceCategories": ["all"],
    "ignored": {
      "categories": [],
      "patterns": [],
      "ids": []
    }
  }
}
字段说明
字段类型默认值描述
loop.mode字符串"auto""auto"、"review-each" 或 "interactive"
loop.maxIterations数字5最大审查修复循环次数
loop.enforceCategories数组["all"]要强制检查的类别
loop.ignored.categories数组[]完全跳过的类别
loop.ignored.patterns数组[]用于匹配问题标题的正则表达式模式(例如:["Unicode", "timezone"])
loop.ignored.ids数组[]要跳过的特定问题 ID

CLI 示例

# Run with defaults (auto mode, all categories, max 5 iterations)
/candid-loop

# Combine flags
/candid-loop --mode review-each --max-iterations 10 --categories critical,major

问题类别参考

类别图标描述
critical🔥生产环境致命问题:崩溃、安全漏洞、数据丢失
major⚠️严重问题:性能、缺少错误处理
standards📜违反 Technical.md 规范
smell📋可维护性问题:复杂度、重复
edge_case🤔未处理的场景:null、空值、并发
architectural💭设计问题:耦合、违反 SRP

评论

支持 Markdown