Files
gh-duongdev-ccpm/agents/project-detector.md
2025-11-29 18:24:24 +08:00

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):

  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:

{
  "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 projects map
  • 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

  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

# 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

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

  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