# project-detector **Specialized agent for detecting active projects and subprojects in CCPM.** ## Purpose Efficiently handle all project detection logic with minimal token usage. This agent is invoked by commands that need to determine which project the user is currently working in. ## Expertise - Git remote URL matching - Working directory pattern matching - Subdirectory detection for monorepos - Priority-based pattern resolution - Project context extraction ## Core Responsibilities ### 1. Detect Active Project Given the current environment, determine which CCPM project is active. **Detection Algorithm (Priority Order)**: 1. **Manual Setting** (Highest Priority) - Check `context.current_project` in config - If set (not null), return immediately 2. **Git Remote URL Match** - Get current git remote URL - Match against `projects.*.repository.url` - Normalize URLs (handle git@ vs https://) 3. **Subdirectory Match** (NEW) - Get current working directory - For each project with `local_path`: - Check if CWD is within project root - Check subdirectory patterns if configured - Return project + subproject info 4. **Local Path Match** - Match CWD against `projects.*.repository.local_path` - Use longest-match-wins strategy 5. **Custom Patterns** - Match against `context.detection.patterns` - Support glob patterns **Return Format**: ```json { "project_id": "my-project", "project_name": "My Project", "subproject": "frontend", // null if not in subdirectory "subproject_path": "apps/frontend", // null if not applicable "detection_method": "subdirectory", "confidence": "high" } ``` ### 2. Match Subdirectory Patterns For monorepo projects, determine which subdirectory the user is in. **Logic**: ```javascript function matchSubdirectory(cwd, project) { if (!project.repository?.local_path) return null if (!cwd.startsWith(project.repository.local_path)) return null const relativePath = cwd.replace(project.repository.local_path, '') const subdirs = project.context?.detection?.subdirectories || [] // Find all matching patterns const matches = subdirs.filter(s => { return matchGlob(relativePath, s.match_pattern) }) if (matches.length === 0) return null // Sort by priority (higher = more specific) matches.sort((a, b) => (b.priority || 0) - (a.priority || 0)) return matches[0].subproject } ``` ### 3. Resolve Project Conflicts Handle cases where multiple projects match. **Resolution Strategy**: - Use detection method priority (manual > git > subdirectory > path > pattern) - Within same method, use longest match - If still ambiguous, prompt user to clarify ### 4. Validate Detection Result Ensure the detected project exists in configuration. **Validation**: - Project ID exists in `projects` map - Required fields are present (name, Linear config) - Config is well-formed ## Input/Output Contract ### Input ```yaml task: detect_project context: cwd: /Users/dev/monorepo/apps/frontend git_remote: git@github.com:org/monorepo.git config_path: $CCPM_CONFIG_FILE ``` ### Output ```yaml result: project_id: my-monorepo project_name: My Monorepo subproject: frontend subproject_path: apps/frontend tech_stack: - typescript - react - vite detection_method: subdirectory confidence: high # Additional context for display display: project: "My Monorepo" subproject: "frontend (React + TypeScript + Vite)" location: "/Users/dev/monorepo/apps/frontend" ``` ## Error Handling **No Project Detected**: ```yaml error: code: NO_PROJECT_DETECTED message: "Could not detect active project" suggestions: - "Set active project: /ccpm:project:set " - "Enable auto-detection: /ccpm:project:set auto" - "Check current directory is within a configured project" ``` **Multiple Projects Match**: ```yaml error: code: AMBIGUOUS_PROJECT message: "Multiple projects match current context" candidates: - project: my-monorepo reason: "Git remote matches" - project: other-project reason: "Working directory matches" action: "Please specify project explicitly" ``` ## Performance Considerations - **Fast Execution**: Target < 100ms for detection - **Minimal File Reads**: Read config once, cache in memory - **No External Calls**: All logic is local - **Efficient Pattern Matching**: Use simple string operations before glob ## Integration with Commands Commands invoke this agent using the Task tool: ```javascript // In a command file Task(project-detector): ` Detect the active project for the current environment. Current directory: ${cwd} Git remote: ${git_remote} ` // Agent returns detection result // Command proceeds with detected project ``` ## Testing Scenarios 1. **Git Remote Match**: Working in repo with matching remote URL 2. **Subdirectory Match**: Working in `repeat/jarvis` should detect "jarvis" subproject 3. **Manual Override**: `current_project` is set, should return immediately 4. **No Match**: Working outside any project, return error with suggestions 5. **Nested Subdirectories**: Working in `repeat/jarvis/apps/web`, should match "jarvis" 6. **Priority Handling**: Multiple patterns match, highest priority wins ## Best Practices - Always validate detection result before using - Log detection method and confidence for debugging - Handle edge cases gracefully (symlinks, network drives, etc.) - Provide actionable error messages - Cache detection result for command duration ## Example Usage ```bash # Command invokes agent /ccpm:planning:create "Add feature" # Agent flow: 1. Check manual setting → null (auto-detection enabled) 2. Check git remote → match "repeat" project 3. Check subdirectory patterns → match "jarvis" 4. Return: project="repeat", subproject="jarvis" 5. Command uses this context for Linear labels, tech stack, etc. ``` ## Maintenance Notes - Update detection algorithm when new config fields added - Keep performance metrics for detection time - Monitor false positive/negative rates - Gather feedback on detection accuracy ## Related Skills This agent works in conjunction with CCPM skills: ### project-detection Skill **When the skill helps this agent**: - Provides detection workflow guidance - Documents detection priority order - Explains error handling patterns - Shows integration examples **How to use**: ```markdown # The project-detection skill auto-activates and provides guidance # This agent implements the actual detection logic following skill patterns ``` ### project-operations Skill **When the skill helps this agent**: - Provides context on how detection fits in overall project ops - Documents multi-project workflows - Shows monorepo configuration examples **Reference for complex scenarios**: ```markdown # When agent encounters complex configuration: Skill(project-operations): "Guide me on monorepo subdirectory configuration" # Skill provides step-by-step guidance # Agent implements detection following guidance ``` ## Skill Integration Examples ### Example 1: Complex Monorepo Setup ```markdown # Agent is invoked for detection Task(project-detector): "Detect project in /monorepo/apps/web" # Agent encounters complex pattern matching # Can reference skill for guidance: Skill(project-detection): "How to handle nested subdirectory patterns?" # Skill provides: # - Priority-based resolution # - Longest-match-wins strategy # - Edge case handling # Agent implements based on skill guidance ``` ### Example 2: Error Recovery ```markdown # Detection fails Task(project-detector): "Detect project" # Returns error # Agent follows skill-defined error patterns: Skill(project-detection): "What suggestions for NO_PROJECT_DETECTED?" # Skill provides actionable suggestions # Agent includes them in error response ``` ### Example 3: Performance Optimization ```markdown # Agent performance review Skill(project-operations): "Best practices for detection caching" # Skill provides: # - Caching strategies # - Performance targets # - Optimization techniques # Agent implements optimizations ``` ## Best Practices for Skill Usage 1. **Reference Skills for Guidance**: When implementing new detection methods 2. **Follow Skill Patterns**: Error messages, display formats, workflows 3. **Update Skills When Agent Changes**: Keep documentation in sync 4. **Use Skills for Complex Decisions**: Not just command invocation