diff --git a/colgrep/README.md b/colgrep/README.md index 2d968da3..be53b901 100644 --- a/colgrep/README.md +++ b/colgrep/README.md @@ -394,6 +394,7 @@ Config stored at `~/.config/colgrep/config.json`. | OpenCode | `colgrep --install-opencode` | `colgrep --uninstall-opencode` | | Codex | `colgrep --install-codex` | `colgrep --uninstall-codex` | | Hermes | `colgrep --install-hermes` | `colgrep --uninstall-hermes` | +| Kimi Code | `colgrep --install-kimi` | `colgrep --uninstall-kimi` | > Restart your agent after installing. @@ -407,6 +408,10 @@ The Claude Code integration installs session and task hooks that: This means Claude Code automatically uses `colgrep` as its primary search tool when the index is ready. +### Kimi Code Integration + +The Kimi Code integration installs a [skill](https://www.kimi.com/code/docs/en/kimi-code-cli/customization/skills.html) at `~/.kimi-code/skills/colgrep/SKILL.md` (or `$KIMI_CODE_HOME/skills/colgrep/SKILL.md` when `KIMI_CODE_HOME` is set) that teaches the agent to use `colgrep` as its primary search tool. New sessions pick it up automatically. + ### Complete Uninstall Remove colgrep from all AI tools, clear all indexes, and delete all data: diff --git a/colgrep/src/cli.rs b/colgrep/src/cli.rs index c7740bd4..bd78daab 100644 --- a/colgrep/src/cli.rs +++ b/colgrep/src/cli.rs @@ -409,6 +409,14 @@ pub struct Cli { #[arg(long = "uninstall-hermes")] pub uninstall_hermes: bool, + /// Install colgrep for Kimi Code + #[arg(long = "install-kimi")] + pub install_kimi: bool, + + /// Uninstall colgrep from Kimi Code + #[arg(long = "uninstall-kimi")] + pub uninstall_kimi: bool, + /// Completely uninstall colgrep: remove from all AI tools, clear all indexes, and remove all data #[arg(long = "uninstall")] pub uninstall: bool, diff --git a/colgrep/src/install/kimi.rs b/colgrep/src/install/kimi.rs new file mode 100644 index 00000000..428b92c6 --- /dev/null +++ b/colgrep/src/install/kimi.rs @@ -0,0 +1,129 @@ +use anyhow::{Context, Result}; +use colored::Colorize; +use std::fs; +use std::path::PathBuf; + +use super::SKILL_MD; + +/// YAML frontmatter required by Kimi Code skills (directory-form SKILL.md +/// must declare `name` and `description` explicitly). +const KIMI_FRONTMATTER: &str = r#"--- +name: colgrep +description: Semantic code search with colgrep - use colgrep as the primary search tool instead of Grep/Glob +type: prompt +whenToUse: When searching, exploring, or trying to understand code in this repository +--- + +"#; + +/// Get the Kimi Code home directory ($KIMI_CODE_HOME or ~/.kimi-code) +fn get_kimi_code_home() -> Result { + if let Ok(home) = std::env::var("KIMI_CODE_HOME") { + if !home.is_empty() { + return Ok(PathBuf::from(home)); + } + } + let home = dirs::home_dir().context("Could not determine home directory")?; + Ok(home.join(".kimi-code")) +} + +/// Get the colgrep skill directory for Kimi Code +fn get_skill_dir() -> Result { + Ok(get_kimi_code_home()?.join("skills").join("colgrep")) +} + +/// Get the SKILL.md path for Kimi Code +fn get_skill_md_path() -> Result { + Ok(get_skill_dir()?.join("SKILL.md")) +} + +/// Write the colgrep SKILL.md for Kimi Code +fn write_skill_md() -> Result<()> { + let skill_dir = get_skill_dir()?; + fs::create_dir_all(&skill_dir)?; + + let skill_path = get_skill_md_path()?; + // Normalize to LF: on Windows checkouts SKILL.md may be CRLF, which would + // otherwise produce a file with mixed line endings. + let content = format!("{}{}", KIMI_FRONTMATTER, SKILL_MD.replace("\r\n", "\n")); + fs::write(&skill_path, content)?; + Ok(()) +} + +/// Remove the colgrep SKILL.md from Kimi Code +fn remove_skill_md() -> Result<()> { + let skill_dir = get_skill_dir()?; + let skill_path = get_skill_md_path()?; + + if skill_path.exists() { + fs::remove_file(&skill_path)?; + } + + // Remove the skill directory if it is now empty + if skill_dir.exists() { + let is_empty = fs::read_dir(&skill_dir) + .map(|mut rd| rd.next().is_none()) + .unwrap_or(false); + if is_empty { + fs::remove_dir(&skill_dir)?; + } + } + + Ok(()) +} + +/// Install colgrep for Kimi Code +pub fn install_kimi() -> Result<()> { + println!("Installing colgrep for Kimi Code..."); + + write_skill_md()?; + let skill_path = get_skill_md_path()?; + println!( + "{} Added colgrep skill to {}", + "✓".green(), + skill_path.display() + ); + + print_kimi_success(); + Ok(()) +} + +/// Uninstall colgrep from Kimi Code +pub fn uninstall_kimi() -> Result<()> { + println!("Uninstalling colgrep from Kimi Code..."); + + remove_skill_md()?; + println!("{} Removed colgrep skill from Kimi Code", "✓".green()); + + println!(); + println!("{}", "Colgrep has been uninstalled from Kimi Code.".green()); + Ok(()) +} + +fn print_kimi_success() { + println!(); + println!("{}", "═".repeat(70).cyan()); + println!(); + println!( + " {} {}", + "✓".green().bold(), + "COLGREP INSTALLED FOR KIMI CODE".green().bold() + ); + println!(); + println!( + " {}", + "Colgrep is now available as a semantic search skill in Kimi Code.".white() + ); + println!(); + println!(" {}", "Usage in Kimi Code:".cyan().bold()); + println!( + " {}", + "Start a new session and search your codebase in natural language.".white() + ); + println!(" {}", "Example: \"find error handling logic\"".white()); + println!(); + println!(" {}", "To uninstall:".cyan().bold()); + println!(" {}", "colgrep --uninstall-kimi".green()); + println!(); + println!("{}", "═".repeat(70).cyan()); +} diff --git a/colgrep/src/install/mod.rs b/colgrep/src/install/mod.rs index 9da6d3c4..68e2768b 100644 --- a/colgrep/src/install/mod.rs +++ b/colgrep/src/install/mod.rs @@ -1,12 +1,14 @@ mod claude_code; mod codex; mod hermes; +mod kimi; mod opencode; mod uninstall; pub use claude_code::{install_claude_code, uninstall_claude_code}; pub use codex::{install_codex, uninstall_codex}; pub use hermes::{install_hermes, uninstall_hermes}; +pub use kimi::{install_kimi, uninstall_kimi}; pub use opencode::{install_opencode, uninstall_opencode}; pub use uninstall::uninstall_all; diff --git a/colgrep/src/install/uninstall.rs b/colgrep/src/install/uninstall.rs index 2ceca0a5..049d239d 100644 --- a/colgrep/src/install/uninstall.rs +++ b/colgrep/src/install/uninstall.rs @@ -7,7 +7,9 @@ use colored::Colorize; use std::fs; use std::path::PathBuf; -use super::{uninstall_claude_code, uninstall_codex, uninstall_hermes, uninstall_opencode}; +use super::{ + uninstall_claude_code, uninstall_codex, uninstall_hermes, uninstall_kimi, uninstall_opencode, +}; /// Get the colgrep data directory (contains indices and config) fn get_colgrep_data_dir() -> Result { @@ -33,10 +35,11 @@ fn get_hf_cache_dir() -> Result { /// 2. Uninstalls from Codex (if installed) /// 3. Uninstalls from OpenCode (if installed) /// 4. Uninstalls from Hermes (if installed) -/// 5. Removes all indexes -/// 6. Removes config and data directory -/// 7. Removes ONNX runtime cache -/// 8. Shows instructions for removing the binary +/// 5. Uninstalls from Kimi Code (if installed) +/// 6. Removes all indexes +/// 7. Removes config and data directory +/// 8. Removes ONNX runtime cache +/// 9. Shows instructions for removing the binary pub fn uninstall_all() -> Result<()> { println!(); println!("{}", "Completely uninstalling colgrep...".yellow().bold()); @@ -112,6 +115,17 @@ fn uninstall_ai_tools() { } } + // Kimi Code + match uninstall_kimi() { + Ok(()) => {} + Err(_) => { + println!( + " {} Kimi Code: not installed or already removed", + "-".dimmed() + ); + } + } + println!(); } diff --git a/colgrep/src/lib.rs b/colgrep/src/lib.rs index bca81230..00f3d442 100644 --- a/colgrep/src/lib.rs +++ b/colgrep/src/lib.rs @@ -36,8 +36,9 @@ pub use parser::{ // Install commands for AI coding tools pub use install::{ - install_claude_code, install_codex, install_hermes, install_opencode, uninstall_all, - uninstall_claude_code, uninstall_codex, uninstall_hermes, uninstall_opencode, + install_claude_code, install_codex, install_hermes, install_kimi, install_opencode, + uninstall_all, uninstall_claude_code, uninstall_codex, uninstall_hermes, uninstall_kimi, + uninstall_opencode, }; // Signal handling diff --git a/colgrep/src/main.rs b/colgrep/src/main.rs index 418cb411..d4ddfc2f 100644 --- a/colgrep/src/main.rs +++ b/colgrep/src/main.rs @@ -12,9 +12,9 @@ use rayon::ThreadPoolBuilder; use colgrep::{ acceleration::{apply_acceleration_mode, env_acceleration_mode, AccelerationMode}, - install_claude_code, install_codex, install_hermes, install_opencode, setup_signal_handler, - uninstall_all, uninstall_claude_code, uninstall_codex, uninstall_hermes, uninstall_opencode, - Config, + install_claude_code, install_codex, install_hermes, install_kimi, install_opencode, + setup_signal_handler, uninstall_all, uninstall_claude_code, uninstall_codex, uninstall_hermes, + uninstall_kimi, uninstall_opencode, Config, }; use cli::{Cli, Commands}; @@ -103,6 +103,14 @@ fn main() -> Result<()> { return uninstall_hermes(); } + if cli.install_kimi { + return install_kimi(); + } + + if cli.uninstall_kimi { + return uninstall_kimi(); + } + if cli.uninstall { return uninstall_all(); }