Skip to content
Development
Command

/estimate-assistant

Generate accurate project time estimates

From plugin
claude-command-suite
1.3k199 skills89 agents199 commands
Install
$ npx -y skills add qdhenry/Claude-Command-Suite --agent claude-code

How it fires

How this command gets triggered: by you, by Claude, or both.

  • Fires itselfClaude auto-loads it when your prompt matches the work.
  • You can call itInvoke it directly when you want it.
  • Slash command/estimate-assistant

Context preview

What this command does when you run it.

Generate accurate project time estimates

Command definition

estimate-assistant.md

estimate-assistant

Generate accurate project time estimates

Purpose

This command analyzes past commits, PR completion times, code complexity metrics, and team performance to provide accurate task estimates. It helps teams move beyond gut-feel estimates to data-backed predictions.

Usage

# Estimate a specific task based on description
claude "Estimate task: Implement OAuth2 login flow with Google"

# Analyze historical accuracy of estimates
claude "Show estimation accuracy for the last 10 sprints"

# Estimate based on code changes
claude "Estimate effort for refactoring src/api/users module"

# Get team member specific estimates
claude "How long would it take Alice to implement the payment webhook handler?"

Instructions

1. Gather Historical Data

Collect data from git history and Linear:

# Get commit history with timestamps and authors
git log --pretty=format:"%h|%an|%ad|%s" --date=iso --since="6 months ago" > commit_history.txt

# Analyze PR completion times
gh pr list --state closed --limit 100 --json number,title,createdAt,closedAt,additions,deletions,files

# Get file change frequency
git log --pretty=format: --name-only --since="6 months ago" | sort | uniq -c | sort -rn

# Analyze commit patterns by author
git shortlog -sn --since="6 months ago"

2. Calculate Code Complexity Metrics

Analyze code characteristics:

function analyzeComplexity(filePath) {
  const metrics = {
    lines: 0,
    cyclomaticComplexity: 0,
    dependencies: 0,
    testCoverage: 0,
    similarFiles: []
  };
  
  // Count lines of code
  const content = readFile(filePath);
  metrics.lines = content.split('\n').length;
  
  // Cyclomatic complexity (simplified)
  const conditions = content.match(/if\s*\(|while\s*\(|for\s*\(|case\s+|\?\s*:/g);
  metrics.cyclomaticComplexity = (conditions?.length || 0) + 1;
  
  // Count imports/dependencies
  const imports = content.match(/import.*from|require\(/g);
  metrics.dependencies = imports?.length || 0;
  
  // Find similar files by structure
  metrics.similarFiles = findSimilarFiles(filePath);
  
  return metrics;
}

3. Build Estimation Models

Time-Based Estimation

class HistoricalEstimator {
  constructor(gitData, linearData) {
    this.gitData = gitData;
    this.linearData = linearData;
    this.authorVelocity = new Map();
    this.fileTypeMultipliers = new Map();
  }
  
  calculateAuthorVelocity(author) {
    const authorCommits = this.gitData.filter(c => c.author === author);
    const taskCompletions = this.linearData.filter(t => 
      t.assignee === author && t.completedAt
    );
    
    // Lines of code per day
    const totalLines = authorCommits.reduce((sum, c) => 
      sum + c.additions + c.deletions, 0
    );
    const totalDays = this.calculateWorkDays(authorCommits);
    const linesPerDay = totalLines / totalDays;
    
    // Story points per sprint
    const pointsCompleted = taskCompletions.reduce((sum, t) => 
      sum + (t.estimate || 0), 0
    );
    const sprintCount = this.countSprints(taskCompletions);
    const pointsPerSprint = pointsCompleted / sprintCount;
    
    return {
      linesPerDay,
      pointsPerSprint,
      averageTaskDuration: this.calculateAverageTaskDuration(taskCompletions),
      accuracy: this.calculateEstimateAccuracy(taskCompletions)
    };
  }
  
  estimateTask(description, assignee = null) {
    // Extract key features from description
    const features = this.extractFeatures(description);
    
    // Find similar completed tasks
    const similarTasks = this.findSimilarTasks(features);
    
    // Base estimate from similar tasks
    let baseEstimate = this.calculateMedianEstimate(similarTasks);
    
    // Adjust for complexity indicators
    const complexityMultiplier = this.calculateComplexityMultiplier(features);
    baseEstimate *= complexityMultiplier;
    
    // Adjust for assignee if specified
    if (assignee) {
      const velocity = this.calculateAuthorVelocity(assignee);
      const teamAvgVelocity = this.calculateTeamAverageVelocity();
      const velocityRatio = velocity.pointsPerSprint / teamAvgVelocity;
      baseEstimate *= (2 - velocityRatio); // Faster devs get lower estimates
    }
    
    // Add confidence interval
    const confidence = this.calculateConfidence(similarTasks.length, features);
    
    return {
      estimate: Math.round(baseEstimate),
      confidence,
      range: {
        min: Math.round(baseEstimate * 0.7),
        max: Math.round(baseEstimate * 1.5)
      },
      basedOn: similarTasks.slice(0, 3),
      factors: this.explainFactors(features, complexityMultiplier)
    };
  }
}

Pattern Recognition

function extractFeatures(taskDescription) {
  const features = {
    keywords: [],
    fileTypes: [],
    modules: [],
    complexity: 'medium',
    type: 'feature', // feature, bug, refactor, etc.
    hasTests: false,
    hasUI: false,
    hasAPI: false,
    hasDatabase: false
  };
  
  // Keywords that indicate complexity
  const complexityKeywords = {
    high: ['refactor', 'migrate', 'redesign', 'optimize', 'architecture'],
    medium: ['implement', 'add', 'create', 'update', 'integrate'],
    low: ['fix', 'adjust', 'tweak', 'change', 'modify']
  };
  
  // Detect task type
  if (taskDescription.match(/bug|fix|repair|broken/i)) {
    features.type = 'bug';
  } else if (taskDescription.match(/refactor|cleanup|optimize/i)) {
    features.type = 'refactor';
  } else if (taskDescription.match(/test|spec|coverage/i)) {
    features.type = 'test';
  }
  
  // Detect components
  features.hasUI = /UI|frontend|component|view|page/i.test(taskDescription);
  features.hasAPI = /API|endpoint|route|REST|GraphQL/i.test(taskDescription);
  features.hasDatabase = /database|DB|migration|schema|query/i.test(taskDescription);
  features.hasTests = /test|spec|TDD|coverage/i.test(taskDescription);
  
  // Extract file types mentioned
  const fileTypeMatches = taskDescription.match(/\.(
Read more
Ships withclaude-command-suite

A comprehensive development toolkit designed following Anthropic's Claude Code Best Practices for AI-assisted software development.

Get the whole plugin