diff --git a/src/hooks/init.rs b/src/hooks/init.rs index 64115a1d..36b0fac9 100644 --- a/src/hooks/init.rs +++ b/src/hooks/init.rs @@ -582,6 +582,36 @@ pub fn uninstall(global: bool, gemini: bool, codex: bool, cursor: bool, verbose: removed.push("Integrity hash: removed".to_string()); } + // 1c. Remove orphaned .github/hooks/rtk-rewrite.json (broken command from old rtk init --copilot) + let github_hook_path = PathBuf::from(".github/hooks/rtk-rewrite.json"); + if github_hook_path.exists() { + let content = fs::read_to_string(&github_hook_path).unwrap_or_default(); + let command = serde_json::from_str::(&content) + .ok() + .and_then(|j| { + j.get("hooks")? + .get("PreToolUse")? + .as_array()? + .first() + .cloned() + }) + .and_then(|e| e.get("command")?.as_str().map(String::from)) + .unwrap_or_default(); + + if command == "rtk hook" { + fs::remove_file(&github_hook_path).with_context(|| { + format!( + "Failed to remove orphaned hook: {}", + github_hook_path.display() + ) + })?; + removed.push(format!( + "Orphaned Copilot hook: {} (broken \"rtk hook\" command)", + github_hook_path.display() + )); + } + } + // 2. Remove RTK.md let rtk_md_path = claude_dir.join("RTK.md"); if rtk_md_path.exists() { @@ -2017,6 +2047,42 @@ fn show_claude_config() -> Result<()> { println!("[--] Cursor: home dir not found"); } + // Check for orphaned .github/hooks/rtk-rewrite.json (generated by older rtk init --copilot) + let github_hook_path = PathBuf::from(".github/hooks/rtk-rewrite.json"); + if github_hook_path.exists() { + let content = fs::read_to_string(&github_hook_path).unwrap_or_default(); + let command = serde_json::from_str::(&content) + .ok() + .and_then(|j| { + j.get("hooks")? + .get("PreToolUse")? + .as_array()? + .first() + .cloned() + }) + .and_then(|e| e.get("command")?.as_str().map(String::from)) + .unwrap_or_default(); + + if command == "rtk hook" { + println!( + "\n[warn] .github/hooks/rtk-rewrite.json: broken hook command (\"rtk hook\" missing subcommand)" + ); + println!(" → Generated by an older version of rtk init --copilot"); + println!(" → Every Bash tool call logs a spurious parse_failure in history.db"); + println!(" → Check impact: rtk gain --failures"); + println!(" → Fix: delete the file or run `rtk init --copilot` to regenerate it"); + } else if command == "rtk hook copilot" { + println!( + "\n[ok] .github/hooks/rtk-rewrite.json: Copilot hook configured" + ); + } else if !command.is_empty() { + println!( + "\n[warn] .github/hooks/rtk-rewrite.json: unexpected command: \"{}\"", + command + ); + } + } + println!("\nUsage:"); println!(" rtk init # Full injection into local CLAUDE.md"); println!(" rtk init -g # Hook + RTK.md + @RTK.md + settings.json (recommended)");