diff --git a/crates/blue-mcp/src/handlers/worktree.rs b/crates/blue-mcp/src/handlers/worktree.rs index e59bc1d..a80396f 100644 --- a/crates/blue-mcp/src/handlers/worktree.rs +++ b/crates/blue-mcp/src/handlers/worktree.rs @@ -7,11 +7,79 @@ //! - Branch: `feature-description` (number prefix stripped) //! - Worktree: `feature-description` +use std::path::Path; + use blue_core::{DocType, ProjectState, Worktree as StoreWorktree}; use serde_json::{json, Value}; use crate::error::ServerError; +/// Detect the appropriate install command for a project +/// +/// Checks for package manager lock files and project files in priority order. +/// Returns None if a setup script exists (takes precedence) or no package manager detected. +fn detect_install_command(path: &Path) -> Option { + // Custom setup script takes precedence + if path.join("scripts/setup-worktree.sh").exists() { + return None; + } + + // Node.js - check lock files for package manager + if path.join("package.json").exists() { + if path.join("bun.lockb").exists() { + return Some("bun install".into()); + } + if path.join("pnpm-lock.yaml").exists() { + return Some("pnpm install".into()); + } + if path.join("yarn.lock").exists() { + return Some("yarn install".into()); + } + return Some("npm install".into()); + } + + // Python + if path.join("pyproject.toml").exists() { + if path.join("uv.lock").exists() { + return Some("uv sync".into()); + } + if path.join("poetry.lock").exists() { + return Some("poetry install".into()); + } + return Some("pip install -e .".into()); + } + if path.join("requirements.txt").exists() { + return Some("pip install -r requirements.txt".into()); + } + + // Rust + if path.join("Cargo.toml").exists() { + return Some("cargo build".into()); + } + + // Go + if path.join("go.mod").exists() { + return Some("go mod download".into()); + } + + // Generic Makefile + if path.join("Makefile").exists() { + return Some("make".into()); + } + + None +} + +/// Check for a custom setup script +fn detect_setup_script(path: &Path) -> Option { + let script_path = path.join("scripts/setup-worktree.sh"); + if script_path.exists() { + Some("./scripts/setup-worktree.sh".into()) + } else { + None + } +} + /// Strip RFC number prefix from title /// /// Converts `0007-consistent-branch-naming` to `consistent-branch-naming` @@ -92,15 +160,50 @@ pub fn handle_create(state: &ProjectState, args: &Value) -> Result Ok(json!({