8.3 KiB
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):
-
Manual Setting (Highest Priority)
- Check
context.current_projectin config - If set (not null), return immediately
- Check
-
Git Remote URL Match
- Get current git remote URL
- Match against
projects.*.repository.url - Normalize URLs (handle git@ vs https://)
-
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
-
Local Path Match
- Match CWD against
projects.*.repository.local_path - Use longest-match-wins strategy
- Match CWD against
-
Custom Patterns
- Match against
context.detection.patterns - Support glob patterns
- Match against
Return Format:
{
"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:
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
projectsmap - Required fields are present (name, Linear config)
- Config is well-formed
Input/Output Contract
Input
task: detect_project
context:
cwd: /Users/dev/monorepo/apps/frontend
git_remote: git@github.com:org/monorepo.git
config_path: $CCPM_CONFIG_FILE
Output
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:
error:
code: NO_PROJECT_DETECTED
message: "Could not detect active project"
suggestions:
- "Set active project: /ccpm:project:set <project-id>"
- "Enable auto-detection: /ccpm:project:set auto"
- "Check current directory is within a configured project"
Multiple Projects Match:
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:
// 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
- Git Remote Match: Working in repo with matching remote URL
- Subdirectory Match: Working in
repeat/jarvisshould detect "jarvis" subproject - Manual Override:
current_projectis set, should return immediately - No Match: Working outside any project, return error with suggestions
- Nested Subdirectories: Working in
repeat/jarvis/apps/web, should match "jarvis" - 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
# 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:
# 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:
# 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
# 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
# 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
# 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
- Reference Skills for Guidance: When implementing new detection methods
- Follow Skill Patterns: Error messages, display formats, workflows
- Update Skills When Agent Changes: Keep documentation in sync
- Use Skills for Complex Decisions: Not just command invocation