code-cleanup
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCode Cleanup
代码清理
Post-implementation cleanup of code that is already correct. Prunes the comment noise an AI tends
to add, applies the project's conventions, and simplifies what is needlessly complicated.
Correctness is not this skill's job. It does not hunt for bugs, and it must not "fix" behavior
it thinks is wrong — that is . Everything here preserves behavior.
/changes-review对已正确实现的代码进行事后清理。精简AI通常会添加的冗余注释,应用项目规范,并简化不必要的复杂实现。
正确性并非本技能的职责。它不会寻找Bug,也绝不能“修复”它认为错误的行为——那是的工作。本技能的所有操作都将保留代码原有行为。
/changes-reviewCore Principle
核心原则
A comment stays only if the code cannot carry it and no other artifact can either. The default
for every comment in scope is delete. One survives by earning its line, not by being defensible.
Ask where the sentence belongs before asking whether it is true. A comment competes with the
code itself and with three other artifacts, and it loses to all four:
| What the sentence says | Where it belongs |
|---|---|
| What the code does | The code. Delete the comment. |
| Why it is built this way — the decision, the alternative rejected, the history | The commit message |
| What changed and what a reviewer should look at | The PR body |
| Work still owed, or context that outlives this change | An issue |
| What a reader of this file would get wrong without it | Here. Keep it, at one or two lines. |
Only the last row survives contact with the source. The rows above it are usually real content
filed in the wrong place — surface the text in the report under the destination it belongs to, then
take it out of the code.
Two further removals are not about placement:
- A missing name. A comment that exists because a symbol is vaguely named is a rename, not a comment.
- A fact already stated nearby. Once one comment carries a mechanism, a second comment on another part of that mechanism is duplication — see Phase 2.5.
Be aggressive, and know what aggression means here. It means deleting what does not earn its
place. It does not mean shortening to save space: a surviving comment must still read well and
still be correct, and a compaction that drops a fact or leaves a half-sentence is a worse outcome
than the verbose original it replaced.
只有当代码无法承载信息且其他文档也无法替代时,注释才可以保留。所有范围内的注释默认都要被删除。注释只有证明自己存在的价值才能留存,而非仅仅合理即可。
先判断语句应归属的位置,再判断其是否正确。注释会与代码本身及另外三类文档竞争,且在这四类场景中都会落败:
| 语句描述的内容 | 应存放的位置 |
|---|---|
| 代码的功能 | 代码本身。删除该注释。 |
| 为何采用这种实现方式——决策过程、被否决的方案、历史背景 | commit message |
| 变更内容及评审重点 | PR正文 |
| 待完成工作或超出本次变更范围的上下文 | Issue |
| 阅读当前文件的用户若没有该注释会产生误解的信息 | 此处。保留1-2行注释。 |
只有最后一行的内容可以留在源代码中。上方几行的内容通常是放错位置的有效信息——在报告中指明其应归属的位置,然后从代码中移除。
还有两类移除操作与位置无关:
- 命名缺失。因符号命名模糊而存在的注释应通过重命名符号来解决,而非保留注释。
- 重复信息。若已有一处注释解释了某个机制,另一处针对同一机制不同部分的注释属于重复内容——详见阶段2.5。
要主动精简,但需明确此处“主动”的含义。它指的是删除那些没有存在价值的内容,而非单纯为了节省空间而缩短内容:留存的注释仍需易于阅读且准确,若精简后遗漏了信息或语句不完整,效果反而比冗长的原文更差。
Read Intent First
优先识别意图
- A request about comments ("clean up the comments") → comment work is the whole job. Code changes are allowed only where a cheap rename removes the need for a comment.
- A general "clean this up" → run the full pass: comments, artifacts, conventions, simplify.
- forces the comment-focused mode regardless of phrasing, and never touches code. It disables, without exception: convention loading and fixes, the simplifier pass, rename-to-kill, and quick wins. Comments and docs only. It may still report what it would otherwise have done.
--comments-only - runs everything except the simplifier pass.
--no-simplify
- 针对注释的请求(如“清理注释”)→ 仅处理注释。仅当简单重命名符号即可消除注释需求时,才允许修改代码。
- 一般性的“清理代码”请求→ 执行完整流程:注释处理、文档归档、规范应用、代码简化。
- 参数强制开启仅聚焦注释的模式,绝不修改代码。它会无条件禁用:规范加载与修复、代码简化流程、重命名消除注释操作,以及快速修复。仅处理注释和文档。它仍会报告原本会执行的操作。
--comments-only - 参数会执行除代码简化之外的所有操作。
--no-simplify
Asking the User
询问用户
Every question in this skill is written as options. Use that tool where
the host offers it, or the host's nearest structured-choice equivalent. Where the host has
neither, ask the same question in normal chat as a numbered list of 2–5 options —
recommended first, one short line of description each — and wait for the user to reply
with a number.
AskUserQuestion本技能中的所有问题均以选项形式呈现。若宿主提供该工具则使用它,或使用宿主最接近的结构化选择替代方案。若宿主两者都不支持,则以普通聊天形式提出相同问题,列出2-5个带编号的选项——推荐优先选项,每个选项配一行简短描述——等待用户回复编号。
AskUserQuestionWorkflow
工作流程
Phase 1: Scope
阶段1:范围确定
Step 1: Find project guidelines. Check for comment/doc conventions in:
CLAUDE.md AGENTS.md .cursor/rules/*.md(c) docs/CONTRIBUTING.md docs/STYLE_GUIDE.md .github/CONTRIBUTING.mdHonor anything they say about comment style, JSDoc requirements, or section markers.
Step 2: Resolve the target. In priority order:
- Explicit argument — files, a directory, or a commit ref passed in → use exactly that.
- Uncommitted changes (default) — staged + unstaged:
bash
git diff --name-only HEAD # tracked modifications (staged + unstaged) git ls-files --others --exclude-standard # new untracked files - Last commit — fall back here only when the working tree is clean:
bash
git diff --name-only HEAD~1..HEAD
Announce which scope resolved (e.g. "Cleaning uncommitted changes: 4 files" or "Tree clean —
cleaning last commit : 3 files").
0cccf9dFilter to code files (exclude , , , , , , ,
, ).
*.md*.json*.lock*.yaml*.ymldist/build/*.min.js*.mapStep 3: Decide which comments are in scope. For diff/commit modes, pull the actual hunks
( / ) and consider:
git diff HEADgit show- every comment added or modified by the change, plus
- pre-existing comments in changed files that relate to the changed code (e.g. a doc comment on a function whose body you just edited).
Leave unrelated pre-existing comments elsewhere in the file alone — surgical. For an explicitly
named file, the whole file is in scope.
Step 4: Load the conventions that apply. Skip entirely under .
--comments-onlyAlways load . It is the repo-adaptive half of the pass: read what
the project itself documents, detect the stack, and audit against both. It is what makes this work
on a repo the stack files below do not describe.
references/conventions.mdThe eight stack files carry fixed conventions for one specific frontend stack. Each is gated on
two conditions, and both must hold:
| Reference | Paths | Only when |
|---|---|---|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
The dependency gate is not optional. A path glob alone would load for any
file and rewrite to in a project with no Tailwind, or convert a variant lookup
to without the package installed. Check before loading a stack file; if the
dependency is absent, the file does not apply and its rules are not violations.
tailwind.md.tsxh-4 w-4size-4cvapackage.jsonreact.mdforwardRefThe project's own instructions outrank all of this. If , , or a rules
file found in Step 1 contradicts a reference, follow the project. These are defaults for repos
that have not said otherwise — not a house style to write into someone else's codebase.
CLAUDE.mdAGENTS.md步骤1:查找项目规范。在以下位置检查注释/文档规范:
CLAUDE.md AGENTS.md .cursor/rules/*.md(c) docs/CONTRIBUTING.md docs/STYLE_GUIDE.md .github/CONTRIBUTING.md严格遵循其中关于注释风格、JSDoc要求或章节标记的规定。
步骤2:确定目标范围。按优先级排序:
- 显式参数——传入的文件、目录或提交引用→ 严格使用该范围。
- 未提交变更(默认)——暂存+未暂存:
bash
git diff --name-only HEAD # 已跟踪文件的修改(暂存+未暂存) git ls-files --others --exclude-standard # 新增的未跟踪文件 - 最后一次提交——仅当工作区干净时才回退到此处:
bash
git diff --name-only HEAD~1..HEAD
告知用户确定的范围(例如:“清理未提交变更:4个文件”或“工作区干净——清理最后一次提交:3个文件”)。
0cccf9d筛选出代码文件(排除、、、、、、、、)。
*.md*.json*.lock*.yaml*.ymldist/build/*.min.js*.map步骤3:确定范围内的注释。对于差异/提交模式,提取实际代码块( / )并考虑:
git diff HEADgit show- 本次变更新增或修改的所有注释,以及
- 变更文件中与修改代码相关的原有注释(例如:刚编辑过的函数的文档注释)。
忽略文件中其他无关的原有注释——精准操作。对于显式指定的文件,整个文件都在范围内。
步骤4:加载适用的规范。在模式下完全跳过此步骤。
--comments-only始终加载。它是适配仓库的核心部分:读取项目自身的文档,检测技术栈,并对照两者进行检查。这是本技能能在未被技术栈文件描述的仓库中正常工作的关键。
references/conventions.md八个技术栈文件针对特定前端栈提供固定规范。每个文件的加载需满足两个条件,且必须同时成立:
| 参考文件 | 路径 | 仅当满足以下条件时加载 |
|---|---|---|
| | 依赖中包含 |
| | 依赖中包含 |
| | 依赖中包含 |
| | 依赖中包含 |
| | 依赖中包含 |
| | 依赖中包含 |
| | 存在 |
依赖检查不可省略。仅通过路径通配符会导致在没有Tailwind的项目中加载,并将重写为,或在未安装包的情况下将变量查找转换为。加载技术栈文件前先检查;若依赖不存在,则该文件不适用,其规则也不视为违规。
tailwind.mdh-4 w-4size-4cvapackage.jsonreact.mdforwardRef项目自身的说明优先级最高。若步骤1中找到的、或规则文件与参考文件冲突,遵循项目自身的规定。这些参考文件是未明确说明的仓库的默认规范——并非要写入他人代码库的固定风格。
CLAUDE.mdAGENTS.mdPhase 2: Classify Each Comment
阶段2:分类每个注释
Run every in-scope comment through this table. The first five classes are the AI-noise the skill
exists to remove; a comment that matches none of them still has to earn its line under the Core
Principle before it stays.
| Class | What it looks like | Action |
|---|---|---|
| Restates the code | One-liner narration ( | Remove |
| Design rationale / history | "We do it this way because…", "Captured here because by the time X runs…", "chose this over Y", the story of the decision aimed at a PR reader | Remove from code; surface the text for the commit message |
| Wider context | Describes the change rather than the file: what a reviewer should check, what the surrounding refactor is for, what is deliberately out of scope | Remove from code; surface it for the PR body |
| Duplicate | Restates a mechanism a nearby comment already carries, from a second angle | Remove — keep the one authoritative statement (Phase 2.5) |
| External-context reference | | Strip the reference. If the fact matters, state it inline so the file reads on its own; if it does not, delete the comment. Keep a link only where the context is genuinely unreachable otherwise — an upstream bug tracker for a workaround, a spec section, an RFC |
| Non-obvious behavior / gotcha / hack | Timing dependency, surprising side effect, workaround for an external bug, a constraint you cannot infer from the code | Keep — compact to 1–2 lines, drop the narration |
| Comment compensating for a bad name | The comment exists mainly to explain what a vague symbol means | Rename the symbol (see Phase 3); delete the comment. Under |
| Documentation (JSDoc / docstring / public API) | API-level doc humans rely on | Gentle, not exempt: correct inaccuracies and tighten — cut prose that re-spells the signature or the parameter names. Never gut what a caller cannot get from the type: what it does, what it throws, what it returns |
| AI implementation artifacts | | Remove |
| Misleading / stale | Describes behavior the code no longer has, wrong names, outdated references | Fix if obvious, else flag |
| Markers | | Preserve (flag |
The test for the top two classes: read the code without the comment. If you still understand
what it does, the comment was restating — remove it. If what you lose is why a decision was made
rather than what the code does, that belongs in the commit message, not the source.
Prefix markers — warning, open question, divider — belong to the human,
never to you. Never author one; the user places them by hand. What to do with one that already
exists turns on whose line it is:
// !// ?// *- In pre-existing code — preserve the prefix. The comment text is still judged like any other, but the marker is not yours to remove.
- On a line this change added — drop the prefix and judge the bare comment on its merits.
Exception: keep and match it where the project genuinely uses the convention — ,
CLAUDE.md, or a rules file documents it, or the surrounding untouched code is visibly written that way.AGENTS.md
A left on work this change just finished is an AI implementation artifact, and goes.
One the project or the user placed is a marker, and stays.
// TODO:Test files: a step-label comment that just narrates the next call () is
restatement — remove it. Keep one only where it conveys intent the calls don't (e.g. "most recent,
not stale"). The test name and assertions should carry the rest.
// focus the field将所有范围内的注释对照下表进行分类。前五类是本技能要清除的AI冗余内容;若注释不属于其中任何一类,仍需符合核心原则才能留存。
| 类别 | 特征 | 操作 |
|---|---|---|
| 重复代码含义 | 单行叙述(如 | 移除 |
| 设计依据/历史背景 | “我们这样做是因为……”、“在此处捕获是因为当X运行时……”、“选择此方案而非Y”、面向PR读者的决策过程描述 | 从代码中移除;将内容提取到commit message中 |
| 更广泛的上下文 | 描述变更而非文件本身:评审重点、周边重构的目的、故意排除在范围外的内容 | 从代码中移除;将内容提取到PR正文中 |
| 重复内容 | 从另一个角度重复描述已有注释解释的机制 | 移除——保留唯一权威说明(阶段2.5) |
| 外部上下文引用 | | 移除引用。若信息重要,则内联说明以确保文件可独立阅读;若不重要,则删除注释。仅当上下文确实无法通过其他方式获取时才保留链接——例如上游Bug跟踪器的 workaround、规范章节、RFC |
| 非直观行为/陷阱/临时方案 | 时序依赖、意外副作用、针对外部Bug的 workaround、无法从代码中推断的约束 | 保留——精简为1-2行,删除冗余叙述 |
| 因命名不佳而存在的注释 | 注释主要用于解释模糊符号的含义 | 重命名符号(见阶段3);删除注释。在 |
| 文档(JSDoc / 文档字符串 / 公共API) | 开发者依赖的API级文档 | 温和精简,而非豁免:修正不准确内容并精简——删除重复签名或参数名称的文字。绝不要删除调用者无法从类型中获取的内容:功能、抛出异常、返回值 |
| AI实现残留内容 | 已完成代码上的 | 移除 |
| 误导性/过时内容 | 描述的行为与当前代码不符、名称错误、过时引用 | 若明显则修正,否则标记 |
| 标记 | | 保留(标记 |
前两类的判断标准:不看注释直接阅读代码。若仍能理解代码功能,则该注释属于重复内容——移除。若缺失的是决策原因而非代码功能,则应放在commit message中,而非源代码中。
前缀标记——警告、待解决问题、分隔符——属于用户,而非本技能。绝不要添加此类标记;由用户手动添加。对于已存在的标记,处理方式取决于其归属:
// !// ?// *- 在原有代码中——保留前缀。注释内容仍需像其他注释一样判断,但标记不可移除。
- 在本次变更添加的行上——移除前缀,仅判断注释本身的价值。例外:若项目确实使用该规范——、
CLAUDE.md或规则文件中有说明,或周边未修改的代码明显采用该风格——则保留并匹配前缀。AGENTS.md
已完成工作上遗留的属于AI实现残留内容,应移除。项目或用户添加的属于标记,应保留。
// TODO:// TODO:测试文件:仅叙述下一个调用的步骤标签注释(如)属于重复内容——移除。仅当注释传达了调用无法体现的意图时才保留(例如“最新的,而非过时的”)。测试名称和断言应承载其余信息。
// 聚焦输入框Phase 2.5: Read the survivors together
阶段2.5:整体审阅留存的注释
Phase 2 judges one comment at a time, which is exactly how three individually defensible comments
end up telling one story between them. Before applying anything, read the surviving set as a whole.
- One mechanism, one home. Where two or three comments each explain a part of the same mechanism, keep the explanation once — on the thing all of them exist to serve, usually the field or the declaration rather than any of the functions touching it — and delete the others. The remaining one may grow a line to absorb what was real in them.
- Contradiction. The same rule stated in opposite directions in two places means at least one is stale. Resolve it against the code; never keep both.
- Density is a signal, not a quota. Count added comment lines against added code lines. Past roughly a fifth, look again — not to hit a number, but because in practice that ratio has meant duplication rather than thoroughness. Report both counts either way.
This phase exists because wording-level trimming cannot reach the problem it solves. A pass that
shortens three comments and leaves all three still leaves the reader three places to look and three
places to update, and it is the failure this skill is most often called back to fix.
阶段2逐个判断注释,这正是三个单独合理的注释最终共同讲述一个故事的原因。在应用任何修改前,整体阅读留存的注释集合。
- 一个机制,一个归属地。若两三个注释分别解释同一机制的不同部分,则仅保留一次解释——放在所有注释服务的对象上,通常是字段或声明,而非任何调用它的函数——并删除其他注释。留存的注释可增加一行以吸收其他注释中的有效内容。
- 矛盾内容。同一规则在两处表述相反,意味着至少一处已过时。根据代码内容解决矛盾;绝不要同时保留两者。
- 密度是信号,而非配额。统计添加的注释行数与添加的代码行数之比。超过约五分之一时,需重新审视——并非为了达到某个数值,而是实际上该比例通常意味着重复内容而非全面性。无论如何都要报告这两个计数。
此阶段的存在是因为逐字精简无法解决其针对的问题。若精简三个注释但仍保留全部三个,读者仍需查看三处并更新三处,这正是本技能常被召回修复的问题。
Phase 3: Apply
阶段3:应用修改
Auto-apply. Edit directly — uncommitted changes are the review surface, and shows
exactly what changed. With , produce the Phase 4 report and stop without editing.
git diff--dry-runOrder: remove restatement → pull rationale and wider context out (collect for the report by
destination) → strip external references → de-duplicate per Phase 2.5 → compact gotchas →
rename-to-kill → docs polish → AI artifacts & dead code → quick wins → conventions → flag the
rest. The simplifier runs after all of it, in Phase 3.5.
Convention fixes. Apply only the references that passed both gates in Step 4. Fix what is
mechanical, local, and behavior-preserving — that should be , an
that should be an intersection type, a flat story name missing its group
prefix, a that should be ref-as-prop if the project is on React 19.
h-4 w-4size-4interface X extends YforwardRefTwo things are never auto-applied:
- Anything that ripples past the files in scope — a rename with external callers, a file move
to satisfy the structure rules, a dependency swap like →
@radix-ui/react-tabs.radix-ui - Anything a reference marks report-only, and anything that changes behavior. Some rules in
and
references/conventions.mdare correctness or security checks; they produce findings, never edits.references/kotlin.md
Skipped entirely under .
--comments-onlyRenaming to kill a comment. Skipped under — a rename is a code change.
When a cheap, local rename makes a comment unnecessary, do it and remove the comment. "Cheap" = a single symbol whose every reference you can update in the in-scope
files (a local variable, a private function). Anything heavier — splitting a function into
utilities, reshaping control flow, renaming an exported symbol with external callers — is not
applied; record it as a suggestion in the report instead.
--comments-onlyQuick wins (auto-fix if truly trivial). Skipped under . An obvious missing
return type TS already infers, or an unused import your comment removal orphaned. Leave an
alone unless you can actually run the linter and confirm the rule passes —
guessing that a suppression is stale is how a suppression becomes a build failure.
--comments-onlyeslint-disableSafety rules:
- Never remove /
@ts-ignorewithout understanding why it's there.@ts-expect-error - Never remove without running the linter and confirming the rule passes.
eslint-disablegrants onlyallowed-tools, so on most invocations you cannot — leave it and report it.Bash(git:*) - Never delete /
HACK/FIXME/XXXcomments — flag them.BUG - Never remove license headers or copyright notices.
- Preserve /
// regionand any project-specific markers.// endregion
自动应用。直接编辑代码——未提交变更是评审依据,可准确显示变更内容。使用参数时,生成阶段4的报告但不进行编辑。
git diff--dry-run顺序:移除重复内容→ 提取设计依据和更广泛的上下文(按归属地收集到报告中)→ 移除外部引用→ 按阶段2.5去重→ 精简陷阱注释→ 重命名消除注释→ 优化文档→ 移除AI残留内容和死代码→ 快速修复→ 应用规范→ 标记剩余内容。代码简化在阶段3.5中最后执行。
规范修复。仅应用步骤4中通过两个检查的参考文件规则。修复机械性、局部性且保留行为的内容——将应改为的修复,将应改为交叉类型的修复,将缺失组前缀的扁平故事名称修复,若项目使用React 19则将改为ref作为属性。
size-4h-4 w-4interface X extends YforwardRef两类内容绝不自动应用:
- 影响范围超出当前文件的内容——涉及外部调用者的重命名、为满足结构规则的文件移动、依赖替换(如→
@radix-ui/react-tabs)。radix-ui - 参考文件标记为仅报告的内容,以及任何改变行为的内容。和
references/conventions.md中的部分规则是正确性或安全检查;它们仅生成发现,绝不进行编辑。references/kotlin.md
在模式下完全跳过此步骤。
--comments-only重命名消除注释。在模式下跳过——重命名属于代码修改。当简单的局部重命名可消除注释需求时,执行重命名并删除注释。“简单”指单个符号,且其所有引用都可在范围内的文件中更新(局部变量、私有函数)。任何更复杂的操作——将函数拆分为工具类、重构控制流、重命名带有外部调用者的导出符号——绝不应用;而是作为建议记录在报告中。
--comments-only快速修复(若确实 trivial则自动修复)。在模式下跳过。TS已推断出的明显缺失的返回类型,或因注释删除而孤立的未使用导入。除非能运行linter确认规则通过,否则不要修改——猜测抑制规则已过时会导致构建失败。
--comments-onlyeslint-disable安全规则:
- 若不理解/
@ts-ignore存在的原因,绝不要移除它们。@ts-expect-error - 若不运行linter确认规则通过,绝不要移除。
eslint-disable仅授权allowed-tools,因此大多数情况下无法运行linter——保留并报告它。Bash(git:*) - 绝不要删除/
HACK/FIXME/XXX注释——标记它们。BUG - 绝不要删除许可证头部或版权声明。
- 保留/
// region以及任何项目特定的标记。// endregion
Phase 3.5: Simplifier pass
阶段3.5:代码简化流程
Skipped entirely under , , or . Under the
analysis still runs — the suggestions go in the report and nothing is written.
--comments-only--no-simplify--dry-run--dry-runSimplify code that is more complicated than it needs to be, preserving behavior exactly:
collapse a nested conditional into a guard clause, replace a hand-rolled loop with the obvious
built-in, drop an indirection with one caller, delete a branch that cannot be reached, unwrap a
wrapper that only forwards. Small, local, provable.
Not in scope: anything that changes behavior, anything that needs a test to prove it is safe, and
anything the code is doing deliberately for a reason you cannot see. When in doubt, it is a
suggestion, not an edit.
Whether to ask first turns on one observable signal: did the invocation carry anything beyond
the bare skill name?
- Any argument, flag, or instruction — apply without asking. A scope, a flag, "simplify the parser", "clean this up and tidy the helpers". The caller already said what they want, and a skill invoking this one always passes at least a scope or a flag.
- Nothing at all — ask before applying. A bare , or a bare "clean up the changes" with no further direction.
/code-cleanup
That rule is deliberately mechanical, because "did a human or a skill call me" is not something
you can read at runtime. A skill calling this one must pass at least one argument — a scope,
or if it wants the pass off. A caller that passes nothing gets treated as a user
who typed the bare command, which means it may block on a prompt.
--no-simplifyIf the host cannot prompt interactively at all, do not ask — apply nothing, and report the
simplifications as suggestions.
Ask per Asking the User:
- (Recommended) — N refactors, all behavior-preserving
Apply the simplifications - — list them under Suggested refactors, change nothing
Report them only
Declined, or the host cannot prompt → fall back to the existing Suggested refactors (not
applied) section. Under and the analysis still runs and populates
that section; under the pass does not run at all and the section carries only
the renames and convention fixes it would otherwise have applied.
--no-simplify--dry-run--comments-only在、或模式下完全跳过。在模式下仍会执行分析——建议会放入报告但不进行修改。
--comments-only--no-simplify--dry-run--dry-run简化过于复杂的代码,严格保留原有行为:将嵌套条件转换为守卫子句,用内置方法替换手动实现的循环,删除仅有一个调用者的间接层,删除无法到达的分支,移除仅转发调用的包装器。操作应小而局部,且可证明安全。
不属于范围的内容:任何改变行为的操作、需要测试证明安全的操作、以及代码故意为你无法看到的原因而执行的操作。若有疑问,作为建议而非编辑。
是否先询问用户取决于一个可观察的信号:调用时是否包含技能名称之外的内容?
- 任何参数、标记或指令——直接应用无需询问。例如指定范围、标记、“简化解析器”、“清理代码并整理工具类”。调用者已明确需求,且调用本技能的其他技能至少会传递范围或标记。
- 无任何额外内容——应用前先询问。例如仅输入,或仅输入“清理变更”无进一步说明。
/code-cleanup
该规则是刻意机械化的,因为无法在运行时判断调用者是人类还是其他技能。调用本技能的其他技能必须至少传递一个参数——范围,或若要关闭简化流程则传递。无参数的调用者会被视为输入裸命令的用户,这意味着可能会因提示而阻塞。
--no-simplify若宿主完全无法交互式提示,则不要询问——不应用任何修改,将简化建议放入报告。
按照询问用户的规则提问:
- (推荐)——N个重构,均保留原有行为
应用简化修改 - ——在“建议重构(未应用)”部分列出,不做任何修改
仅报告建议
若用户拒绝,或宿主无法提示→ 回退到现有的**建议重构(未应用)**部分。在和模式下仍会执行分析并填充该部分;在模式下完全不执行该流程,该部分仅包含原本会应用的重命名和规范修复建议。
--no-simplify--dry-run--comments-onlyPhase 4: Report
阶段4:生成报告
undefinedundefinedCleanup: [N files, M comments touched]
清理结果:[N个文件,M个注释被处理]
Scope: uncommitted changes (4 files)
Comment lines: 64 → 28 · added code lines: 201
范围:未提交变更(4个文件)
注释行数:64 → 28 · 新增代码行数:201
Removed
已移除内容
- [count] restated / how-it-works comments
- [count] duplicate explanations, folded into the one that stays
- [count] external references (issue / PR / doc numbers) stripped
- [count] AI artifacts
- [count] dead commented code
- [数量] 重复代码含义/机制说明注释
- [数量] 重复解释,已合并到留存的注释中
- [数量] 外部引用(Issue/PR/文档编号)已移除
- [数量] AI残留内容
- [数量] 已注释的死代码
Compacted
已精简内容
- [count] gotcha comments shortened
- [数量] 陷阱注释已缩短
Renamed (to remove a comment)
重命名(以消除注释)
- →
activeDataContext(file.ts)focusedDataContext
- →
activeDataContext(file.ts)focusedDataContext
Docs
文档优化
- [count] doc comments corrected / tightened
- [数量] 文档注释已修正/精简
Conventions applied
已应用的规范
- forwardRef → ref-as-prop (react.md)
Button.tsx:12 Card.tsx:30→h-4 w-4(tailwind.md)size-4
- forwardRef → ref作为属性 (react.md)
Button.tsx:12 Card.tsx:30→h-4 w-4(tailwind.md)size-4
Simplified
已简化的代码
- nested conditional → guard clause
parse.ts:44 - removed a wrapper that only forwarded to
index.ts:8format()
- 嵌套条件 → 守卫子句
parse.ts:44 - 移除仅转发到
index.ts:8的包装器format()
Belongs in the commit message
应放入commit message的内容
The seed is captured at the toggle's pointer-down because the click blurs the field before the open handler runs. Clearing context on close is the plugin's job.
在切换按钮的pointer-down事件时捕获种子,因为点击会在打开处理程序运行前失去输入框焦点。关闭时清除上下文是插件的职责。
Belongs in the PR body
应放入PR正文的内容
- The change is scoped to the branch of the converter; the surrounding conversion path is deliberately untouched.
Map
- 变更范围限于转换器的分支;周边转换路径故意未修改。
Map
Belongs in an issue
应放入Issue的内容
- still handles the legacy
parse.tsenvelope and nothing in this change needs it — worth an issue, not a comment.v1
- 仍处理旧版
parse.ts信封,本次变更无需此功能——值得创建一个Issue,而非保留注释。v1
Quick wins
快速修复
- removed an import orphaned by a comment deletion
util.ts:3
- 移除因注释删除而孤立的导入
util.ts:3
Suggested refactors (not applied)
建议重构(未应用)
Everything analysed but not edited lands here: declined simplifications, renames with callers
outside scope, convention fixes that ripple past the files in scope, and file moves the structure
rules imply.
- handleDataActivePath does two things — consider splitting focus-tracking from context-push
file.ts:120 - structure rules put this in
Card.tsx— a move, so not appliedcomponents/card/
所有已分析但未编辑的内容都放在此处:被拒绝的简化、影响范围外调用者的重命名、影响范围外文件的规范修复、结构规则建议的文件移动。
- handleDataActivePath承担两项职责——考虑将焦点跟踪与上下文推送拆分
file.ts:120 - 结构规则建议将其放在
Card.tsx——属于文件移动,未应用components/card/
Flagged for review
标记需评审的内容
- FIXME left in place — needs attention
file.ts:456 - comment claims X but code does Y
file.ts:88
The three **Belongs in** sections carry the text taken out of the source, filed where it should have
gone. They are *inputs* to those artifacts, not blocks to be pasted at the end of one.
**Commit message** is the important one: it answers why the code is built the way it is, which is
the first thing a body has to establish, so the commit writer folds it into that opening paragraph.
Write it as prose that can carry that weight — the reason, not a label for it.
**PR body** and **an issue** are handed to whoever writes them. This skill files nothing itself: it
opens no issue and edits no PR. Omit a section that has nothing in it rather than printing an empty
heading.- FIXME已保留——需关注
file.ts:456 - 注释声称X但代码实际执行Y
file.ts:88
三个**应放入**部分包含从源代码中提取的内容,并归档到正确位置。它们是这些文档的**输入**,而非要粘贴到末尾的块。
**commit message**是最重要的:它解释了代码为何采用这种实现方式,这是commit message首先要说明的内容,因此提交者应将其融入开头段落。将其写成能承载该重要性的散文——说明原因,而非仅贴标签。
**PR正文**和**Issue**的内容会交给负责编写它们的人。本技能本身不会创建任何内容:不会打开Issue也不会编辑PR。若某部分无内容则省略该标题,而非打印空标题。Examples
示例
Restated mechanism → remove
重复机制说明 → 移除
The function name already says everything the comment does.
typescript
// Before
// Opens the Content Operator dialog and seeds it with the field captured by
// `captureOperatorSeed` (if any), then clears the pending seed.
export function openOperatorWithSeed(): void { ... }
// After
export function openOperatorWithSeed(): void { ... }函数名称已包含注释的所有信息。
typescript
// 之前
// 打开内容操作器对话框,并使用`captureOperatorSeed`捕获的输入框(若有)填充种子,然后清除待处理的种子。
export function openOperatorWithSeed(): void { ... }
// 之后
export function openOperatorWithSeed(): void { ... }Design rationale → commit message
设计依据 → 放入commit message
typescript
// Before
// CS pushes the focused data field to the operator as its mention target — but
// only while the dialog is open. While closed the field is remembered so the
// toolbar can seed the dialog on open. The seed is captured at pointer-down
// because clicking the toggle blurs the field before the open handler runs.
// Clearing context on close is the plugin's responsibility.
// After (a short orienting note stays; the decision story goes to the commit)
// Focused field is pushed as context only while the dialog is open;
// while closed it is remembered as a seed for the next open.Report → Belongs in the commit message: "Seed captured at pointer-down because the click blurs
the field before the open handler runs; clearing on close is the plugin's job."
typescript
// 之前
// CS将聚焦的数据字段作为提及目标推送给操作器——但仅在对话框打开时有效。关闭时会记住该字段,以便工具栏在打开对话框时填充种子。在pointer-down事件时捕获种子,因为点击切换按钮会在打开处理程序运行前失去输入框焦点。关闭时清除上下文是插件的职责。
// 之后 (保留简短的定位说明;决策过程放入commit message)
// 聚焦字段仅在对话框打开时作为上下文推送;关闭时会被记住作为下次打开的种子。报告 → 应放入commit message的内容:“在pointer-down事件时捕获种子,因为点击会在打开处理程序运行前失去输入框焦点;关闭时清除上下文是插件的职责。”
Gotcha → keep, compacted
陷阱注释 → 保留并精简
typescript
// Before
// Field snapshotted when the user initiates opening the operator dialog (toolbar
// toggle pointer-down), consumed by `openOperatorWithSeed`. Captured before the
// click blurs the field, because by the time the dialog opens focus is gone.
let pendingOperatorSeed: string | null = null;
// After
// Captured at toggle pointer-down, before the click blurs the focused field.
let pendingOperatorSeed: string | null = null;typescript
// 之前
// 用户启动打开操作器对话框(工具栏切换按钮pointer-down)时快照输入框,供`openOperatorWithSeed`使用。在点击失去输入框焦点前捕获,因为对话框打开时焦点已消失。
let pendingOperatorSeed: string | null = null;
// 之后
// 在切换按钮pointer-down事件时捕获,早于点击导致的输入框失焦。
let pendingOperatorSeed: string | null = null;Rename to kill the comment
重命名以消除注释
typescript
// Before
// Live focused data field as a context path, or null. Reflects the field
// focused right now (set on focus, cleared on blur).
let activeDataContext: string | null = null;
// After
let focusedDataContext: string | null = null;typescript
// 之前
// 当前聚焦的数据字段的上下文路径,或null。反映当前聚焦的字段(聚焦时设置,失焦时清除)。
let activeDataContext: string | null = null;
// 之后
let focusedDataContext: string | null = null;Useful transformation → keep, carried by the concrete example
有用的转换 → 保留,通过具体示例体现
typescript
// Before: "Strip the leading dot from the absolute data path (e.g. …)."
// After
// Drop the leading dot: ".itemSet[1].field" -> "itemSet[1].field".typescript
// 之前:“从绝对数据路径中移除前导点(例如……)。”
// 之后
// 移除前导点:".itemSet[1].field" -> "itemSet[1].field"。One mechanism in three places → one home
同一机制在三处出现 → 合并到一处
Each of these is defensible alone, which is why a per-comment pass keeps all three. Together they
are one story told in fragments, and the reader has three places to look and three to update.
typescript
// Before — three adjacent declarations, three angles on the same mechanism
// Set when a modifier rebuilds its own output, so the target's render is dead work.
suppressRender: boolean;
// A modifier rebuilds from `expression` plus its own `renderDice`, so rendering
// the target first produces a string nobody reads.
function createDiscardedRenderContext() { ... }
// Every pool render routes through here, including the suppressed ones, which is
// why the guard lives at the call site rather than in each wrapper.
function renderedPool() { ... }
// After — the whole mechanism sits once, on the field both functions serve
// Set when a modifier rebuilds its own output; the target's render is then dead work.
// Every pool render routes through `renderedPool`, including suppressed ones.
suppressRender: boolean;单独看每一处都合理,这也是逐注释流程会保留全部三处的原因。但它们共同讲述一个碎片化的故事,读者需要查看三处并更新三处。
typescript
// 之前——三个相邻的声明,从三个角度描述同一机制
// 当修改器重建自身输出时设置,因此目标的渲染是无效工作。
suppressRender: boolean;
// 修改器从`expression`加上自身的`renderDice`重建,因此先渲染目标会生成无人读取的字符串。
function createDiscardedRenderContext() { ... }
// 所有池渲染都通过此处路由,包括被抑制的渲染,因此守卫逻辑位于调用点而非每个包装器中。
function renderedPool() { ... }
// 之后——整个机制仅保留一次,放在两个函数都服务的字段上
// 当修改器重建自身输出时设置;此时目标的渲染是无效工作。
// 所有池渲染都通过`renderedPool`路由,包括被抑制的渲染。
suppressRender: boolean;External reference → self-contained, or gone
外部引用 → 改为自包含内容或移除
typescript
// Before
// Workaround for the case described in #412.
// After — the fact is in the file; the issue number bought the reader nothing
// Chrome reports a zero-height box until the font loads, so measure after `ready`.typescript
// 之前
// 针对#412中描述的情况的workaround。
// 之后——信息已包含在文件中;Issue编号对读者无意义
// Chrome在字体加载前会报告零高度盒子,因此在`ready`事件后再测量。Common Mistakes
常见错误
- Deleting a gotcha as if it were restatement. "Captured before the click blurs the field" is why, not what — compact it, don't drop it.
- Keeping rationale "to be safe". If it's the decision story, the commit message is its home; surface it and remove it from the source.
- Over-trimming docs. Public API docs are for humans reading the signature — correct and tighten, never gut.
- Renaming exported symbols with outside callers. That's a refactor, not a rename-to-kill — flag it, don't apply it.
- Trimming a duplicate's wording instead of deleting it. Three shorter comments still telling one story is the same defect, one round later. Phase 2.5 is not optional.
- Keeping a comment because it is true. True is not the bar — being unobtainable from the code, and belonging in this file rather than the commit, the PR, or an issue, is.
- Authoring a warning, a
// !or a// ?prefix. Those are the user's to place.// * - Touching unrelated comments. Stay within the changed code; surgical.
- Drifting into correctness. A simplification that changes behavior is a bug you introduced,
not a cleanup. If the code looks wrong rather than untidy, say so in the report and leave it —
owns correctness.
/changes-review - Imposing the references on a project that disagrees. and the repo's own rules files win. The references are defaults, not a house style to export.
CLAUDE.md
- 将陷阱注释当作重复内容删除。“在点击失焦前捕获”是原因,而非功能——应精简,而非删除。
- 为了“安全”保留设计依据。若属于决策过程,其归属地是commit message;提取内容并从源代码中移除。
- 过度精简文档。公共API文档供阅读签名的开发者使用——修正并精简,绝不要删除核心内容。
- 重命名带有外部调用者的导出符号。这属于重构,而非重命名消除注释——标记它,不要应用。
- 精简重复内容的措辞而非删除。三个较短的注释仍讲述同一个故事,属于同一缺陷。阶段2.5是必须执行的步骤。
- 因注释正确而保留。正确并非标准——标准是无法从代码中获取,且属于当前文件而非commit message、PR或Issue。
- 添加警告、
// !或// ?前缀。这些由用户添加。// * - 修改无关注释。仅处理修改的代码;精准操作。
- 偏离到正确性检查。改变行为的简化是你引入的Bug,而非清理。若代码看起来错误而非混乱,在报告中说明并保留——负责正确性检查。
/changes-review - 将参考规范强加给有不同规定的项目。和仓库自身的规则文件优先级更高。参考规范是默认值,而非要输出的固定风格。
CLAUDE.md
Arguments
参数
| Argument | Description |
|---|---|
| (none) | Clean uncommitted changes; fall back to the last commit if the tree is clean |
| Clean the named file(s) or directory — whole file in scope |
| Clean the files changed in that commit |
| Comment work only; never touch code — no conventions, no simplification |
| Everything except the simplifier pass |
| Report what would change without editing |
| 参数 | 描述 |
|---|---|
| 无 | 清理未提交变更;若工作区干净则回退到最后一次提交 |
| 清理指定文件或目录——整个文件都在范围内 |
| 清理该提交中修改的文件 |
| 仅处理注释;绝不修改代码——不应用规范,不进行简化 |
| 执行除代码简化之外的所有操作 |
| 报告会进行的修改但不执行编辑 |
| ", |