用途
scratch-cleanup 是一个智能体技能,用于清理堆积的 .scratch/ 目录。它把 .scratch/ 当作收件箱而不是归档:其中每个文件最终只有三种去向——归档(适合放进 docs/ 的研究内容)、删除(全部工作已完成的事项)或保留(仍未完成的工作,列入报告)。磁盘上的任何改动都需先经用户批准计划。
陈旧阈值由 $ARGUMENTS 天决定,为空时取 30 天。
主要能力
1. 清点
从 .agents/issue-tracker.md 读取追踪器布局(回退到 docs/agents/issue-tracker.md,再回退到本集合中的 setup/issue-tracker.md),并从匹配的 triage-labels.md 读取状态词汇。然后遍历 .scratch/,把每个文件恰好放入一个类别:
- Effort:
.scratch/<slug>/目录,包含 map、spec、decisions、tickets 或 triage 请求文件。较早的事项可能用issues/文件夹代替tickets/,按 tickets 处理。 - Research:发现类文件,默认位于
.scratch/research/下,或任何正文为带引用的发现报告并以 “What this unblocks” 结尾的文件。 - Unclassified:其余一切(wizards、零散笔记、事项之外的问题清单)。
.DS_Store文件视为垃圾:在计划中直接列为删除,无需询问。
对每个文件记录是否被 git 跟踪(git ls-files --error-unmatch <path>)及其最后变更日期(git log -1 --format=%cs -- <path>,未跟踪时用文件 mtime)。完成标准:.scratch/ 下每个文件都有类别、跟踪标记和日期。
2. 判定每个事项
以两种写法之一读取每个文件的状态:YAML frontmatter 中的 status: 字段,或正文顶部附近的旧式 **Status:** / Status: 行。状态为 closed 或 wontfix 角色字符串时视为完成。只有以下三条全部成立,事项才算完成:
- 其中每个文件都已完成:map、每个 decision ticket、spec、每个 build ticket、每个 triage 文件。
- 每个 ticket 引用的提交(状态行、
## Resolution或## Comments中的 7–40 位十六进制 SHA)都存在于默认分支:git merge-base --is-ancestor <sha> <default-branch>。默认分支为去掉远程前缀后的git symbolic-ref --short refs/remotes/origin/HEAD,否则为 main。被引用但非祖先的提交,在通过 squash-merge 或 rebase 合入时仍算在默认分支上,因此判定缺失前需先检查等价性:已合并的 PR 包含它(gh api repos/{owner}/{repo}/commits/<sha>/pulls --jq '.[] | select(.merged_at) | .number')、git cherry <default-branch> <sha> <sha>~1输出带-的行(分支上存在等价补丁),或默认分支上有相同主题的提交(git log <default-branch> --fixed-strings --grep="$(git log -1 --format=%s <sha>)" -1)。git 完全无法解析的 SHA 只走 PR 途径检查。只有所有检查都失败的提交才算缺失。 - 事项内部无自相矛盾:例如 spec 仍是 ready-for-agent 而所有 ticket 都已关闭,或关闭的 ticket 其提交缺失。
不满足第 3 条、或有文件状态无法读取的事项为 mismatched:在计划中列为问题,绝不列为删除。任何文件仍打开的事项为 open。open 事项的最新文件早于阈值时也属陈旧;清除陈旧事项中声称的 claimed-by(认领会话已不存在),但保留其状态不变。完成标准:每个事项都被标记为 done、mismatched 或 open(含陈旧标记)。
3. 计划
为每个类别制定计划:
- Research:在 docs/ 下选择目标位置。主题匹配现有主题文件夹时使用
docs/<topic>/;否则使用docs/research/<same-filename>。两个文件夹都匹配、或都不匹配而主题明显属于尚不存在的主题时,列为问题。查找所有入站链接(全仓库含 .scratch/ 执行rg -n --fixed-strings '<old path>'),以便移动后重写。 - Done 事项:阅读其 spec、map 和已关闭的 decision ticket,找出持久决策:难以逆转、在今天的代码中仍然成立、且理由无处可寻的选择。每条列为一个单行 ADR 候选,然后列出该事项待删除。
- Mismatched 事项:用一行说明矛盾之处以及如何解决。
- Unclassified:每个文件一行,说明看起来像什么,并提出处置建议(归档、删除或保留)。
用一条消息展示计划,按以下顺序分节:File(研究文件移动与链接重写)、ADR candidates(编号,方便用户按编号选择)、Remove(已提交路径)、Remove: cannot recover(未跟踪路径,并注明 git 不保存副本)、Questions(mismatched 事项、不明确的目标位置、未分类文件)、Keep(第 5 步的报告表)。可用时通过 AskUserQuestion 请求批准,否则在聊天中请求。未跟踪文件的删除需单独获得明确同意,与计划其余部分分开。完成标准:用户已对每一节批准、删减或拒绝,并回答了所有问题。
4. 应用
只应用用户批准的内容,按以下顺序:
- 先写 ADR,趁源文件仍存在:按 domain-modeling 技能的格式和位置(单上下文仓库中的
docs/adr/)把每个被选中的候选写成 ADR。 - 归档研究文件:已跟踪文件用
git mv,未跟踪文件用mv,按需创建 docs/ 文件夹;把第 3 步找到的每个入站链接重写为新路径。 - 删除:对已提交的事项和文件执行
git rm -r -- <path>;对已批准的未跟踪文件和.DS_Store执行rm。 - 释放第 2 步发现的陈旧认领。
- 按显式路径暂存每个变更路径(
git add -- <path> …);提交留给用户。
完成标准:rg -n --fixed-strings 找不到任何指向已移动或已删除路径的引用,且 git status --short 只显示已批准的改动。
5. 报告
最后输出留在 .scratch/ 中的所有内容的表格,每个事项或保留文件一行:
| Effort | Open work | Blocked by | Last change | Stale | Next |
|---|---|---|---|---|---|
.scratch/<slug>/ |
未关闭的 ticket 或 decision 文件,按编号 | 未解决的阻塞项,或用户留下未答的问题 | 日期 | yes/no | 推动它前进的技能(/implement <ticket>、/wayfinder <map>、/to-tickets <spec>) |
表格下方各给一行:已归档文件(旧 → 新路径)、已写 ADR、已删除路径、已释放的认领。然后建议对已暂存的改动执行 /commit。
适用场景
适用于开发者在 .scratch/ 中累积了大量研究笔记、事项目录和临时文件,需要定期归档有价值的研究、清理已完成事项、识别仍未完成工作并写 ADR 的仓库维护场景。
限制
该技能假定仓库使用 git;需要相应 issue-tracker 布局和 triage-labels 文件;ADR 格式依赖 domain-modeling 技能;未跟踪文件的删除不可恢复。资料未提供该技能的安装方式与其他平台信息。