关于 omc-doctor
用于诊断和修复 OMC 安装问题的技能,面向 Claude Code 环境维护者。它检查插件版本、设置文件、旧版钩子和相关脚本,并依据来源与内容核验是否可安全清理。
主要功能
- 01检查已安装及最新插件版本
- 02扫描配置中的旧版钩子
- 03核验脚本来源与内容指纹
- 04检查旧版 Bash 钩子脚本
- 05检查 CLAUDE.md 管理设置
适用场景
- 01排查插件未安装或版本过旧
- 02识别可能重复的旧版钩子
- 03判断脚本是否应交由人工审查
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ yeachan-heo/ oh-my-claudecode --skill omc-doctor安装后在 Claude Code 中输入/omc-doctor确认已加载。
附带文件node-hook-fingerprints.json
详细介绍
Doctor Skill
注意:当设置了 CLAUDE_CONFIG_DIR 环境变量时,本指南中的所有 ~/.claude/... 路径都会遵循该变量。
任务:运行安装诊断
你是 OMC Doctor——诊断并修复安装问题。
第 1 步:检查插件版本
# Get installed and latest versions (cross-platform)
node -e "const p=require('path'),f=require('fs'),h=require('os').homedir(),d=process.env.CLAUDE_CONFIG_DIR||p.join(h,'.claude'),b=p.join(d,'plugins','cache','omc','oh-my-claudecode');try{const v=f.readdirSync(b).filter(x=>/^\d/.test(x)).sort((a,c)=>a.localeCompare(c,void 0,{numeric:true}));console.log('Installed:',v.length?v[v.length-1]:'(none)')}catch{console.log('Installed: (none)')}"
npm view oh-my-claude-sisyphus version 2>/dev/null || echo "Latest: (unavailable)"
诊断:
- 如果未安装任何版本:CRITICAL - 插件未安装
- 如果 INSTALLED != LATEST:WARN - 插件已过时
- 如果存在多个版本:WARN - 缓存陈旧
第 2 步:检查设置文件中的遗留 Hook
读取配置文件级别的 ${CLAUDE_CONFIG_DIR:-~/.claude}/settings.json 以及主工作目录的 .claude/settings.json,然后解析 Claude Code 可能读取的每个项目本地设置文件,再检查 hook。在普通检出中,检查仓库根目录的 .claude/settings.local.json。在链接的 Git worktree 中,检查主检出根目录的 .claude/settings.local.json,而不仅仅是链接 worktree 中的文件;使用 git worktree list --porcelain 识别主检出。在 Windows 上,以及每当 Claude Code 将本地文件与共享的 .claude/settings.json 放在一起时,检查该共享设置文件旁边的 .claude/settings.local.json,包括在 worktree 中。还要检查 Claude Code 2.1.211 之前的版本遗留在任何起始目录中的 .claude/settings.local.json;Claude Code 仍可能将其与根文件一起读取。对相同路径去重。如果无法解析或读取主检出根目录或任何适用的本地设置文件,则将设置和脚本引用视为不确定,并且不要移除 hook 或脚本。检查任何适用文件是否具有 "hooks" 键,其中包含如下条目:
bash ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/hooks/keyword-detector.shbash ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/hooks/persistent-mode.shbash ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/hooks/session-start.shbash ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/hooks/stop-continuation.shbash ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/hooks/silent-auto-update.sh
还要识别活动配置目录的 hooks/ 文件夹下的独立 Node hook 注册:名为 keyword-detector、persistent-mode、session-start、session-end、pre-tool-use、post-tool-use、post-tool-use-failure、code-simplifier 或 stop-continuation 的 .mjs 文件。对于历史名称 keyword-detector、persistent-mode、session-start 和 stop-continuation,.cjs 和 .js 变体同样是遗留的。例如,node "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/hooks/keyword-detector.mjs" 是一个遗留注册。在 Windows 上,将诸如 node "%USERPROFILE%\.claude\hooks\keyword-detector.mjs" 和 %CLAUDE_CONFIG_DIR%\hooks\<filename>(或其展开后的绝对等价形式)这类使用反斜杠分隔符的路径,识别为同一活动配置目录。仅匹配从该目录使用 node 调用的确切列出的文件名;不要匹配插件根目录命令或其他目录中名称相似的脚本。
仅当命令是对确切一个所列文件的普通直接调用时,才是自动修复候选:bash <确切的 .sh 路径>、node <确切的 Node 路径>,或目标具有执行权限时的确切可执行脚本路径本身(例如 $HOME/.claude/hooks/keyword-detector.sh)。任何形式都不得包含额外参数、shell 操作符或其他命令。如果命令仅仅提及该路径、添加了自定义行为(例如 bash legacy.sh && run-my-check),或无法明确解析,则报告以便手动清理,并保持 hook 对象不变。
在将独立注册判定为重复项之前,请按照运行时的优先级顺序解析插件启用状态:首先是受管设置和命令行设置(只读),然后是在其之上解析出的所有适用的项目本地设置文件,然后是主工作目录的 ./.claude/settings.json,最后是 ${CLAUDE_CONFIG_DIR:-~/.claude}/settings.json。在适用时,纳入主检出、Windows 并行以及旧版启动目录的本地路径。对于根本地文件与 2.1.211 之前的启动目录文件之间的重复键,根本地值优先;永远不要忽略生效的本地文件中的 false,也不要回退到项目/配置文件中的 true。第一个明确提及任何受支持的 OMC ID 的作用域起决定作用;未提及的作用域是透明的。受支持的 marketplace ID 为 oh-my-claudecode、oh-my-claudecode@omc 和 oh-my-claudecode@oh-my-claudecode。当当前会话从 --plugin-dir、--plugin-url 或 CLAUDE_CODE_PLUGIN_DIRS 等内联来源加载 OMC 时,仅当活动根的 .claude-plugin/plugin.json 具有 "name": "oh-my-claudecode" 且会话来源确认该根已加载后,才额外考虑 oh-my-claudecode@inline。将该内联插件视为会话期间处于活动状态,除非其清单设置了 "defaultEnabled": false 或某个适用的设置来源将其禁用;一个明确适用的 true 会覆盖清单默认值。CLAUDE_PLUGIN_ROOT 只是一个定位符,并非插件已启用的证明;一个明确生效的 false 始终会阻止自动移除。在每个作用域内,enabledPlugins 是规范来源,仅当 enabledPlugins 未提及任何受支持的 OMC ID 时,才查阅旧版 plugins。因此,规范来源中的 false 会覆盖过时的旧版 true,而较高优先级的 false 会覆盖任何较低优先级的 true。如果适用的本地来源相互冲突且无法确定生效值、获胜字段中的受支持 ID 相互冲突、相关文件无法读取或格式错误,或者无法确定任何生效的启用结果,则将插件活动视为不确定,不要自动移除。以只读方式检查活动根的每个 hook 来源:可选的 .claude-plugin/plugin.json hooks 字段接受一个路径、一个内联 hooks 对象,或一个混合路径与内联对象的数组;相对于插件根解析声明的文件路径,并在存在时纳入 hooks/hooks.json。格式错误、无法读取或无法解析的已声明来源会使事件归属变得不确定。仅凭缓存的插件版本是不够的。还要解析独立脚本文件,并将其字节或 SHA-256 与该确切文件名的随附 OMC 载荷进行比较;对于历史 .sh 文件,使用下面的带版本指纹。仅名称或路径匹配并不能证明归属。如果插件处于非活动状态、不提供该事件、不存在载荷或指纹、目标无法读取,或内容不同,则将该条目视为可能属于用户所有,不要建议移除。
对于已知的独立载荷,除了验证载荷身份外,还要验证预期的插件事件。已知的 OMC 文件名到事件的映射为:
| 独立载荷基名 | 规范插件事件 |
|---|---|
keyword-detector | UserPromptSubmit |
session-start | SessionStart |
session-end | SessionEnd |
pre-tool-use | PreToolUse |
post-tool-use | PostToolUse |
post-tool-use-failure | PostToolUseFailure |
persistent-mode、stop-continuation、code-simplifier | Stop |
对于历史载荷,需从该版本的受信清单或安装程序来源验证其事件映射;若无法获取,则留待人工审查。活动插件必须在注册的事件下提供该载荷的规范或经专门验证的等效处理程序,且该处理程序必须替换该载荷的行为。仅仅找到该事件的任意插件处理程序是不够的。例如,注册在 Stop 下的 session-start 脚本即使活动插件定义了不相关的 Stop 处理程序,也不属于重复。如果事件或行为等价性不确定,则保留该 hook 和脚本。 |
已追踪的历史 OMC Bash hook 载荷指纹(SHA-256)如下:
keyword-detector.sh:abe4dd5e4b16231060166264d271a51e781f08a31c6aa402b26976f9c40d424e(96266316)、748463911b2a8b7fffed51137c9731c962b656d490a1e4b27ef7ab10dbbbaff5(3a02feb1)、1eaced21774916c31bec5b149a87009d014ffd8027ecf8e9d6ae6a36bdd79a40(bef486f1)persistent-mode.sh:c131c6846573f0f69b6e39aed1e6db8f05279131a8976f604c1511a46f564ce5(96266316)、219e50bf42b7a7a0e52fb142844dce21faca7c327d9acf346fa70f074ac982ac(3a02feb1)、02f4d0d63a9ce092fe5be02ce6e79f275710b773d4b8d75ff33f272540451eff(bef486f1)session-start.sh:d87571c326c43cc43b6948aca661a9616faa6943cfe1d1131f482bd30f638134(96266316)、a9607c64a14d9f8e9fa990b9f38879ef095d85652f548b1232e28d14641214eb(3a02feb1)、cf7aa2b008829784c8942766c3f00d348ef33a1aab66dd3f96536e95560fd56b(bef486f1)stop-continuation.sh:f74deb67479c7861b0966bc959ffd3917152b8872ac83d9243a03c7cb707b51f(96266316)
对于 silent-auto-update.sh 或历史 .js/.cjs 变体,没有可用的已追踪 OMC 载荷指纹。将这些文件视为归属不确定;不要自动移除它们的 hook 注册或文件。
对于 Node hooks,需与活动插件载荷、位于 ${CLAUDE_CONFIG_DIR:-~/.claude}/plugins/cache/omc/oh-my-claudecode/<version>/ 下的任何已验证保留包,以及相邻的 node-hook-fingerprints.json 索引进行比对。该索引记录了 templates/hooks/**/*.mjs 下每个随附 Node 模块的 SHA-256 指纹及其确切的稳定发布标签来源,包括 hook 辅助程序;按载荷路径搜索,仅检查该区块,而不要加载整个索引。如果该索引缺失、格式错误或没有匹配的指纹,则将该条目留待人工审查。保留以下额外的受信历史 keyword-detector.mjs 指纹,它们来自未必由发布标签代表的提交:22d612620f54f360797e42fe608bf7f98155b92a3b0bba187fd89e216395d65a(fb125b37)、180fc09840baa8ada1661bcc5a13821c9ca802f43ac52cb4e517ca2cba75838a(387956a4)和 71a01806c1b0e29d8e553797de3900b7172654091980ae644d74e5e9291b8af2(0b46a595)。
诊断:
- 如果直接命令被验证为 OMC 所有,且活动插件在注册的事件下提供了该载荷的规范或经专门验证的等效处理程序:CRITICAL - 重复的遗留 hook
- 如果复合命令或含义不明确的命令提到了遗留路径:WARN - 需要人工清理;切勿自动移除
- 如果插件未激活、不提供该事件,或无法验证归属:WARN - 独立 hook 可能处于活动状态或归用户所有;不要建议移除
步骤 3:检查遗留 Bash Hook 脚本
ls -la "${CLAUDE_CONFIG_DIR:-$HOME/.claude}"/hooks/*.sh 2>/dev/null
诊断:
- 如果所列脚本存在,仅当活动插件在注册的事件下提供了该载荷的规范或经专门验证的等效处理程序,且该文件与随附载荷或历史指纹匹配时,才称其为重复;否则将归属标记为未知,或将其视为活动的独立 hook。
步骤 4:检查 CLAUDE.md
首先检查是否已禁用 CLAUDE.md 管理。读取 ${CLAUDE_CONFIG_DIR:-~/.claude}/.omc-config.json;只有明确设置 "claudeMdEnabled": false 才会禁用管理(文件缺失、键缺失或其他任何值均表示已启用)。
# Check if the user opted out of global CLAUDE.md management (cross-platform; expands ~ in CLAUDE_CONFIG_DIR like getClaudeConfigDir)
node -e "const p=require('path'),f=require('fs'),h=require('os').homedir(),c=(process.env.CLAUDE_CONFIG_DIR||'').trim(),d=!c?p.join(h,'.claude'):c==='~'?h:/^~[/\x5c]/.test(c)?p.join(h,c.slice(2)):c;let off=false;try{off=JSON.parse(f.readFileSync(p.join(d,'.omc-config.json'),'utf8')).claudeMdEnabled===false}catch{};console.log(off?'CLAUDE.md management disabled by claudeMdEnabled: false':'CLAUDE.md management enabled')"
只有当探测结果精确打印出 CLAUDE.md management enabled 时,才继续进行以下 CLAUDE.md 检查。
- 如果打印出
CLAUDE.md management disabled by claudeMdEnabled: false,请将该行报告为 INFO,跳过本步骤的其余内容以及“修复:缺失/过期的 CLAUDE.md”修复,并且绝不要创建或覆盖CLAUDE.md或CLAUDE-omc.md。 - 如果未打印出上述任一行,或命令执行失败(例如
node不在PATH中,步骤 5 会对此进行诊断),请报告 WARN - 无法检查claudeMdEnabled退出选项,跳过本步骤的其余内容以及“修复:缺失/过期的 CLAUDE.md”修复,并且绝不要创建或覆盖CLAUDE.md或CLAUDE-omc.md。
# Check if CLAUDE.md exists
ls -la "${CLAUDE_CONFIG_DIR:-$HOME/.claude}"/CLAUDE.md 2>/dev/null
# Check for OMC markers ( is the canonical marker)
grep -q "" "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/CLAUDE.md" 2>/dev/null && echo "Has OMC config" || echo "Missing OMC config in CLAUDE.md"
# Check CLAUDE.md (or deterministic companion) version marker and compare with latest installed plugin cache version
node -e "const p=require('path'),f=require('fs'),h=require('os').homedir(),d=process.env.CLAUDE_CONFIG_DIR||p.join(h,'.claude');const base=p.join(d,'CLAUDE.md');let baseContent='';try{baseContent=f.readFileSync(base,'utf8')}catch{};let candidates=[base];let referenced='';const importMatch=baseContent.match(/CLAUDE-[^ )]*\\.md/);if(importMatch){referenced=p.join(d,importMatch[0]);candidates.push(referenced)}else{const defaultCompanion=p.join(d,'CLAUDE-omc.md');if(f.existsSync(defaultCompanion))candidates.push(defaultCompanion);try{const others=f.readdirSync(d).filter(n=>/^CLAUDE-.*\\.md$/i.test(n)).sort().map(n=>p.join(d,n));for(const o of others){if(candidates.includes(o)===false)candidates.push(o)}}catch{}};let claudeV='(missing)';let claudeSource='(none)';for(const file of candidates){try{const c=f.readFileSync(file,'utf8');const m=c.match(//i);if(m){claudeV=m[1];claudeSource=file;break}}catch{}};if(claudeV==='(missing)'&&candidates.length>0){claudeV='(missing marker)';claudeSource='scanned deterministic CLAUDE sources';};let pluginV='(none)';try{const b=p.join(d,'plugins','cache','omc','oh-my-claudecode');const v=f.readdirSync(b).filter(x=>/^\\d/.test(x)).sort((a,c)=>a.localeCompare(c,void 0,{numeric:true}));pluginV=v.length?v[v.length-1]:'(none)';}catch{};console.log('CLAUDE.md OMC version:',claudeV);console.log('OMC version source:',claudeSource);console.log('Latest cached plugin version:',pluginV);if(claudeV==='(missing)'||claudeV==='(missing marker)'||pluginV==='(none)'){console.log('VERSION CHECK SKIPPED: missing CLAUDE marker or plugin cache')}else if(claudeV===pluginV){console.log('VERSION MATCH: CLAUDE and plugin cache are aligned')}else{console.log('VERSION DRIFT: CLAUDE.md and plugin versions differ')}"
# Check companion files for file-split pattern (e.g. CLAUDE-omc.md)
find "${CLAUDE_CONFIG_DIR:-$HOME/.claude}" -maxdepth 1 -type f -name 'CLAUDE-*.md' -print 2>/dev/null
while IFS= read -r f; do
grep -q "" "$f" 2>/dev/null && echo "Has OMC config in companion: $f"
done < <(find "${CLAUDE_CONFIG_DIR:-$HOME/.claude}" -maxdepth 1 -type f -name 'CLAUDE-*.md' -print 2>/dev/null)
# Check if CLAUDE.md references a companion file
grep -o "CLAUDE-[^ )]*\.md" "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/CLAUDE.md" 2>/dev/null
诊断:
- 如果 CLAUDE.md 缺失:CRITICAL - CLAUDE.md 未配置
- 如果在 CLAUDE.md 中找到 ``:OK
- 如果在伴随文件中找到 ``(例如
CLAUDE-omc.md):OK - 检测到文件拆分模式 - 如果 CLAUDE.md 或任何伴随文件中都没有 OMC 标记:WARN - CLAUDE.md 已过期
- 如果确定性 CLAUDE 源扫描(基础文件 + 引用的伴随文件)中缺少
OMC:VERSION标记:WARN - 无法验证 CLAUDE.md 是否为最新版本 - 如果
CLAUDE.md OMC version!=Latest cached plugin version:WARN - 检测到版本不一致(运行omc update或omc setup)
步骤 5:检查 Ralph 运行时前置条件
Ralph 是由 Agent 驱动的持久化循环,而不是编译后的程序:它唯一严格的运行时前置条件是用于执行 OMC 钩子脚本(persistent-mode.mjs、keyword-detector.mjs)的 Node 运行时,以及用于存储 .omc/state/ 状态文件(例如 ralph-state.json)的可写配置目录。
node --version || echo "Node for Ralph: MISSING"
mkdir -p "${CLAUDE_CONFIG_DIR:-$HOME/.claude}" 2>/dev/null
touch "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/.omc-write-probe" 2>/dev/null && rm -f "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/.omc-write-probe" && echo "Config dir writable" || echo "Config dir NOT writable"
诊断:
- 如果 Node 可运行并输出版本号:OK - Ralph 运行时前置条件已满足
- 如果缺少
node或执行失败:CRITICAL - 没有 Node,OMC 钩子和 Ralph 无法运行(请访问 https://nodejs.org 获取安装程序;nvm/fnm 用户需要确保非交互式 shell 的PATH中包含 Node) - 如果配置目录不可写:WARN - 在配置目录可写之前,Ralph 状态持久化将失败
步骤 6:检查过期的插件缓存
# Count versions in cache (cross-platform)
node -e "const p=require('path'),f=require('fs'),h=require('os').homedir(),d=process.env.CLAUDE_CONFIG_DIR||p.join(h,'.claude'),b=p.join(d,'plugins','cache','omc','oh-my-claudecode');try{const v=f.readdirSync(b).filter(x=>/^\d/.test(x));console.log(v.length+' version(s):',v.join(', '))}catch{console.log('0 versions')}"
诊断:
- 如果版本数 > 1:WARN - 存在多个缓存版本(建议清理)
步骤 7:检查通过 Curl 安装的旧版内容
检查通过 curl 安装的旧版 Agent、命令和技能(插件系统推出之前)。 重要:仅标记名称与插件实际提供内容相符的文件。不要标记与 OMC 无关的用户自定义 Agent、命令或技能。
# Check for legacy agents directory
ls -la "${CLAUDE_CONFIG_DIR:-$HOME/.claude}"/agents/ 2>/dev/null
# Check for legacy commands directory
ls -la "${CLAUDE_CONFIG_DIR:-$HOME/.claude}"/commands/ 2>/dev/null
# Check for legacy skills directory
ls -la "${CLAUDE_CONFIG_DIR:-$HOME/.claude}"/skills/ 2>/dev/null
诊断:
- 如果
~/.claude/agents/存在且包含名称与插件 Agent 相符的文件:WARN - 旧版 Agent(现由插件提供) - 如果
~/.claude/commands/存在且包含名称与插件命令相符的文件:WARN - 旧版命令(现由插件提供) - 如果
~/.claude/skills/存在且包含名称与插件技能相符的文件:WARN - 旧版技能(现由插件提供) - 如果存在名称与插件内容不符的自定义文件:OK - 这些是用户自定义内容,不要标记
已知插件 Agent 名称(检查 agents/ 中是否有以下文件):
architect.md、document-specialist.md、explore.md、executor.md、debugger.md、planner.md、analyst.md、critic.md、verifier.md、test-engineer.md、designer.md、writer.md、qa-tester.md、scientist.md、security-reviewer.md、code-reviewer.md、git-master.md、code-simplifier.md
已知插件技能名称(检查 skills/ 中是否有以下名称):
ai-slop-cleaner、ask、autopilot、cancel、configure-notifications、deep-interview、deepinit、external-context、hud、omc-doctor、omc-setup、plan、project-session-manager、ralph、ralplan、release、skill、team、visual-verdict、wiki
已知插件命令名称(检查 commands/ 中是否有以下文件):
deepsearch.md
报告格式
运行所有检查后,输出报告:
## OMC Doctor Report
### Summary
[HEALTHY / ISSUES FOUND]
### Checks
| Check | Status | Details |
|-------|--------|---------|
| Plugin Version | OK/WARN/CRITICAL | ... |
| Legacy Hooks (settings.json) | OK/WARN/CRITICAL | ... |
| Legacy Scripts (~/.claude/hooks/) | OK/WARN | ... |
| CLAUDE.md | OK/INFO/WARN/CRITICAL | ... |
| Ralph Runtime Prerequisites (Node, config dir) | OK/CRITICAL | ... |
| Plugin Cache | OK/WARN | ... |
| Legacy Agents (~/.claude/agents/) | OK/WARN | ... |
| Legacy Commands (~/.claude/commands/) | OK/WARN | ... |
| Legacy Skills (~/.claude/skills/) | OK/WARN | ... |
### Issues Found
1. [Issue description]
2. [Issue description]
### Recommended Fixes
[List fixes based on issues]
自动修复(经用户确认后)
如果发现问题,请询问用户:“是否要我自动修复这些问题?”
如果用户同意,请应用修复。对于每个受影响的配置文件(包括配置文件级、项目级或项目本地设置文件),仅凭对这个一般性问题的同意,不足以授权移除钩子:请展示完全匹配的钩子对象,以及将保留的非 OMC 条目/组,然后就这项具体变更征求明确确认。提案中应包含所有适用的项目本地文件,包括存在时的主检出目录、Windows 并列目录和旧版起始目录文件;更改主检出目录的本地文件会影响与其关联的工作树。写入前,请确认目标是常规非符号链接文件。在原文件旁创建带时间戳的备份,并使用独占、禁止跟随符号链接的语义(例如,使用 wx 打开),不得覆盖现有路径。备份文件的权限不得比源文件更宽松(例如,源文件权限为 0600 时使用 0600,并保留任何更严格的模式或 ACL);不要依赖进程 umask 或默认文件模式。通过同目录下独占且禁止跟随符号链接的临时文件写入替换内容,并以原子方式替换,同时保留原始模式和限制性 ACL,或应用更严格的保护。在 Windows 上,使用适用于该平台的操作保留源 ACL。如果无法确保备份或替换文件的权限不比原文件宽松,则保持设置文件不变,且不要执行清理。绝不编辑受管设置或 MDM/服务器策略。如果没有匹配的旧版条目,则保持文件不变。
修复:settings.json 中的旧版钩子
对于每个受影响的配置文件(包括配置文件级、项目级或项目本地设置文件):
- 仅当第 2 步的所有检查均通过时,才移除钩子:命令是纯粹的直接调用(仅当目标具有执行权限时,才包括直接可执行文件路径形式);活动插件在注册的事件下提供与该载荷规范或经专门验证的等效处理程序;且目标文件与已发布或可信的版本化 OMC 载荷相匹配。即使同一事件下的处理程序实现了不相关的行为,也不符合条件。不得仅因其他脚本位于
hooks/目录下、属于插件根目录命令,或是其他目录下的同名脚本,就将其匹配。 - 仅从
hooks.<event>[].hooks[]数组中移除这些匹配的对象。保留所有未匹配的钩子对象,以及仍包含钩子的所有匹配器组,包括用户和第三方钩子。如果命令是复合命令或含义不明确,则保持不变,并报告以便手动清理。如果移除匹配对象后,某个匹配器组不再包含钩子,则移除该空组;如果没有剩余组,则移除事件键;如果没有剩余事件,则移除顶层"hooks"键。其他所有设置保持不变。
修复:旧版脚本文件
删除任何脚本前,请检查技能和子代理 frontmatter、已启用的插件清单以及设置来源中活动的会话范围钩子引用。技能 frontmatter 钩子在调用后会在本次会话剩余时间内保持活动;子代理 frontmatter 钩子在该子代理运行期间保持活动。请检查每个活动技能和运行中子代理的源 frontmatter,查找引用候选脚本的命令。如果某个活动钩子引用该脚本,则在该技能或子代理不再活动之前保留脚本,之后重新检查引用。如果无法明确枚举或读取活动技能/子代理的来源,则保留该脚本。
此外,还要枚举每个已启用或已加载的插件根目录,包括通过 --plugin-dir、--plugin-url 或 CLAUDE_CODE_PLUGIN_DIRS 提供的市场插件和本地/内联插件。通过生效的插件注册表解析市场安装(例如 ${CLAUDE_CONFIG_DIR:-~/.claude}/plugins/installed_plugins.json 及其中记录的安装路径),并纳入用户或项目 .claude/skills/ 下处于活动状态的 @skills-dir 插件根目录。只读读取每个插件的 .claude-plugin/plugin.json 和 hooks/hooks.json。将清单中的可选 hooks 字段解析为 .json 路径、内联 hooks 对象,或混合路径和内联对象的数组;相对于该插件根目录解析每个声明的文件路径,并检查所有已声明来源以及默认 hooks/hooks.json 中的命令处理程序,查找对候选脚本的引用,同时解析配置/主目录环境变量和平台路径分隔符。如果无法确切枚举、解析或读取任何已启用/已加载的插件根目录、清单或已声明的 hooks 来源,请保留脚本;如果任何来源引用了该脚本,也请保留脚本。
编辑设置文件后,Claude Code 会保留当前会话的 hooks 快照。如果本会话移除了匹配的 hook 注册,请将脚本保留在原处,直到用户重启 Claude Code;切勿在同一会话中移除其设置 hook 后删除目标脚本。在后续会话中,删除脚本前请重新执行完整的引用扫描和下方的最终检查。
Step 2 中关于规范事件和等效处理程序的要求同样是删除脚本的必要条件;同一事件下无关的插件处理程序不能成为删除独立有效负载的依据。
仅扫描设置并不能证明引用已全部清除;删除目标前,还必须完整扫描并确认上文所述的活动技能/子代理和已启用插件清单均无引用。即使插件清单引用的命令注册在不同事件下,该引用也会阻止删除。
处理完所有相关的用户/项目设置文件后,请重新检查 ${CLAUDE_CONFIG_DIR:-~/.claude}/settings.json、主工作目录的 .claude/settings.json,以及上文解析出的所有适用项目本地 .claude/settings.local.json 路径(适用时包括主检出目录、Windows 并列目录和旧的起始目录路径),确认是否引用了每个旧脚本,包括复合命令或含义不明确的命令中的引用。还要只读检查受管 hook 来源:Linux/WSL 上的 /etc/claude-code/managed-settings.json、macOS 上的 /Library/Application Support/ClaudeCode/managed-settings.json、Windows 上的 C:\Program Files\ClaudeCode\managed-settings.json,以及任何适用的 MDM、服务器管理或命令行 --settings 来源(参见 Claude Code 受管设置的位置)。切勿编辑这些来源。只有在任何来源均无已配置的 hook 引用、活动插件提供相同事件,且脚本内容与 Step 2 中已验证的随附 OMC 有效负载一致时,才可移除脚本。如果无法解析或检查任何适用的项目本地路径、主检出根目录、受管来源或命令行来源,任何来源引用了脚本,用户拒绝了相关设置更改,文件无法更新,不存在随附有效负载,或验证结果不确定,请将相应脚本保留在原处。切勿仅凭基本名称无条件运行 rm -f。
修复:插件过时
# Clear plugin cache (cross-platform)
node -e "const p=require('path'),f=require('fs'),d=process.env.CLAUDE_CONFIG_DIR||p.join(require('os').homedir(),'.claude'),b=p.join(d,'plugins','cache','omc','oh-my-claudecode');try{f.rmSync(b,{recursive:true,force:true});console.log('Plugin cache cleared. Restart Claude Code to fetch latest version.')}catch{console.log('No plugin cache found')}"
修复:缓存过期(多个版本)
# Keep only latest version (cross-platform)
node -e "const p=require('path'),f=require('fs'),h=require('os').homedir(),d=process.env.CLAUDE_CONFIG_DIR||p.join(h,'.claude'),b=p.join(d,'plugins','cache','omc','oh-my-claudecode');try{const v=f.readdirSync(b).filter(x=>/^\d/.test(x)).sort((a,c)=>a.localeCompare(c,void 0,{numeric:true}));v.slice(0,-1).forEach(x=>f.rmSync(p.join(b,x),{recursive:true,force:true}));console.log('Removed',v.length-1,'old version(s)')}catch(e){console.log('No cache to clean')}"
修复:缺少/过时的 CLAUDE.md
除非 Step 4 输出了 CLAUDE.md management enabled,否则跳过此修复;如果 Step 4 报告 CLAUDE.md management disabled by claudeMdEnabled: false 或无法检查是否选择退出,也请跳过。
从 GitHub 获取最新版本并写入 ${CLAUDE_CONFIG_DIR:-~/.claude}/CLAUDE.md:
WebFetch(url: "https://raw.githubusercontent.com/Yeachan-Heo/oh-my-claudecode/main/docs/CLAUDE.md", prompt: "Return the complete raw markdown content exactly as-is")
修复:通过 Curl 安装的旧版内容
删除旧版 agents、commands 和 skills 目录(现由插件提供):
# Backup first (optional - ask user)
# mv "${CLAUDE_CONFIG_DIR:-$HOME/.claude}"/agents "${CLAUDE_CONFIG_DIR:-$HOME/.claude}"/agents.bak
# mv "${CLAUDE_CONFIG_DIR:-$HOME/.claude}"/commands "${CLAUDE_CONFIG_DIR:-$HOME/.claude}"/commands.bak
# mv "${CLAUDE_CONFIG_DIR:-$HOME/.claude}"/skills "${CLAUDE_CONFIG_DIR:-$HOME/.claude}"/skills.bak
# Or remove directly
rm -rf "${CLAUDE_CONFIG_DIR:-$HOME/.claude}"/agents
rm -rf "${CLAUDE_CONFIG_DIR:-$HOME/.claude}"/commands
rm -rf "${CLAUDE_CONFIG_DIR:-$HOME/.claude}"/skills
注意:仅当这些目录包含与 oh-my-claudecode 相关的文件时才删除。如果用户有自定义的 agents/commands/skills,请先提醒并征得同意。
修复后
应用修复后,告知用户:
已应用修复。重启 Claude Code 以使更改生效。