config-gc

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Config GC — Garbage Collection for Claude Code Setups

Config GC — Claude Code配置的垃圾回收工具

Borrowed from runtime garbage collection: periodically scan for objects that are no longer referenced, redundant, expired, or low-value, and reclaim the space. The critical difference: here, collection requires a human in the loop. Never delete autonomously.
借鉴运行时垃圾回收机制:定期扫描不再被引用、冗余、过期或低价值的对象并回收空间。核心区别在于:此处的回收需要人工参与,绝不自动删除任何内容。

When to Activate

激活时机

  • The user asks to clean up, audit, or slim down their Claude Code configuration
  • The user complains about too many skills, noisy hooks, or slow session startup
  • A monthly/periodic config review is due
  • After installing a large skill pack (e.g. this repo), to reconcile overlaps with existing setup
Do NOT activate for: cleaning project source code (that's refactoring), clearing chat history, or uninstalling Claude Code itself.
  • 用户要求清理、审计或精简其Claude Code配置
  • 用户抱怨技能过多、钩子干扰性强或会话启动缓慢
  • 月度/定期配置审查到期时
  • 安装大型技能包(如本仓库)后,用于协调与现有设置的重叠内容
请勿在以下场景激活:清理项目源代码(属于重构范畴)、清除聊天记录或卸载Claude Code本身。

Design Philosophy

设计理念

  1. Append-only configs leak. Skills, memory files, hooks, and permission entries only ever get added. Without periodic review they rot silently.
  2. Regular audits beat one-time purges. Scan every ~30 days, propose a small batch of candidates each time.
  3. Per-channel strategies. Each accumulation type (skills, hooks, permissions, ...) has its own staleness signals — don't apply one rule everywhere.
  4. Soft-delete first. Rename to
    .disabled
    > move to
    ~/.claude/_gc_trash/
    > real deletion. Always keep an undo path.
  5. Forced human-in-the-loop. Every candidate gets its own
    [y/n/skip]
    confirmation. No "yes to all" shortcut.
  6. Keep a log. Every GC run appends to
    ~/.claude/gc_log.md
    : what was touched, why, and how to undo it.
  1. 仅追加式配置会产生泄漏。 Skills、内存文件、hooks和权限条目只会不断增加,若不定期审查会悄然失效。
  2. 定期审计优于一次性清理。 每约30天扫描一次,每次仅提出一小批待处理项。
  3. 分渠道策略。 每种累积类型(skills、hooks、权限等)都有其自身的过期信号——不要一概而论。
  4. 优先软删除。 先重命名为
    .disabled
    > 移至
    ~/.claude/_gc_trash/
    > 再执行实际删除。始终保留撤销路径。
  5. 强制人工参与。 每个待处理项都需要单独确认
    [y/n/skip]
    ,不提供“全选确认”快捷方式。
  6. 保留日志。 每次GC运行都会将操作内容、原因及撤销方法追加至
    ~/.claude/gc_log.md

Scan Channels

扫描渠道

#ChannelPathStaleness / redundancy signals
1Skills
~/.claude/skills/*/
Heavily overlapping names; never triggered in recent transcripts; domain mismatch with the user's actual work; broken or empty SKILL.md
2Memory
~/.claude/**/memory/*.md
+ its index
Multiple index entries for one topic; contents contradicting newer entries; dates that have passed; orphan files missing from the index; sub-100-word fragments that should merge
3Hooks
~/.claude/hooks/
+ settings
Scripts present on disk but referenced by no hook config; old versions superseded by rewrites
4Permissions
permissions.allow
in
settings.json
/
settings.local.json
Duplicate entries; specific entries already covered by a wildcard (e.g.
Bash(git push)
when
Bash(*)
is allowed); one-off grants from past experiments
5MCP servers
~/.claude.json
or project
.mcp.json
Servers that fail to connect; functional duplicates; long-unused
6Scheduled reminders / jobswherever the user keeps themFired one-shots older than 30 days; jobs whose target scripts no longer exist
7Project history
~/.claude/projects/*/
Stale handoff snapshots; session records superseded by newer state
8Runtime caches
cache/
,
file-history/
,
logs/
,
shell-snapshots/
Sort by size and mtime; propose items >30 days old and large
序号渠道路径过期/冗余信号
1Skills
~/.claude/skills/*/
名称高度重叠;近期对话中从未触发;与用户实际工作领域不匹配;SKILL.md损坏或为空
2Memory
~/.claude/**/memory/*.md
+ 其索引
同一主题存在多条索引条目;内容与较新条目矛盾;日期已过期;索引中缺失的孤立文件;应合并的不足100字的片段
3Hooks
~/.claude/hooks/
+ 设置
磁盘上存在但未被任何hook配置引用的脚本;被重写版本取代的旧版本
4Permissions
settings.json
/
settings.local.json
中的
permissions.allow
重复条目;已被通配符覆盖的特定条目(例如已允许
Bash(*)
时的
Bash(git push)
);过去实验中的一次性授权
5MCP servers
~/.claude.json
或项目
.mcp.json
连接失败的服务器;功能重复的服务器;长期未使用的服务器
6定时提醒/任务用户存储它们的任意位置30天前已触发的一次性任务;目标脚本已不存在的任务
7项目历史
~/.claude/projects/*/
过期的交接快照;被较新状态取代的会话记录
8运行时缓存
cache/
,
file-history/
,
logs/
,
shell-snapshots/
按大小和修改时间排序;建议清理超过30天的大文件

Workflow

工作流程

  1. Scan all channels (or the subset the user names). Collect candidates with: path, channel, signal that flagged it, size, last-modified.
  2. Rank by confidence (broken/orphaned = high; merely old = low) and present as a numbered table. Cap each run at ~20 candidates — GC is periodic, not exhaustive.
  3. Confirm one by one. For each candidate show the evidence, then ask
    [y/n/skip]
    . The user can stop at any point.
  4. Soft-delete confirmed items: prefer
    .disabled
    rename for skills/hooks and
    _gc_trash/<date>/
    move for files. Permission entries live in JSON (no comments possible): back up the settings file, record each removed entry verbatim in
    gc_log.md
    , then remove it from the
    allow
    array with
    jq
    . Only hard-delete when the user explicitly asks.
  5. Log the run to
    ~/.claude/gc_log.md
    : timestamp, items actioned, undo instructions.
  6. Report: reclaimed size, channels still healthy, suggested next review date.
  1. 扫描所有渠道(或用户指定的子集)。收集待处理项的信息:路径、渠道、标记信号、大小、最后修改时间。
  2. 排序:按置信度排序(损坏/孤立项=高;仅过期=低),以编号表格形式呈现。每次运行最多处理约20个待处理项——GC是定期执行,而非一次性穷尽清理。
  3. 逐个确认:为每个待处理项展示证据,然后询问
    [y/n/skip]
    。用户可随时停止操作。
  4. 软删除已确认项:对于skills/hooks优先重命名为
    .disabled
    ,对于文件则移至
    _gc_trash/<date>/
    。权限条目存储在JSON中(不支持注释):备份设置文件,将每个移除的条目原封不动记录到
    gc_log.md
    ,然后使用
    jq
    allow
    数组中删除。仅当用户明确要求时才执行硬删除。
  5. 记录日志:将本次运行记录到
    ~/.claude/gc_log.md
    :时间戳、操作的项目、撤销说明。
  6. 生成报告:回收的空间大小、状态良好的渠道、建议的下次审查日期。

Example Scan Commands

扫描命令示例

Orphaned hook scripts (channel 3) — scripts on disk that no hook config references:
bash
for f in ~/.claude/hooks/*; do
  name=$(basename "$f")
  grep -rq "$name" ~/.claude/settings.json ~/.claude/settings.local.json 2>/dev/null \
    || echo "ORPHAN: $f"
done
Redundant permission entries (channel 4) — duplicates, and specific grants shadowed by a wildcard:
bash
jq -r '.permissions.allow[]' ~/.claude/settings.local.json | sort | uniq -d
if jq -e '.permissions.allow | index("Bash(*)")' ~/.claude/settings.local.json >/dev/null; then
  jq -r '.permissions.allow[]' ~/.claude/settings.local.json \
    | grep '^Bash(' | grep -vF 'Bash(*)'
fi
Largest stale caches (channel 8) —
du -k
instead of GNU-only
find -printf
, so it works on macOS/BSD too:
bash
find ~/.claude/file-history ~/.claude/shell-snapshots -type f -mtime +30 \
  -exec du -k {} + 2>/dev/null | sort -rn | head -20
Soft-delete with undo path (capture the date once so the log can't disagree with the directory):
bash
gc_date=$(date +%Y-%m-%d)
mkdir -p ~/.claude/_gc_trash/$gc_date
mv ~/.claude/skills/dead-skill ~/.claude/_gc_trash/$gc_date/
echo "$(date -Iseconds) moved skills/dead-skill -> _gc_trash/$gc_date/ (undo: mv back)" >> ~/.claude/gc_log.md
Removing a confirmed-redundant permission entry (JSON has no comments — back up, log, then edit):
bash
cp ~/.claude/settings.local.json ~/.claude/settings.local.json.bak
echo "$(date -Iseconds) removed permission entry: Bash(git push) (undo: restore from .bak or re-add)" >> ~/.claude/gc_log.md
jq '.permissions.allow -= ["Bash(git push)"]' ~/.claude/settings.local.json.bak \
  > ~/.claude/settings.local.json
孤立的hook脚本(渠道3)——磁盘上存在但未被任何hook配置引用的脚本:
bash
for f in ~/.claude/hooks/*; do
  name=$(basename "$f")
  grep -rq "$name" ~/.claude/settings.json ~/.claude/settings.local.json 2>/dev/null \
    || echo "ORPHAN: $f"
done
冗余权限条目(渠道4)——重复条目,以及被通配符覆盖的特定授权:
bash
jq -r '.permissions.allow[]' ~/.claude/settings.local.json | sort | uniq -d
if jq -e '.permissions.allow | index("Bash(*)")' ~/.claude/settings.local.json >/dev/null; then
  jq -r '.permissions.allow[]' ~/.claude/settings.local.json \
    | grep '^Bash(' | grep -vF 'Bash(*)'
fi
最大的过期缓存(渠道8)——使用
du -k
而非仅GNU支持的
find -printf
,因此可在macOS/BSD上运行:
bash
find ~/.claude/file-history ~/.claude/shell-snapshots -type f -mtime +30 \
  -exec du -k {} + 2>/dev/null | sort -rn | head -20
带撤销路径的软删除(一次性捕获日期,确保日志与目录一致):
bash
gc_date=$(date +%Y-%m-%d)
mkdir -p ~/.claude/_gc_trash/$gc_date
mv ~/.claude/skills/dead-skill ~/.claude/_gc_trash/$gc_date/
echo "$(date -Iseconds) moved skills/dead-skill -> _gc_trash/$gc_date/ (undo: mv back)" >> ~/.claude/gc_log.md
移除已确认冗余的权限条目(JSON不支持注释——先备份、记录日志,再编辑):
bash
cp ~/.claude/settings.local.json ~/.claude/settings.local.json.bak
echo "$(date -Iseconds) removed permission entry: Bash(git push) (undo: restore from .bak or re-add)" >> ~/.claude/gc_log.md
jq '.permissions.allow -= ["Bash(git push)"]' ~/.claude/settings.local.json.bak \
  > ~/.claude/settings.local.json

Anti-Patterns

反模式

  • Bulk approval. Asking "delete all 15? [y/n]" defeats the design. One item, one decision.
  • Hard-deleting on first pass. If there's no
    _gc_trash/
    copy or
    .disabled
    rename, you did it wrong.
  • Treating "old" as "dead". A skill untouched for 60 days may be seasonal (tax season, quarterly reviews). Age is a signal, not a verdict — that's why a human confirms.
  • Cleaning memory by truncation. Merging two contradicting memory files requires reading both and keeping the newer truth, not deleting the longer one.
  • Touching anything outside
    ~/.claude
    (or the project's
    .claude/
    ). Config GC never wanders into source trees.
  • 批量确认:询问“是否删除全部15项?[y/n]”违背设计初衷。应一项一确认。
  • 首次扫描即硬删除:若未创建
    _gc_trash/
    副本或重命名为
    .disabled
    ,则操作有误。
  • 将“过期”等同于“失效”:60天未使用的技能可能是季节性的(如报税季、季度审查)。时间仅为参考信号,而非最终判定——这也是需要人工确认的原因。
  • 通过截断清理内存:合并两个内容矛盾的内存文件需要读取两者并保留较新的正确内容,而非删除较长的文件。
  • 触碰
    ~/.claude
    之外的内容
    (或项目的
    .claude/
    目录外)。Config GC绝不会涉足源代码目录。

Best Practices

最佳实践

  • Run after big additions, not just on a calendar: installing a 50-skill pack is exactly when overlap with existing skills appears.
  • When two skills overlap, prefer disabling the one with the weaker trigger description — it's the one that was probably never firing anyway.
  • Permission cleanup is the highest-value channel per minute spent: redundant allow-entries make security review harder.
  • Keep
    gc_log.md
    forever. It's tiny, and "when did I disable that hook and why" comes up more often than you'd think.
  • 不仅要按计划运行,还要在大量添加内容后运行:安装包含50个技能的技能包时,恰好是与现有技能出现重叠的时刻。
  • 当两个技能重叠时,优先禁用触发描述较弱的那个——它很可能从未被触发过。
  • 权限清理是单位时间价值最高的渠道:冗余的允许条目会增加安全审查的难度。
  • 永久保留
    gc_log.md
    。它占用空间极小,而“我何时以及为何禁用了那个hook”这类问题出现的频率远超预期。

Related Skills

相关技能

  • skill-stocktake
    — audits skill quality; config-gc audits skill existence. Run stocktake on what survives GC.
  • workspace-surface-audit
    — the additive counterpart: recommends what to install. config-gc is the subtractive half of the same lifecycle.
  • configure-ecc
    — after installing skills with it, run config-gc to reconcile overlaps with your pre-existing setup.
  • continuous-learning
    — produces the memory files this skill later audits.
  • security-review
    — pairs well with the permissions channel.
  • skill-stocktake
    — 审计技能的质量;config-gc审计技能的存在性。对GC后保留的技能运行stocktake。
  • workspace-surface-audit
    — 作为补充工具:推荐应安装的内容。config-gc是同一生命周期中的精简环节。
  • configure-ecc
    — 使用它安装技能后,运行config-gc以协调与现有设置的重叠内容。
  • continuous-learning
    — 生成此技能后续审计的内存文件。
  • security-review
    — 与权限渠道配合效果极佳。