Communitygithub.com

持续重构技能套件

一组用于持续检测、提议和执行代码库重构的智能体技能。

持续重构技能套件 是什么?

`Art4/continuous-refactoring` 是一套为 AI 智能体设计的技能套件,专注于对代码库进行持续的、半自动化的重构。它不是一个单一的操作,而是一个包含扫描(`refactor-scan`)、设计(`refactor-design`)、排序(`refactor-prioritize`)、实施(`refactor-implement`)和学习(`refactor-learn`)等多个子技能的编排流程。其主要目标是检测重构机会、跟踪已提议或进行中的工作,并根据上下文(如Git状态、现有Issue、语言工具树)决定下一步行动,从而实现有序、高效且可追溯的重构过程。该套件支持GitHub、GitLab等平台,并具备基于工具链的智能提议能力。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add Art4/continuous-refactoring

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

重构扫描

检测,但不写入。 提议下一步可做的工作,并注意到自上次扫描以来哪些问题已自行解决——从不创建 Issue,也从不替用户做决定。refactor-design 负责为选中的提议创建 Issue;refactor-learn 则根据此技能检测到的结果采取行动。

流程

1. 检查前置条件

  • 没有Git仓库 → 停止本轮扫描,报告情况,不提出任何提议。
  • 存在五个或更多打开的 refactor:candidate 标签的 Issue → 停止,不提出新提议;让现有工作先清理完成。

2. 优先恢复待办工作

读取重构笔记的 bookkeeping.md 中的 Pending candidates 字段(路径:skills/continuous-refactoring/references/refactoring-bookkeeping.md)。如果该字段指定了一个 Issue,表示前一轮的 refactor-design 已为其创建了 Issue,但在遵循合并请求之前被中断。此时直接提议该 Issue 并停止——完成待办工作优先于提出新工作。

3. 检测已关闭/合并的已记录状态

获取已记录的集合——docs/agents/issue-tracker.md 指定了一个原生标签跟踪器(GitHub, GitLab)→ 获取所有打开的 refactor:candidate Issue,并通过跟踪器自身的原生 Issue↔关闭PR 交叉引用(Closes #<n>,即 refactor-implement 步骤5已放置在交付MR上的信息)将每个Issue解析到其关联的拉取请求;如果Issue还没有关联的PR,则此步骤无需处理。否则 → 获取重构笔记的 merge-requests.md 中的每一项。针对每一项,检查外部跟踪器/git:该MR是否仍然打开?该Issue是否仍然打开?

没有 gh/glab(或其他Forge API/令牌)可用 → 回退到仅使用Git进行协调,而不是跳过此步骤(也不要尝试在此处安装 gh/glab——将其缺失视为此回退的精确触发条件):skills/refactor-scan/references/git-only-reconciliation.md。没有远程仓库(git remote -v 为空)→ 使用同一文件的纯本地变体——一个已记录的候选者可能已被人类在纯本地环境中合并或拒绝,遵循 opening-a-merge-request.md 中的“无Forge/远程可用”。

  • 已合并 → 发现:已交付。

  • 未合并即关闭 → 发现:已拒绝——记录关闭评论是否给出了维护者的结构性原因(超出范围的材料)或没有。

  • 仍打开,且有审阅活动(审阅或评论)晚于分支的最后一次提交 → 一个恢复候选者,不是发现——没有人做出任何决定,只是需要再看一次。如果API可用 → 同时根据时间戳读取实际的审阅状态(gh pr view <n> --json reviews,reviewDecision 或等效命令)——不要仅仅因为“有变化”就停止:

    • CHANGES_REQUESTED(请求变更),且未被解决(没有比审阅更新的提交)→ 仍然是恢复候选者,但需要将审阅自身的评论/正文连同分支一起传递——refactor-implement 的步骤1将读取并处理该特定反馈,而不仅仅是重新从头检查分支。
    • 一条评论,或一个 APPROVED(批准)审阅且没有阻塞性反馈 → 执行现有的通用恢复候选者处理;不需要附加其他内容。

    按照步骤2将Pending candidates条目传递出去的相同方式传递它:直接交给 refactor-implement,跳过 refactor-prioritize/refactor-design(它已经有了设计和打开的MR;只应用修复循环——refactor-implement的步骤1已经支持恢复现有分支)。没有API访问(仅Git回退)→ 审阅状态不可用,正如 git-only-reconciliation.md 已记录的那样;此细化不适用于此处。

  • 仍打开,但无任何变化 → 没有发现。

同时检查重构笔记的 out-of-scope/<node>.md 中的每一项,这些项标明了 **Blocked by:** PHP >= X.Y 条件(tooling_tree.py 的 detect_nodes() 在运行时直接报告此信息;手动操作时,对照目标当前的 composer.json require.php/config.platform.php 进行比较)——如果目标的当前PHP版本现在满足此条件,则有一个发现:此拒绝被撤销。没有 Blocked by: 字段,或条件仍未满足 → 永远不是发现。

将所有发现交给 refactor-learn——此技能仅负责检测;它永远不会将任何内容标记为 done/wontfix,也永远不会自行写入重构笔记的 out-of-scope/ 目录。

3b. 检测外部标记的候选者

API可用(非仅Git回退)→ 同时查询那些没有被步骤2的 Pending candidates 条目或步骤3的已记录集合覆盖的打开的 refactor:candidate Issue(一个有关联拉取请求的Issue已经在进行中)。剩下的,就是由人类(或其他进程)直接标记的候选者,此循环从未为其设计或实施过——在正常操作中,套件自身的候选者总是被上述两者之一覆盖,因此无需额外操作来区分“我们的”和“别人的”。将每个候选者作为提议传递出去,与步骤4的工具树提议加入的列表相同——refactor-prioritize 将根据其常规因素对所有提议进行排序;它凭自身能力竞争,不会仅仅因为存在而插队。没有API访问(仅Git回退)→ 完全跳过此步骤,纯Git无法按标签枚举Issue。

4. 提议工具树节点

如果步骤2已经提出了一个待办候选者,则跳过此步骤。

运行 python3 skills/refactor-scan/references/tooling_tree.py <target-repo> 并读取JSON的 next 字段——真实的、当前未被阻塞的集合,已排除被拒绝的节点(重构笔记 out-of-scope/<node>.md 中已有的条目),照单全收,无论有多少个条目。注意是 next,不是 roadmap(roadmap是前瞻模拟,不是今天真实可选的)。同时读取 withheld:那些本来应该在 next 中,但等待一个未决定的推荐父节点的节点——每个条目指明了等待哪个/哪些父节点。没有 python3,或不允许执行 → 使用 skills/refactor-scan/references/tree-walk-prompt.md 中的提示({N}=all)分派一个子智能体——它将手动遍历相同的树文档(首先读取重构笔记的 bookkeeping.md 中的 Fulfilled nodes 以跳过重新推导缓存状态,跳过任何有超出范围条目的节点);没有子智能体机制 → 自己内联执行其步骤。

  • 普通工具节点(loop-config 和语言特化节点,例如 skills/refactor-scan/references/php-tooling-tree.md)——通过它们的名称(绝不是原始slug)提议;每个节点已在其树文档中完全指定。
  • structural-scan——仅在每一个具有指向它的 resolved 边的节点都已解决(已满足,或在重构笔记的 out-of-scope/ 下被明确拒绝)时才提议:通用根目录下的 editorconfig,加上活动语言特化自身的聚合节点(PHP:php-structural-scan),而聚合节点本身又在其每一个已解决的父节点都解决后才解决(skills/refactor-scan/references/tooling-tree.md)。只有 structural-scan 会以这种方式被提议——php-structural-scan 纯粹是管道,永远不会成为候选者。提议它仅仅是命名它;代码库遍历发生在 refactor-design 中,仅针对实际被选中的节点。
  • 未识别到语言树:structural-scan 仍然等待 editorconfig,即通用根节点的叶子节点——不能仅仅因为没有特定语言的树适用就立即提议。

输出

由编排器清晰地传递下去:

  • 如果某前置条件阻止了本次扫描,则报告哪个前置条件——本次扫描下面的内容均不适用。
  • 发现(可能为空)→ 交给 refactor-learn。
  • 一个恢复候选者(如果有检测到)→ 直接交给 refactor-implement,绕过 refactor-prioritize/refactor-design。
  • 提议——仅限待办候选者,或者当前所有未被阻塞节点的名称(绝不是slug,不设上限)加上步骤3b中的任何外部标记的候选者,或者为空 → 交给 refactor-prioritize。包含所有当前未被阻塞的节点(所需父节点已满足、未被拒绝,且所有推荐父节点已决定)——绝不是按优先级截断的子集。同时,列出每个 withheld 节点及其正在等待的父节点(例如:“Rector: Type Coverage Set — 等待:PHP CS Fixer”)。

完成标准

发现(如果有)已交给 refactor-learn,恢复候选者(如果有)已直接交给 refactor-implement,提议(如果有)已交给 refactor-prioritize——或者有前置条件阻止了本次扫描并且报告指明了是哪个。绝不将一个节点与 structural-scan 之后的条目放在同一个列表中。

相关技能