Initial commit
This commit is contained in:
186
commands/commit-analysis/.scripts/atomicity-checker.py
Executable file
186
commands/commit-analysis/.scripts/atomicity-checker.py
Executable file
@@ -0,0 +1,186 @@
|
||||
#!/usr/bin/env python3
|
||||
# Script: atomicity-checker.py
|
||||
# Purpose: Assess if changes form an atomic commit or should be split
|
||||
# Author: Git Commit Assistant Plugin
|
||||
# Version: 1.0.0
|
||||
#
|
||||
# Usage:
|
||||
# git diff HEAD | ./atomicity-checker.py
|
||||
#
|
||||
# Returns:
|
||||
# JSON: {"atomic": true/false, "reasoning": "...", "recommendations": [...]}
|
||||
#
|
||||
# Exit Codes:
|
||||
# 0 - Success
|
||||
# 1 - No input
|
||||
# 2 - Analysis error
|
||||
|
||||
import sys
|
||||
import re
|
||||
import json
|
||||
from collections import defaultdict
|
||||
|
||||
def analyze_atomicity(diff_content):
|
||||
"""
|
||||
Analyze if changes are atomic (single logical unit).
|
||||
|
||||
Criteria for atomic:
|
||||
- Single type (all feat, or all fix, etc.)
|
||||
- Single scope (all in one module)
|
||||
- Logically cohesive
|
||||
- Reasonable file count (<= 10)
|
||||
"""
|
||||
|
||||
lines = diff_content.split('\n')
|
||||
|
||||
# Track changes
|
||||
files = []
|
||||
types_detected = set()
|
||||
scopes_detected = set()
|
||||
file_changes = defaultdict(lambda: {'additions': 0, 'deletions': 0})
|
||||
|
||||
current_file = None
|
||||
|
||||
for line in lines:
|
||||
# Track files
|
||||
if line.startswith('+++ '):
|
||||
file_path = line[4:].strip()
|
||||
if file_path != '/dev/null' and file_path.startswith('b/'):
|
||||
file_path = file_path[2:]
|
||||
files.append(file_path)
|
||||
current_file = file_path
|
||||
|
||||
# Detect type from file
|
||||
if '.test.' in file_path or '.spec.' in file_path:
|
||||
types_detected.add('test')
|
||||
elif file_path.endswith('.md'):
|
||||
types_detected.add('docs')
|
||||
elif 'package.json' in file_path or 'pom.xml' in file_path:
|
||||
types_detected.add('build')
|
||||
elif '.github/workflows' in file_path or '.gitlab-ci' in file_path:
|
||||
types_detected.add('ci')
|
||||
|
||||
# Detect scope from path
|
||||
match = re.match(r'src/([^/]+)/', file_path)
|
||||
if match:
|
||||
scopes_detected.add(match.group(1))
|
||||
|
||||
# Count line changes
|
||||
if current_file:
|
||||
if line.startswith('+') and not line.startswith('+++'):
|
||||
file_changes[current_file]['additions'] += 1
|
||||
elif line.startswith('-') and not line.startswith('---'):
|
||||
file_changes[current_file]['deletions'] += 1
|
||||
|
||||
# Detect types from content
|
||||
if line.startswith('+'):
|
||||
if 'export function' in line or 'export class' in line:
|
||||
types_detected.add('feat')
|
||||
elif 'fix' in line.lower() or 'error' in line.lower():
|
||||
types_detected.add('fix')
|
||||
elif 'refactor' in line.lower() or 'rename' in line.lower():
|
||||
types_detected.add('refactor')
|
||||
|
||||
# Calculate metrics
|
||||
total_files = len(files)
|
||||
total_additions = sum(f['additions'] for f in file_changes.values())
|
||||
total_deletions = sum(f['deletions'] for f in file_changes.values())
|
||||
total_changes = total_additions + total_deletions
|
||||
|
||||
num_types = len(types_detected)
|
||||
num_scopes = len(scopes_detected)
|
||||
|
||||
# Atomicity checks
|
||||
checks = {
|
||||
'single_type': num_types <= 1,
|
||||
'single_scope': num_scopes <= 1,
|
||||
'reasonable_file_count': total_files <= 10,
|
||||
'reasonable_change_size': total_changes <= 500,
|
||||
'cohesive': num_types <= 1 and num_scopes <= 1
|
||||
}
|
||||
|
||||
# Determine atomicity
|
||||
is_atomic = all([
|
||||
checks['single_type'] or num_types == 0,
|
||||
checks['single_scope'] or num_scopes == 0,
|
||||
checks['reasonable_file_count']
|
||||
])
|
||||
|
||||
# Build reasoning
|
||||
if is_atomic:
|
||||
reasoning = f"Changes are atomic: {total_files} files, "
|
||||
if num_types <= 1:
|
||||
reasoning += f"single type ({list(types_detected)[0] if types_detected else 'unknown'}), "
|
||||
if num_scopes <= 1:
|
||||
reasoning += f"single scope ({list(scopes_detected)[0] if scopes_detected else 'root'}). "
|
||||
reasoning += "Forms a cohesive logical unit."
|
||||
else:
|
||||
issues = []
|
||||
if num_types > 1:
|
||||
issues.append(f"multiple types ({', '.join(types_detected)})")
|
||||
if num_scopes > 1:
|
||||
issues.append(f"multiple scopes ({', '.join(list(scopes_detected)[:3])})")
|
||||
if total_files > 10:
|
||||
issues.append(f"many files ({total_files})")
|
||||
|
||||
reasoning = f"Changes are NOT atomic: {', '.join(issues)}. Should be split into focused commits."
|
||||
|
||||
# Generate recommendations if not atomic
|
||||
recommendations = []
|
||||
if not is_atomic:
|
||||
if num_types > 1:
|
||||
recommendations.append({
|
||||
'strategy': 'Split by type',
|
||||
'description': f"Create separate commits for each type: {', '.join(types_detected)}"
|
||||
})
|
||||
if num_scopes > 1:
|
||||
recommendations.append({
|
||||
'strategy': 'Split by scope',
|
||||
'description': f"Create separate commits for each module: {', '.join(list(scopes_detected)[:3])}"
|
||||
})
|
||||
if total_files > 15:
|
||||
recommendations.append({
|
||||
'strategy': 'Split by feature',
|
||||
'description': 'Break into smaller logical units (5-10 files per commit)'
|
||||
})
|
||||
|
||||
return {
|
||||
'atomic': is_atomic,
|
||||
'reasoning': reasoning,
|
||||
'checks': checks,
|
||||
'metrics': {
|
||||
'total_files': total_files,
|
||||
'total_additions': total_additions,
|
||||
'total_deletions': total_deletions,
|
||||
'total_changes': total_changes,
|
||||
'types_detected': list(types_detected),
|
||||
'scopes_detected': list(scopes_detected),
|
||||
'num_types': num_types,
|
||||
'num_scopes': num_scopes
|
||||
},
|
||||
'recommendations': recommendations if not is_atomic else []
|
||||
}
|
||||
|
||||
def main():
|
||||
diff_content = sys.stdin.read()
|
||||
|
||||
if not diff_content or not diff_content.strip():
|
||||
print(json.dumps({
|
||||
'error': 'No diff content provided',
|
||||
'atomic': None
|
||||
}))
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
result = analyze_atomicity(diff_content)
|
||||
print(json.dumps(result, indent=2))
|
||||
sys.exit(0)
|
||||
except Exception as e:
|
||||
print(json.dumps({
|
||||
'error': str(e),
|
||||
'atomic': None
|
||||
}))
|
||||
sys.exit(2)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
103
commands/commit-analysis/.scripts/git-diff-analyzer.sh
Executable file
103
commands/commit-analysis/.scripts/git-diff-analyzer.sh
Executable file
@@ -0,0 +1,103 @@
|
||||
#!/bin/bash
|
||||
# Script: git-diff-analyzer.sh
|
||||
# Purpose: Parse git diff output for detailed file and line change analysis
|
||||
# Author: Git Commit Assistant Plugin
|
||||
# Version: 1.0.0
|
||||
#
|
||||
# Usage:
|
||||
# git diff HEAD | ./git-diff-analyzer.sh
|
||||
#
|
||||
# Returns:
|
||||
# JSON with file details, line counts, and change summaries
|
||||
#
|
||||
# Exit Codes:
|
||||
# 0 - Success
|
||||
# 1 - No input
|
||||
# 2 - Analysis error
|
||||
|
||||
# Read diff from stdin
|
||||
diff_content=$(cat)
|
||||
|
||||
if [ -z "$diff_content" ]; then
|
||||
echo '{"error": "No diff content provided"}'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Initialize counters
|
||||
total_files=0
|
||||
total_additions=0
|
||||
total_deletions=0
|
||||
declare -A file_stats
|
||||
|
||||
# Parse diff output
|
||||
current_file=""
|
||||
while IFS= read -r line; do
|
||||
# File headers
|
||||
if [[ "$line" =~ ^\+\+\+\ b/(.+)$ ]]; then
|
||||
current_file="${BASH_REMATCH[1]}"
|
||||
((total_files++))
|
||||
file_stats["$current_file,additions"]=0
|
||||
file_stats["$current_file,deletions"]=0
|
||||
file_stats["$current_file,status"]="M"
|
||||
|
||||
# New file
|
||||
elif [[ "$line" =~ ^\+\+\+\ b/(.+)$ ]] && [[ "$diff_content" == *"--- /dev/null"* ]]; then
|
||||
file_stats["$current_file,status"]="A"
|
||||
|
||||
# Deleted file
|
||||
elif [[ "$line" =~ ^---\ a/(.+)$ ]] && [[ "$diff_content" == *"+++ /dev/null"* ]]; then
|
||||
current_file="${BASH_REMATCH[1]}"
|
||||
file_stats["$current_file,status"]="D"
|
||||
|
||||
# Count additions
|
||||
elif [[ "$line" =~ ^\+[^+] ]] && [ -n "$current_file" ]; then
|
||||
((total_additions++))
|
||||
((file_stats["$current_file,additions"]++))
|
||||
|
||||
# Count deletions
|
||||
elif [[ "$line" =~ ^-[^-] ]] && [ -n "$current_file" ]; then
|
||||
((total_deletions++))
|
||||
((file_stats["$current_file,deletions"]++))
|
||||
fi
|
||||
done <<< "$diff_content"
|
||||
|
||||
# Build JSON output
|
||||
echo "{"
|
||||
echo " \"summary\": {"
|
||||
echo " \"total_files\": $total_files,"
|
||||
echo " \"total_additions\": $total_additions,"
|
||||
echo " \"total_deletions\": $total_deletions,"
|
||||
echo " \"net_change\": $((total_additions - total_deletions))"
|
||||
echo " },"
|
||||
echo " \"files\": ["
|
||||
|
||||
# Output file stats
|
||||
first=true
|
||||
for key in "${!file_stats[@]}"; do
|
||||
if [[ "$key" == *",status" ]]; then
|
||||
file="${key%,status}"
|
||||
status="${file_stats[$key]}"
|
||||
additions=${file_stats["$file,additions"]:-0}
|
||||
deletions=${file_stats["$file,deletions"]:-0}
|
||||
|
||||
if [ "$first" = true ]; then
|
||||
first=false
|
||||
else
|
||||
echo ","
|
||||
fi
|
||||
|
||||
echo -n " {"
|
||||
echo -n "\"file\": \"$file\", "
|
||||
echo -n "\"status\": \"$status\", "
|
||||
echo -n "\"additions\": $additions, "
|
||||
echo -n "\"deletions\": $deletions, "
|
||||
echo -n "\"net\": $((additions - deletions))"
|
||||
echo -n "}"
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo " ]"
|
||||
echo "}"
|
||||
|
||||
exit 0
|
||||
131
commands/commit-analysis/.scripts/scope-identifier.sh
Executable file
131
commands/commit-analysis/.scripts/scope-identifier.sh
Executable file
@@ -0,0 +1,131 @@
|
||||
#!/bin/bash
|
||||
# Script: scope-identifier.sh
|
||||
# Purpose: Identify primary scope (module/component) from file paths
|
||||
# Author: Git Commit Assistant Plugin
|
||||
# Version: 1.0.0
|
||||
#
|
||||
# Usage:
|
||||
# git diff HEAD --name-only | ./scope-identifier.sh
|
||||
# ./scope-identifier.sh < files.txt
|
||||
#
|
||||
# Returns:
|
||||
# JSON: {"scope": "auth", "confidence": "high", "affected_areas": {...}}
|
||||
#
|
||||
# Exit Codes:
|
||||
# 0 - Success
|
||||
# 1 - No input
|
||||
# 2 - Analysis error
|
||||
|
||||
# Read file paths from stdin
|
||||
files=()
|
||||
while IFS= read -r line; do
|
||||
files+=("$line")
|
||||
done
|
||||
|
||||
if [ ${#files[@]} -eq 0 ]; then
|
||||
echo '{"error": "No files provided", "scope": null}'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Scope counters
|
||||
declare -A scope_counts
|
||||
declare -A scope_files
|
||||
|
||||
# Analyze each file path
|
||||
for file in "${files[@]}"; do
|
||||
# Skip empty lines
|
||||
[ -z "$file" ] && continue
|
||||
|
||||
# Extract scope from path patterns
|
||||
scope=""
|
||||
|
||||
# Pattern 1: src/<scope>/*
|
||||
if [[ "$file" =~ ^src/([^/]+)/ ]]; then
|
||||
scope="${BASH_REMATCH[1]}"
|
||||
# Pattern 2: components/<Component>
|
||||
elif [[ "$file" =~ components/([^/]+) ]]; then
|
||||
# Convert PascalCase to kebab-case
|
||||
component="${BASH_REMATCH[1]}"
|
||||
scope=$(echo "$component" | sed 's/\([A-Z]\)/-\1/g' | tr '[:upper:]' '[:lower:]' | sed 's/^-//')
|
||||
# Pattern 3: tests/<module>
|
||||
elif [[ "$file" =~ tests?/([^/]+) ]]; then
|
||||
scope="${BASH_REMATCH[1]}"
|
||||
scope=$(echo "$scope" | sed 's/\.test.*$//' | sed 's/\.spec.*$//')
|
||||
# Pattern 4: docs/*
|
||||
elif [[ "$file" =~ ^docs?/ ]]; then
|
||||
scope="docs"
|
||||
# Pattern 5: .github/workflows
|
||||
elif [[ "$file" =~ \.github/workflows ]]; then
|
||||
scope="ci"
|
||||
# Pattern 6: config files
|
||||
elif [[ "$file" =~ (package\.json|tsconfig\.json|.*\.config\.(js|ts|json)) ]]; then
|
||||
scope="config"
|
||||
# Pattern 7: root README
|
||||
elif [[ "$file" == "README.md" ]]; then
|
||||
scope="docs"
|
||||
fi
|
||||
|
||||
# Count scopes
|
||||
if [ -n "$scope" ]; then
|
||||
((scope_counts[$scope]++))
|
||||
scope_files[$scope]="${scope_files[$scope]}$file\n"
|
||||
fi
|
||||
done
|
||||
|
||||
# Find primary scope (most files)
|
||||
primary_scope=""
|
||||
max_count=0
|
||||
for scope in "${!scope_counts[@]}"; do
|
||||
count=${scope_counts[$scope]}
|
||||
if [ $count -gt $max_count ]; then
|
||||
max_count=$count
|
||||
primary_scope="$scope"
|
||||
fi
|
||||
done
|
||||
|
||||
# Determine confidence
|
||||
confidence="low"
|
||||
total_files=${#files[@]}
|
||||
if [ -n "$primary_scope" ]; then
|
||||
primary_percentage=$((max_count * 100 / total_files))
|
||||
if [ $primary_percentage -ge 80 ]; then
|
||||
confidence="high"
|
||||
elif [ $primary_percentage -ge 50 ]; then
|
||||
confidence="medium"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Build affected areas JSON
|
||||
affected_areas="{"
|
||||
first=true
|
||||
for scope in "${!scope_counts[@]}"; do
|
||||
if [ "$first" = true ]; then
|
||||
first=false
|
||||
else
|
||||
affected_areas+=","
|
||||
fi
|
||||
affected_areas+="\"$scope\":${scope_counts[$scope]}"
|
||||
done
|
||||
affected_areas+="}"
|
||||
|
||||
# Build reasoning
|
||||
if [ -n "$primary_scope" ]; then
|
||||
reasoning="Primary scope '$primary_scope' identified from $max_count of $total_files files ($primary_percentage%)."
|
||||
else
|
||||
reasoning="Unable to identify clear scope. Files span multiple unrelated areas."
|
||||
fi
|
||||
|
||||
# Output JSON
|
||||
cat <<EOF
|
||||
{
|
||||
"scope": ${primary_scope:+\"$primary_scope\"},
|
||||
"confidence": "$confidence",
|
||||
"reasoning": "$reasoning",
|
||||
"affected_areas": $affected_areas,
|
||||
"total_files": $total_files,
|
||||
"primary_file_count": $max_count,
|
||||
"primary_percentage": ${primary_percentage:-0}
|
||||
}
|
||||
EOF
|
||||
|
||||
exit 0
|
||||
246
commands/commit-analysis/.scripts/type-detector.py
Executable file
246
commands/commit-analysis/.scripts/type-detector.py
Executable file
@@ -0,0 +1,246 @@
|
||||
#!/usr/bin/env python3
|
||||
# Script: type-detector.py
|
||||
# Purpose: Detect conventional commit type from git diff analysis
|
||||
# Author: Git Commit Assistant Plugin
|
||||
# Version: 1.0.0
|
||||
#
|
||||
# Usage:
|
||||
# git diff HEAD | ./type-detector.py
|
||||
# ./type-detector.py < diff.txt
|
||||
#
|
||||
# Returns:
|
||||
# JSON: {"type": "feat", "confidence": "high", "reasoning": "..."}
|
||||
#
|
||||
# Exit Codes:
|
||||
# 0 - Success
|
||||
# 1 - No input provided
|
||||
# 2 - Analysis error
|
||||
|
||||
import sys
|
||||
import re
|
||||
import json
|
||||
|
||||
def detect_type_from_diff(diff_content):
|
||||
"""
|
||||
Detect commit type using priority-based decision tree.
|
||||
|
||||
Priority order:
|
||||
1. feat - new files/functions
|
||||
2. fix - bug fixes/error handling
|
||||
3. docs - documentation only
|
||||
4. refactor - code restructuring
|
||||
5. style - formatting only
|
||||
6. test - test files only
|
||||
7. build - dependencies
|
||||
8. ci - CI/CD configs
|
||||
9. perf - performance
|
||||
10. chore - other
|
||||
"""
|
||||
|
||||
lines = diff_content.split('\n')
|
||||
|
||||
# Indicators
|
||||
indicators = {
|
||||
'new_files': 0,
|
||||
'new_exports': 0,
|
||||
'bug_keywords': 0,
|
||||
'error_handling': 0,
|
||||
'docs_only': True,
|
||||
'test_only': True,
|
||||
'formatting_only': True,
|
||||
'build_files': 0,
|
||||
'ci_files': 0,
|
||||
'perf_keywords': 0,
|
||||
'refactor_keywords': 0
|
||||
}
|
||||
|
||||
changed_files = []
|
||||
|
||||
for line in lines:
|
||||
# Track changed files
|
||||
if line.startswith('+++') or line.startswith('---'):
|
||||
file_path = line[4:].strip()
|
||||
if file_path != '/dev/null':
|
||||
changed_files.append(file_path)
|
||||
|
||||
# New file indicator
|
||||
if line.startswith('+++ ') and '/dev/null' not in line:
|
||||
if line.startswith('+++ b/'):
|
||||
indicators['new_files'] += 1
|
||||
|
||||
# New exports (feat indicator)
|
||||
if line.startswith('+') and ('export function' in line or 'export class' in line or 'export const' in line):
|
||||
indicators['new_exports'] += 1
|
||||
|
||||
# Bug fix keywords
|
||||
if line.startswith('+') and any(kw in line.lower() for kw in ['fix', 'resolve', 'correct', 'handle error']):
|
||||
indicators['bug_keywords'] += 1
|
||||
|
||||
# Error handling (fix indicator)
|
||||
if line.startswith('+') and ('try {' in line or 'catch' in line or 'if (! in line or 'throw' in line):
|
||||
indicators['error_handling'] += 1
|
||||
|
||||
# Check if only docs changed
|
||||
if line.startswith('+++') and not line.endswith('.md') and not '# ' in line:
|
||||
if '/dev/null' not in line:
|
||||
indicators['docs_only'] = False
|
||||
|
||||
# Check if only tests changed
|
||||
if line.startswith('+++'):
|
||||
if not ('.test.' in line or '.spec.' in line or '_test' in line):
|
||||
if '/dev/null' not in line:
|
||||
indicators['test_only'] = False
|
||||
|
||||
# Check if only formatting
|
||||
if line.startswith('+') and len(line.strip()) > 1:
|
||||
stripped = line[1:].strip()
|
||||
if stripped and not stripped.isspace():
|
||||
indicators['formatting_only'] = False
|
||||
|
||||
# Build files (package.json, etc.)
|
||||
if 'package.json' in line or 'pom.xml' in line or 'build.gradle' in line:
|
||||
indicators['build_files'] += 1
|
||||
|
||||
# CI files
|
||||
if '.github/workflows' in line or '.gitlab-ci' in line or 'Jenkinsfile' in line:
|
||||
indicators['ci_files'] += 1
|
||||
|
||||
# Performance keywords
|
||||
if line.startswith('+') and any(kw in line.lower() for kw in ['optimize', 'cache', 'memoize', 'performance']):
|
||||
indicators['perf_keywords'] += 1
|
||||
|
||||
# Refactor keywords
|
||||
if line.startswith('+') and any(kw in line.lower() for kw in ['extract', 'rename', 'simplify', 'reorganize']):
|
||||
indicators['refactor_keywords'] += 1
|
||||
|
||||
# Decision tree
|
||||
|
||||
# 1. Check for feat
|
||||
if indicators['new_files'] > 0 or indicators['new_exports'] > 2:
|
||||
return {
|
||||
'type': 'feat',
|
||||
'confidence': 'high' if indicators['new_files'] > 0 else 'medium',
|
||||
'reasoning': f"New files ({indicators['new_files']}) or new exports ({indicators['new_exports']}) detected. Indicates new feature.",
|
||||
'indicators': {
|
||||
'new_files': indicators['new_files'],
|
||||
'new_exports': indicators['new_exports']
|
||||
}
|
||||
}
|
||||
|
||||
# 2. Check for fix
|
||||
if indicators['error_handling'] > 2 or indicators['bug_keywords'] > 1:
|
||||
return {
|
||||
'type': 'fix',
|
||||
'confidence': 'high',
|
||||
'reasoning': f"Error handling ({indicators['error_handling']}) or bug fix keywords ({indicators['bug_keywords']}) found. Indicates bug fix.",
|
||||
'indicators': {
|
||||
'error_handling': indicators['error_handling'],
|
||||
'bug_keywords': indicators['bug_keywords']
|
||||
}
|
||||
}
|
||||
|
||||
# 3. Check for docs
|
||||
if indicators['docs_only']:
|
||||
return {
|
||||
'type': 'docs',
|
||||
'confidence': 'high',
|
||||
'reasoning': "Only documentation files (.md) changed. Pure documentation update.",
|
||||
'indicators': {}
|
||||
}
|
||||
|
||||
# 4. Check for style
|
||||
if indicators['formatting_only']:
|
||||
return {
|
||||
'type': 'style',
|
||||
'confidence': 'high',
|
||||
'reasoning': "Only formatting/whitespace changes detected. No logic changes.",
|
||||
'indicators': {}
|
||||
}
|
||||
|
||||
# 5. Check for test
|
||||
if indicators['test_only']:
|
||||
return {
|
||||
'type': 'test',
|
||||
'confidence': 'high',
|
||||
'reasoning': "Only test files changed. Test additions or updates.",
|
||||
'indicators': {}
|
||||
}
|
||||
|
||||
# 6. Check for build
|
||||
if indicators['build_files'] > 0:
|
||||
return {
|
||||
'type': 'build',
|
||||
'confidence': 'high',
|
||||
'reasoning': f"Build files ({indicators['build_files']}) changed. Dependency or build system updates.",
|
||||
'indicators': {
|
||||
'build_files': indicators['build_files']
|
||||
}
|
||||
}
|
||||
|
||||
# 7. Check for ci
|
||||
if indicators['ci_files'] > 0:
|
||||
return {
|
||||
'type': 'ci',
|
||||
'confidence': 'high',
|
||||
'reasoning': f"CI/CD configuration files ({indicators['ci_files']}) changed.",
|
||||
'indicators': {
|
||||
'ci_files': indicators['ci_files']
|
||||
}
|
||||
}
|
||||
|
||||
# 8. Check for perf
|
||||
if indicators['perf_keywords'] > 2:
|
||||
return {
|
||||
'type': 'perf',
|
||||
'confidence': 'medium',
|
||||
'reasoning': f"Performance-related keywords ({indicators['perf_keywords']}) found.",
|
||||
'indicators': {
|
||||
'perf_keywords': indicators['perf_keywords']
|
||||
}
|
||||
}
|
||||
|
||||
# 9. Check for refactor
|
||||
if indicators['refactor_keywords'] > 2:
|
||||
return {
|
||||
'type': 'refactor',
|
||||
'confidence': 'medium',
|
||||
'reasoning': f"Refactoring keywords ({indicators['refactor_keywords']}) found.",
|
||||
'indicators': {
|
||||
'refactor_keywords': indicators['refactor_keywords']
|
||||
}
|
||||
}
|
||||
|
||||
# 10. Default to chore
|
||||
return {
|
||||
'type': 'chore',
|
||||
'confidence': 'low',
|
||||
'reasoning': "Changes don't match specific patterns. Defaulting to chore.",
|
||||
'indicators': {}
|
||||
}
|
||||
|
||||
def main():
|
||||
# Read diff from stdin
|
||||
diff_content = sys.stdin.read()
|
||||
|
||||
if not diff_content or not diff_content.strip():
|
||||
print(json.dumps({
|
||||
'error': 'No diff content provided',
|
||||
'type': None,
|
||||
'confidence': None
|
||||
}))
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
result = detect_type_from_diff(diff_content)
|
||||
print(json.dumps(result, indent=2))
|
||||
sys.exit(0)
|
||||
except Exception as e:
|
||||
print(json.dumps({
|
||||
'error': str(e),
|
||||
'type': None,
|
||||
'confidence': None
|
||||
}))
|
||||
sys.exit(2)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
196
commands/commit-analysis/analyze-changes.md
Normal file
196
commands/commit-analysis/analyze-changes.md
Normal file
@@ -0,0 +1,196 @@
|
||||
---
|
||||
description: Perform comprehensive analysis of git changes including type, scope, and atomicity
|
||||
---
|
||||
|
||||
# Operation: Analyze Changes
|
||||
|
||||
Perform full analysis of git repository changes to understand the nature, scope, commit type, and whether changes are atomic.
|
||||
|
||||
## Parameters from $ARGUMENTS
|
||||
|
||||
No parameters required. Analyzes all current changes.
|
||||
|
||||
## Workflow
|
||||
|
||||
### Step 1: Verify Git Repository
|
||||
|
||||
```bash
|
||||
git rev-parse --git-dir 2>/dev/null
|
||||
```
|
||||
|
||||
If this fails:
|
||||
- Return error: "Not a git repository. Run 'git init' to initialize."
|
||||
- Exit operation
|
||||
|
||||
### Step 2: Check for Changes
|
||||
|
||||
```bash
|
||||
git status --short
|
||||
```
|
||||
|
||||
If no changes:
|
||||
- Return: "No changes to analyze. Working tree is clean."
|
||||
- Exit operation
|
||||
|
||||
### Step 3: Gather Change Information
|
||||
|
||||
Run git commands to collect comprehensive data:
|
||||
|
||||
```bash
|
||||
# Get detailed diff
|
||||
git diff HEAD
|
||||
|
||||
# Get status summary
|
||||
git status --short
|
||||
|
||||
# Get diff statistics
|
||||
git diff --stat HEAD
|
||||
|
||||
# Count changed files
|
||||
git status --short | wc -l
|
||||
```
|
||||
|
||||
### Step 4: Invoke Analysis Scripts
|
||||
|
||||
Execute utility scripts to analyze different aspects:
|
||||
|
||||
**Type Detection:**
|
||||
```bash
|
||||
# Run type detector script
|
||||
.scripts/type-detector.py
|
||||
```
|
||||
This script analyzes the diff output and returns the primary commit type (feat, fix, docs, etc.)
|
||||
|
||||
**Scope Identification:**
|
||||
```bash
|
||||
# Run scope identifier
|
||||
.scripts/scope-identifier.sh
|
||||
```
|
||||
This script identifies the primary module/component affected
|
||||
|
||||
**Atomicity Assessment:**
|
||||
```bash
|
||||
# Run atomicity checker
|
||||
.scripts/atomicity-checker.py
|
||||
```
|
||||
This script determines if changes should be split into multiple commits
|
||||
|
||||
**Diff Analysis:**
|
||||
```bash
|
||||
# Run git diff analyzer
|
||||
.scripts/git-diff-analyzer.sh
|
||||
```
|
||||
This script parses diff output for detailed file and line change information
|
||||
|
||||
### Step 5: Compile Analysis Report
|
||||
|
||||
Format comprehensive analysis:
|
||||
|
||||
```
|
||||
COMMIT ANALYSIS REPORT
|
||||
═══════════════════════════════════════════════
|
||||
|
||||
CHANGE SUMMARY:
|
||||
───────────────────────────────────────────────
|
||||
Files Changed: X files
|
||||
Insertions: +XXX lines
|
||||
Deletions: -XXX lines
|
||||
Net Change: ±XXX lines
|
||||
|
||||
COMMIT TYPE DETECTION:
|
||||
───────────────────────────────────────────────
|
||||
Primary Type: <feat|fix|docs|refactor|style|test|chore|perf|ci>
|
||||
Confidence: <High|Medium|Low>
|
||||
Reasoning: <explanation of why this type was chosen>
|
||||
|
||||
Alternative Types: <if applicable>
|
||||
|
||||
SCOPE IDENTIFICATION:
|
||||
───────────────────────────────────────────────
|
||||
Primary Scope: <module/component name>
|
||||
Affected Areas: <list of all affected areas>
|
||||
Scope Confidence: <High|Medium|Low>
|
||||
|
||||
ATOMICITY ASSESSMENT:
|
||||
───────────────────────────────────────────────
|
||||
Status: <Atomic|Should Split>
|
||||
Reasoning: <explanation>
|
||||
|
||||
If Should Split:
|
||||
Recommended Splits:
|
||||
1. <type>(<scope>): <description> - X files
|
||||
2. <type>(<scope>): <description> - X files
|
||||
...
|
||||
|
||||
FILE BREAKDOWN:
|
||||
───────────────────────────────────────────────
|
||||
<list files grouped by type/scope>
|
||||
|
||||
New Files: <count>
|
||||
- <file1>
|
||||
- <file2>
|
||||
|
||||
Modified Files: <count>
|
||||
- <file1> (+XX -YY)
|
||||
- <file2> (+XX -YY)
|
||||
|
||||
Deleted Files: <count>
|
||||
- <file1>
|
||||
|
||||
RECOMMENDATIONS:
|
||||
───────────────────────────────────────────────
|
||||
- <recommendation 1>
|
||||
- <recommendation 2>
|
||||
- <recommendation 3>
|
||||
|
||||
═══════════════════════════════════════════════
|
||||
```
|
||||
|
||||
## Output Format
|
||||
|
||||
Return structured analysis with:
|
||||
- Change statistics
|
||||
- Detected commit type with confidence level
|
||||
- Identified scope
|
||||
- Atomicity assessment
|
||||
- File breakdown
|
||||
- Specific recommendations
|
||||
|
||||
## Error Handling
|
||||
|
||||
**Not a git repository:**
|
||||
```
|
||||
ERROR: Not a git repository
|
||||
Initialize with: git init
|
||||
```
|
||||
|
||||
**No changes to analyze:**
|
||||
```
|
||||
NO CHANGES
|
||||
Working tree is clean. Make changes before analyzing.
|
||||
```
|
||||
|
||||
**Git command fails:**
|
||||
```
|
||||
ERROR: Git command failed
|
||||
<error message>
|
||||
Ensure git is properly configured.
|
||||
```
|
||||
|
||||
## Integration with Agent
|
||||
|
||||
The commit-assistant agent uses this operation to:
|
||||
1. Understand change nature before suggesting commits
|
||||
2. Determine if changes are atomic or need splitting
|
||||
3. Identify appropriate commit type and scope
|
||||
4. Provide context for message generation
|
||||
|
||||
## Usage Example
|
||||
|
||||
```bash
|
||||
# Agent workflow:
|
||||
# User: "analyze my changes"
|
||||
# Agent invokes: analyze-changes operation
|
||||
# Operation returns comprehensive report
|
||||
# Agent presents findings to user
|
||||
```
|
||||
363
commands/commit-analysis/assess-atomicity.md
Normal file
363
commands/commit-analysis/assess-atomicity.md
Normal file
@@ -0,0 +1,363 @@
|
||||
---
|
||||
description: Assess if changes are atomic (single logical change) or should be split into multiple commits
|
||||
---
|
||||
|
||||
# Operation: Assess Atomicity
|
||||
|
||||
Determine if changes form an atomic commit (single logical change) or should be split into multiple focused commits.
|
||||
|
||||
## Parameters from $ARGUMENTS
|
||||
|
||||
No parameters required. Analyzes all current changes.
|
||||
|
||||
## Workflow
|
||||
|
||||
### Step 1: Gather Change Data
|
||||
|
||||
```bash
|
||||
git status --short
|
||||
git diff HEAD --stat
|
||||
git diff HEAD
|
||||
```
|
||||
|
||||
### Step 2: Run Atomicity Analysis
|
||||
|
||||
Execute atomicity checker script:
|
||||
|
||||
```bash
|
||||
git diff HEAD | .scripts/atomicity-checker.py
|
||||
```
|
||||
|
||||
The script analyzes:
|
||||
- Number of files changed
|
||||
- Types of changes (feat, fix, docs, etc.)
|
||||
- Scopes affected
|
||||
- Interdependencies
|
||||
- Logical cohesion
|
||||
|
||||
### Step 3: Atomicity Criteria
|
||||
|
||||
**Atomic Commit** (single commit appropriate):
|
||||
- All changes serve ONE logical purpose
|
||||
- All files relate to the same feature/fix
|
||||
- Changes are interdependent
|
||||
- Same type throughout (all feat, or all fix)
|
||||
- Same scope throughout (all auth, or all api)
|
||||
- Can be reverted as a complete unit
|
||||
- Tests pass after commit
|
||||
|
||||
**Non-Atomic** (should split):
|
||||
- Multiple distinct types (feat + fix + docs)
|
||||
- Multiple unrelated scopes (auth + api + ui)
|
||||
- Mixing concerns (feature + refactoring + bug fix)
|
||||
- Too many files (10+ unrelated files)
|
||||
- Multiple stories being told
|
||||
|
||||
### Step 4: Splitting Recommendations
|
||||
|
||||
If non-atomic, suggest how to split:
|
||||
|
||||
**By Type:**
|
||||
```
|
||||
Split into commits by change type:
|
||||
1. feat(auth): OAuth implementation (5 files)
|
||||
2. test(auth): OAuth tests (2 files)
|
||||
3. docs: authentication guide (1 file)
|
||||
```
|
||||
|
||||
**By Scope:**
|
||||
```
|
||||
Split into commits by module:
|
||||
1. feat(auth): authentication system (6 files)
|
||||
2. feat(api): user API endpoints (4 files)
|
||||
3. feat(ui): login components (3 files)
|
||||
```
|
||||
|
||||
**By Feature:**
|
||||
```
|
||||
Split into commits by logical unit:
|
||||
1. feat(payments): Stripe integration (8 files)
|
||||
2. feat(payments): PayPal integration (6 files)
|
||||
3. test(payments): payment tests (4 files)
|
||||
```
|
||||
|
||||
### Step 5: Format Atomicity Assessment
|
||||
|
||||
```
|
||||
ATOMICITY ASSESSMENT
|
||||
═══════════════════════════════════════════════
|
||||
|
||||
STATUS: <ATOMIC | SHOULD SPLIT>
|
||||
|
||||
ANALYSIS:
|
||||
───────────────────────────────────────────────
|
||||
Files Changed: X
|
||||
Lines Changed: +XXX -XXX
|
||||
|
||||
Type Diversity: <Single | Multiple>
|
||||
Scope Diversity: <Single | Multiple>
|
||||
Logical Cohesion: <High | Medium | Low>
|
||||
|
||||
ATOMICITY CHECKS:
|
||||
───────────────────────────────────────────────
|
||||
✓ Single logical purpose
|
||||
✓ Related files only
|
||||
✓ Same change type
|
||||
✓ Same scope
|
||||
✓ Interdependent changes
|
||||
✓ Complete unit
|
||||
✓ Can be reverted independently
|
||||
|
||||
OR
|
||||
|
||||
✗ Multiple purposes detected
|
||||
✗ Unrelated files mixed
|
||||
✗ Multiple change types
|
||||
✗ Multiple scopes
|
||||
✗ Independent changes
|
||||
✗ Incomplete without splits
|
||||
|
||||
REASONING:
|
||||
───────────────────────────────────────────────
|
||||
<detailed explanation>
|
||||
|
||||
If ATOMIC:
|
||||
All changes implement [specific feature/fix].
|
||||
Files work together and depend on each other.
|
||||
Single commit tells a clear, focused story.
|
||||
|
||||
If SHOULD SPLIT:
|
||||
Changes address multiple concerns:
|
||||
1. <concern 1>
|
||||
2. <concern 2>
|
||||
3. <concern 3>
|
||||
|
||||
Each concern should be a separate commit.
|
||||
|
||||
SPLITTING RECOMMENDATIONS:
|
||||
───────────────────────────────────────────────
|
||||
<if should split>
|
||||
|
||||
Recommended Commits:
|
||||
|
||||
Commit 1: <type>(<scope>): <description>
|
||||
Files: X files
|
||||
Purpose: <specific purpose>
|
||||
Files:
|
||||
- file1.js
|
||||
- file2.js
|
||||
Lines: +XX -YY
|
||||
|
||||
Commit 2: <type>(<scope>): <description>
|
||||
Files: X files
|
||||
Purpose: <specific purpose>
|
||||
Files:
|
||||
- file3.js
|
||||
- file4.js
|
||||
Lines: +XX -YY
|
||||
|
||||
BENEFITS OF SPLITTING:
|
||||
───────────────────────────────────────────────
|
||||
<if should split>
|
||||
- Better code review (focused changes)
|
||||
- Easier to revert individual features
|
||||
- Clearer git history
|
||||
- Better bisecting for bugs
|
||||
- Easier cherry-picking
|
||||
|
||||
RECOMMENDATION:
|
||||
───────────────────────────────────────────────
|
||||
<specific actionable recommendation>
|
||||
|
||||
═══════════════════════════════════════════════
|
||||
```
|
||||
|
||||
## Detailed Atomicity Rules
|
||||
|
||||
### Rule 1: Single Purpose Test
|
||||
**Question:** Can you describe ALL changes in one sentence?
|
||||
|
||||
**Atomic Examples:**
|
||||
- "Add OAuth authentication"
|
||||
- "Fix null pointer in user endpoint"
|
||||
- "Refactor date utility functions"
|
||||
|
||||
**Non-Atomic Examples:**
|
||||
- "Add OAuth and fix login bug and update README"
|
||||
- "Implement payment and refactor utils and add tests"
|
||||
|
||||
### Rule 2: Type Consistency
|
||||
**Atomic:**
|
||||
- All files are "feat" type
|
||||
- All files are "fix" type
|
||||
- All files are "refactor" type
|
||||
|
||||
**Non-Atomic:**
|
||||
- Mix of feat + fix
|
||||
- Mix of refactor + feat
|
||||
- Mix of docs + code changes (exception: docs can accompany code)
|
||||
|
||||
### Rule 3: Scope Consistency
|
||||
**Atomic:**
|
||||
- All changes in "auth" module
|
||||
- All changes in "api" module
|
||||
- All changes in "ui/components"
|
||||
|
||||
**Non-Atomic:**
|
||||
- Changes in auth + api + ui
|
||||
- Changes in multiple unrelated modules
|
||||
|
||||
### Rule 4: Revert Independence
|
||||
**Test:** If reverted, does it break unrelated functionality?
|
||||
|
||||
**Atomic:**
|
||||
- Can be reverted without breaking other features
|
||||
- Forms a complete, self-contained unit
|
||||
|
||||
**Non-Atomic:**
|
||||
- Reverting breaks unrelated features
|
||||
- Mixes independent changes
|
||||
|
||||
### Rule 5: Review Simplicity
|
||||
**Atomic:**
|
||||
- Reviewer can focus on one logical change
|
||||
- Clear what and why
|
||||
- Single story
|
||||
|
||||
**Non-Atomic:**
|
||||
- Reviewer must context-switch between multiple concerns
|
||||
- Multiple stories mixed together
|
||||
|
||||
## File Count Guidelines
|
||||
|
||||
**Generally Atomic:**
|
||||
- 1-5 files: Usually focused
|
||||
- 5-10 files: Check cohesion carefully
|
||||
- 10-15 files: Likely needs splitting unless tightly coupled
|
||||
|
||||
**Usually Non-Atomic:**
|
||||
- 15+ files: Almost always should split
|
||||
- 20+ files: Definitely split
|
||||
|
||||
**Exceptions:**
|
||||
- Large refactoring may touch many files atomically
|
||||
- Package updates may affect many files atomically
|
||||
- Renaming across project may touch many files atomically
|
||||
|
||||
## Edge Cases
|
||||
|
||||
### Case 1: Feature + Tests
|
||||
**Atomic?** Usually YES
|
||||
- Tests directly validate the feature code
|
||||
- They tell the same story
|
||||
- Can be reverted together
|
||||
|
||||
**Example:**
|
||||
```
|
||||
feat(auth): implement OAuth authentication
|
||||
- 5 implementation files
|
||||
- 2 test files
|
||||
→ ATOMIC (7 files, same feature)
|
||||
```
|
||||
|
||||
### Case 2: Feature + Documentation
|
||||
**Atomic?** DEPENDS
|
||||
- If docs describe the feature: YES
|
||||
- If docs are unrelated updates: NO
|
||||
|
||||
**Example:**
|
||||
```
|
||||
feat(auth): add OAuth support
|
||||
- 5 auth files
|
||||
- 1 auth documentation file
|
||||
→ ATOMIC (documents the feature)
|
||||
|
||||
vs.
|
||||
|
||||
feat(auth): add OAuth support
|
||||
- 5 auth files
|
||||
- README general update
|
||||
→ NON-ATOMIC (split docs)
|
||||
```
|
||||
|
||||
### Case 3: Refactoring + New Feature
|
||||
**Atomic?** NO
|
||||
- Refactoring should be separate
|
||||
- Makes review harder
|
||||
- Mixing concerns
|
||||
|
||||
**Example:**
|
||||
```
|
||||
Changes:
|
||||
- Refactor utils (3 files)
|
||||
- Add new payment feature (5 files)
|
||||
→ NON-ATOMIC
|
||||
|
||||
Split:
|
||||
1. refactor(utils): simplify utility functions
|
||||
2. feat(payments): add Stripe integration
|
||||
```
|
||||
|
||||
### Case 4: Multiple Small Fixes
|
||||
**Atomic?** DEPENDS
|
||||
- If all in same module: MAYBE
|
||||
- If unrelated: NO
|
||||
|
||||
**Example:**
|
||||
```
|
||||
fix(auth): resolve three auth-related bugs
|
||||
- All in auth module
|
||||
- All are fixes
|
||||
- Related to each other
|
||||
→ ATOMIC
|
||||
|
||||
vs.
|
||||
|
||||
- Fix auth bug
|
||||
- Fix API bug
|
||||
- Fix UI bug
|
||||
→ NON-ATOMIC (different scopes)
|
||||
```
|
||||
|
||||
## Output Format
|
||||
|
||||
Return:
|
||||
- Atomicity status (ATOMIC or SHOULD SPLIT)
|
||||
- Detailed analysis and reasoning
|
||||
- Atomicity checks (passed/failed)
|
||||
- Splitting recommendations if needed
|
||||
- Benefits explanation
|
||||
- Specific recommendation
|
||||
|
||||
## Error Handling
|
||||
|
||||
**No changes:**
|
||||
```
|
||||
NO CHANGES TO ASSESS
|
||||
Working tree is clean.
|
||||
```
|
||||
|
||||
**Single file change:**
|
||||
```
|
||||
ATOMIC (Single File)
|
||||
One file changed: <filename>
|
||||
Automatically atomic.
|
||||
```
|
||||
|
||||
## Integration with Agent
|
||||
|
||||
The commit-assistant agent uses this operation to:
|
||||
1. Determine if /commit or /commit-split should be used
|
||||
2. Warn users about non-atomic changes
|
||||
3. Provide splitting guidance
|
||||
4. Educate users on atomic commit benefits
|
||||
|
||||
## Usage Example
|
||||
|
||||
```bash
|
||||
# Agent checks atomicity before committing
|
||||
# User: "commit my changes"
|
||||
# Agent: Invokes assess-atomicity
|
||||
# Operation: Returns "SHOULD SPLIT"
|
||||
# Agent: "Your changes should be split. Run /commit-review"
|
||||
```
|
||||
341
commands/commit-analysis/detect-type.md
Normal file
341
commands/commit-analysis/detect-type.md
Normal file
@@ -0,0 +1,341 @@
|
||||
---
|
||||
description: Detect the appropriate conventional commit type based on git diff analysis
|
||||
---
|
||||
|
||||
# Operation: Detect Commit Type
|
||||
|
||||
Analyze git changes to determine the conventional commit type (feat, fix, docs, refactor, style, test, chore, perf, ci).
|
||||
|
||||
## Parameters from $ARGUMENTS
|
||||
|
||||
No parameters required. Analyzes current git diff.
|
||||
|
||||
## Workflow
|
||||
|
||||
### Step 1: Verify Git Repository and Changes
|
||||
|
||||
```bash
|
||||
git rev-parse --git-dir 2>/dev/null
|
||||
git diff HEAD
|
||||
```
|
||||
|
||||
If no repository or no changes, exit with appropriate message.
|
||||
|
||||
### Step 2: Run Type Detection Algorithm
|
||||
|
||||
Execute the type detector script with git diff output:
|
||||
|
||||
```bash
|
||||
git diff HEAD | .scripts/type-detector.py
|
||||
```
|
||||
|
||||
The script implements the decision tree algorithm:
|
||||
|
||||
### Detection Algorithm (Implemented in type-detector.py)
|
||||
|
||||
```
|
||||
Priority Order (check in sequence):
|
||||
|
||||
1. Check for new files or new exports
|
||||
→ IF new files OR new functions/classes/exports
|
||||
→ RETURN "feat"
|
||||
|
||||
2. Check for bug fixes
|
||||
→ IF error handling OR bug keywords (fix, resolve, correct)
|
||||
→ RETURN "fix"
|
||||
|
||||
3. Check for docs-only changes
|
||||
→ IF only .md files OR only comments changed
|
||||
→ RETURN "docs"
|
||||
|
||||
4. Check for code restructuring
|
||||
→ IF code moved/renamed but no behavior change
|
||||
→ RETURN "refactor"
|
||||
|
||||
5. Check for style changes
|
||||
→ IF only whitespace OR formatting changed
|
||||
→ RETURN "style"
|
||||
|
||||
6. Check for test changes
|
||||
→ IF only test files changed
|
||||
→ RETURN "test"
|
||||
|
||||
7. Check for dependency changes
|
||||
→ IF package.json OR build files changed
|
||||
→ RETURN "build"
|
||||
|
||||
8. Check for CI changes
|
||||
→ IF .github/workflows OR CI configs changed
|
||||
→ RETURN "ci"
|
||||
|
||||
9. Check for performance improvements
|
||||
→ IF optimization keywords OR caching added
|
||||
→ RETURN "perf"
|
||||
|
||||
10. Default
|
||||
→ RETURN "chore"
|
||||
```
|
||||
|
||||
### Step 3: Analyze Confidence Level
|
||||
|
||||
Determine confidence in the detected type:
|
||||
|
||||
**High Confidence:**
|
||||
- Only one type detected
|
||||
- Clear indicators present
|
||||
- No ambiguity
|
||||
|
||||
**Medium Confidence:**
|
||||
- Multiple possible types
|
||||
- Mixed indicators
|
||||
- Requires human judgment
|
||||
|
||||
**Low Confidence:**
|
||||
- Unclear changes
|
||||
- Multiple types with equal weight
|
||||
- Recommend manual review
|
||||
|
||||
### Step 4: Identify Alternative Types
|
||||
|
||||
If changes could fit multiple types, list alternatives:
|
||||
|
||||
```
|
||||
Primary: feat (High confidence)
|
||||
Alternatives:
|
||||
- test (if test files are significant)
|
||||
- docs (if documentation is substantial)
|
||||
```
|
||||
|
||||
### Step 5: Format Detection Result
|
||||
|
||||
Return structured type detection:
|
||||
|
||||
```
|
||||
COMMIT TYPE DETECTION
|
||||
═══════════════════════════════════════════════
|
||||
|
||||
DETECTED TYPE: <type>
|
||||
CONFIDENCE: <High|Medium|Low>
|
||||
|
||||
REASONING:
|
||||
───────────────────────────────────────────────
|
||||
<detailed explanation of why this type was chosen>
|
||||
|
||||
Key Indicators:
|
||||
- <indicator 1>
|
||||
- <indicator 2>
|
||||
- <indicator 3>
|
||||
|
||||
FILE ANALYSIS:
|
||||
───────────────────────────────────────────────
|
||||
New Files: X (suggests feat)
|
||||
Bug Fixes: X (suggests fix)
|
||||
Documentation: X (suggests docs)
|
||||
Refactoring: X (suggests refactor)
|
||||
Formatting: X (suggests style)
|
||||
Tests: X (suggests test)
|
||||
Dependencies: X (suggests build/chore)
|
||||
CI/CD: X (suggests ci)
|
||||
|
||||
ALTERNATIVE TYPES:
|
||||
───────────────────────────────────────────────
|
||||
<if applicable>
|
||||
- <type>: <reasoning>
|
||||
|
||||
RECOMMENDATION:
|
||||
───────────────────────────────────────────────
|
||||
<specific recommendation based on analysis>
|
||||
|
||||
═══════════════════════════════════════════════
|
||||
```
|
||||
|
||||
## Type Detection Rules
|
||||
|
||||
### feat (Feature)
|
||||
**Indicators:**
|
||||
- New files created
|
||||
- New functions/classes exported
|
||||
- New functionality added
|
||||
- New components/modules
|
||||
- Keywords: "add", "implement", "introduce", "create"
|
||||
|
||||
**Example Patterns:**
|
||||
```diff
|
||||
+export function newFeature() {
|
||||
+export class NewComponent {
|
||||
+++ new-file.js
|
||||
```
|
||||
|
||||
### fix (Bug Fix)
|
||||
**Indicators:**
|
||||
- Error handling added
|
||||
- Null/undefined checks
|
||||
- Validation corrections
|
||||
- Bug keywords in code
|
||||
- Keywords: "fix", "resolve", "correct", "handle"
|
||||
|
||||
**Example Patterns:**
|
||||
```diff
|
||||
+if (!value) throw new Error
|
||||
+try { ... } catch
|
||||
-return null
|
||||
+return value || default
|
||||
```
|
||||
|
||||
### docs (Documentation)
|
||||
**Indicators:**
|
||||
- Only .md files changed
|
||||
- Only comments changed
|
||||
- JSDoc additions
|
||||
- README updates
|
||||
- No code logic changes
|
||||
|
||||
**Example Patterns:**
|
||||
```diff
|
||||
+++ README.md
|
||||
+// This function does...
|
||||
+/** @param {string} name */
|
||||
```
|
||||
|
||||
### refactor (Code Restructuring)
|
||||
**Indicators:**
|
||||
- Code moved/reorganized
|
||||
- Variables/functions renamed
|
||||
- Logic extracted
|
||||
- No behavior change
|
||||
- Keywords: "extract", "rename", "simplify", "reorganize"
|
||||
|
||||
**Example Patterns:**
|
||||
```diff
|
||||
-function oldName() {
|
||||
+function newName() {
|
||||
-inline code block
|
||||
+extractedFunction()
|
||||
```
|
||||
|
||||
### style (Formatting)
|
||||
**Indicators:**
|
||||
- Only whitespace changes
|
||||
- Indentation fixes
|
||||
- Semicolon additions/removals
|
||||
- Code formatting
|
||||
- No logic changes
|
||||
|
||||
**Example Patterns:**
|
||||
```diff
|
||||
- const x = 1
|
||||
+ const x = 1;
|
||||
-function(a,b) {
|
||||
+function(a, b) {
|
||||
```
|
||||
|
||||
### test (Tests)
|
||||
**Indicators:**
|
||||
- Only test files changed (.test.js, .spec.js, _test.py)
|
||||
- Test additions/updates
|
||||
- Mock/fixture changes
|
||||
- Keywords: "describe", "it", "test", "expect"
|
||||
|
||||
**Example Patterns:**
|
||||
```diff
|
||||
+++ tests/feature.test.js
|
||||
+describe('Feature', () => {
|
||||
+it('should work', () => {
|
||||
```
|
||||
|
||||
### build (Build System)
|
||||
**Indicators:**
|
||||
- package.json changes
|
||||
- Dependency updates
|
||||
- Build configuration
|
||||
- Build scripts
|
||||
|
||||
**Example Patterns:**
|
||||
```diff
|
||||
+++ package.json
|
||||
+"dependencies": {
|
||||
+ "new-lib": "^1.0.0"
|
||||
```
|
||||
|
||||
### ci (CI/CD)
|
||||
**Indicators:**
|
||||
- .github/workflows changes
|
||||
- .gitlab-ci.yml changes
|
||||
- CI configuration
|
||||
- Deployment scripts
|
||||
|
||||
**Example Patterns:**
|
||||
```diff
|
||||
+++ .github/workflows/test.yml
|
||||
+++ .gitlab-ci.yml
|
||||
```
|
||||
|
||||
### perf (Performance)
|
||||
**Indicators:**
|
||||
- Optimization changes
|
||||
- Caching implementation
|
||||
- Algorithm improvements
|
||||
- Keywords: "optimize", "cache", "performance", "faster"
|
||||
|
||||
**Example Patterns:**
|
||||
```diff
|
||||
+const cache = new Map()
|
||||
+if (cache.has(key)) return cache.get(key)
|
||||
-O(n²) algorithm
|
||||
+O(n log n) algorithm
|
||||
```
|
||||
|
||||
### chore (Other)
|
||||
**Indicators:**
|
||||
- Maintenance tasks
|
||||
- Tooling configuration
|
||||
- Repository housekeeping
|
||||
- Doesn't fit other types
|
||||
|
||||
## Output Format
|
||||
|
||||
Return:
|
||||
- Detected type
|
||||
- Confidence level
|
||||
- Detailed reasoning
|
||||
- Key indicators found
|
||||
- Alternative types (if any)
|
||||
- Specific recommendation
|
||||
|
||||
## Error Handling
|
||||
|
||||
**No changes:**
|
||||
```
|
||||
NO CHANGES TO ANALYZE
|
||||
Working tree is clean.
|
||||
```
|
||||
|
||||
**Ambiguous changes:**
|
||||
```
|
||||
AMBIGUOUS TYPE DETECTION
|
||||
Multiple types detected with equal weight.
|
||||
Manual review recommended.
|
||||
|
||||
Detected types:
|
||||
- feat (40%)
|
||||
- refactor (35%)
|
||||
- test (25%)
|
||||
```
|
||||
|
||||
## Integration with Agent
|
||||
|
||||
The commit-assistant agent uses this operation to:
|
||||
1. Automatically determine commit type
|
||||
2. Validate user-provided types
|
||||
3. Suggest alternative types if ambiguous
|
||||
4. Guide users in type selection
|
||||
|
||||
## Usage Example
|
||||
|
||||
```bash
|
||||
# Agent detects type before generating message
|
||||
# User: "commit these changes"
|
||||
# Agent: Invokes detect-type
|
||||
# Operation: Returns "feat" with high confidence
|
||||
# Agent: Generates message with "feat" type
|
||||
```
|
||||
327
commands/commit-analysis/file-stats.md
Normal file
327
commands/commit-analysis/file-stats.md
Normal file
@@ -0,0 +1,327 @@
|
||||
---
|
||||
description: Get detailed file change statistics for commit analysis
|
||||
---
|
||||
|
||||
# Operation: File Statistics
|
||||
|
||||
Retrieve detailed statistics about file changes including counts, line changes, and file types.
|
||||
|
||||
## Parameters from $ARGUMENTS
|
||||
|
||||
Optional parameters:
|
||||
- `format:json|text` - Output format (default: text)
|
||||
- `detailed:true|false` - Include per-file breakdown (default: false)
|
||||
|
||||
## Workflow
|
||||
|
||||
### Step 1: Verify Repository
|
||||
|
||||
```bash
|
||||
git rev-parse --git-dir 2>/dev/null
|
||||
```
|
||||
|
||||
### Step 2: Collect File Statistics
|
||||
|
||||
```bash
|
||||
# Get file status
|
||||
git status --short
|
||||
|
||||
# Get statistics
|
||||
git diff --stat HEAD
|
||||
|
||||
# Get detailed stats per file
|
||||
git diff --numstat HEAD
|
||||
|
||||
# Count file types
|
||||
git diff --name-only HEAD | wc -l
|
||||
```
|
||||
|
||||
### Step 3: Categorize Files
|
||||
|
||||
Group files by status and type:
|
||||
|
||||
**By Status:**
|
||||
- New files (A)
|
||||
- Modified files (M)
|
||||
- Deleted files (D)
|
||||
- Renamed files (R)
|
||||
|
||||
**By Type:**
|
||||
- Source code (.js, .ts, .py, .java, etc.)
|
||||
- Tests (.test.js, .spec.ts, _test.py, etc.)
|
||||
- Documentation (.md, .txt)
|
||||
- Configuration (.json, .yml, .toml, .config.js)
|
||||
- Styles (.css, .scss, .less)
|
||||
|
||||
### Step 4: Calculate Metrics
|
||||
|
||||
```
|
||||
METRICS:
|
||||
- Total files changed
|
||||
- Total insertions (lines added)
|
||||
- Total deletions (lines removed)
|
||||
- Net change (insertions - deletions)
|
||||
- Largest files (by lines changed)
|
||||
- Files by type distribution
|
||||
- New vs Modified vs Deleted ratio
|
||||
```
|
||||
|
||||
### Step 5: Format Statistics Report
|
||||
|
||||
**Text Format (default):**
|
||||
```
|
||||
FILE STATISTICS
|
||||
═══════════════════════════════════════════════
|
||||
|
||||
OVERVIEW:
|
||||
───────────────────────────────────────────────
|
||||
Total Files: X
|
||||
Insertions: +XXX lines
|
||||
Deletions: -XXX lines
|
||||
Net Change: ±XXX lines
|
||||
|
||||
STATUS BREAKDOWN:
|
||||
───────────────────────────────────────────────
|
||||
New Files: X
|
||||
Modified Files: X
|
||||
Deleted Files: X
|
||||
Renamed Files: X
|
||||
|
||||
FILE TYPE BREAKDOWN:
|
||||
───────────────────────────────────────────────
|
||||
Source Code: X files (+XXX -XXX lines)
|
||||
Tests: X files (+XXX -XXX lines)
|
||||
Documentation: X files (+XXX -XXX lines)
|
||||
Configuration: X files (+XXX -XXX lines)
|
||||
Styles: X files (+XXX -XXX lines)
|
||||
Other: X files (+XXX -XXX lines)
|
||||
|
||||
TOP CHANGED FILES:
|
||||
───────────────────────────────────────────────
|
||||
1. <filename> (+XXX -XXX) = XXX lines
|
||||
2. <filename> (+XXX -XXX) = XXX lines
|
||||
3. <filename> (+XXX -XXX) = XXX lines
|
||||
4. <filename> (+XXX -XXX) = XXX lines
|
||||
5. <filename> (+XXX -XXX) = XXX lines
|
||||
|
||||
<if detailed:true>
|
||||
PER-FILE BREAKDOWN:
|
||||
───────────────────────────────────────────────
|
||||
<status> <filename>
|
||||
Insertions: +XXX
|
||||
Deletions: -XXX
|
||||
Net: ±XXX
|
||||
|
||||
<status> <filename>
|
||||
Insertions: +XXX
|
||||
Deletions: -XXX
|
||||
Net: ±XXX
|
||||
|
||||
═══════════════════════════════════════════════
|
||||
```
|
||||
|
||||
**JSON Format (if format:json):**
|
||||
```json
|
||||
{
|
||||
"overview": {
|
||||
"total_files": X,
|
||||
"insertions": XXX,
|
||||
"deletions": XXX,
|
||||
"net_change": XXX
|
||||
},
|
||||
"status_breakdown": {
|
||||
"new": X,
|
||||
"modified": X,
|
||||
"deleted": X,
|
||||
"renamed": X
|
||||
},
|
||||
"type_breakdown": {
|
||||
"source": {
|
||||
"count": X,
|
||||
"insertions": XXX,
|
||||
"deletions": XXX
|
||||
},
|
||||
"tests": {
|
||||
"count": X,
|
||||
"insertions": XXX,
|
||||
"deletions": XXX
|
||||
},
|
||||
"docs": {
|
||||
"count": X,
|
||||
"insertions": XXX,
|
||||
"deletions": XXX
|
||||
},
|
||||
"config": {
|
||||
"count": X,
|
||||
"insertions": XXX,
|
||||
"deletions": XXX
|
||||
}
|
||||
},
|
||||
"top_files": [
|
||||
{
|
||||
"path": "<filename>",
|
||||
"insertions": XXX,
|
||||
"deletions": XXX,
|
||||
"net": XXX
|
||||
}
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "<filename>",
|
||||
"status": "<status>",
|
||||
"insertions": XXX,
|
||||
"deletions": XXX,
|
||||
"net": XXX,
|
||||
"type": "<file-type>"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## File Type Detection
|
||||
|
||||
**Source Code:**
|
||||
```
|
||||
.js, .jsx, .ts, .tsx (JavaScript/TypeScript)
|
||||
.py (Python)
|
||||
.java (Java)
|
||||
.go (Go)
|
||||
.rs (Rust)
|
||||
.rb (Ruby)
|
||||
.php (PHP)
|
||||
.c, .cpp, .h (C/C++)
|
||||
.swift (Swift)
|
||||
.kt (Kotlin)
|
||||
```
|
||||
|
||||
**Tests:**
|
||||
```
|
||||
.test.js, .spec.js
|
||||
.test.ts, .spec.ts
|
||||
_test.py, test_*.py
|
||||
.test.jsx, .spec.tsx
|
||||
```
|
||||
|
||||
**Documentation:**
|
||||
```
|
||||
.md (Markdown)
|
||||
.txt (Text)
|
||||
.rst (reStructuredText)
|
||||
.adoc (AsciiDoc)
|
||||
```
|
||||
|
||||
**Configuration:**
|
||||
```
|
||||
.json, .yml, .yaml, .toml
|
||||
.config.js, .config.ts
|
||||
.env, .env.*
|
||||
.editorconfig, .gitignore
|
||||
package.json, tsconfig.json
|
||||
```
|
||||
|
||||
**Styles:**
|
||||
```
|
||||
.css, .scss, .sass, .less
|
||||
```
|
||||
|
||||
## Statistical Insights
|
||||
|
||||
Provide insights based on stats:
|
||||
|
||||
**Large Changes:**
|
||||
```
|
||||
INSIGHT: Large change detected
|
||||
You've changed 500+ lines across 15 files.
|
||||
Consider splitting into smaller commits.
|
||||
```
|
||||
|
||||
**Many New Files:**
|
||||
```
|
||||
INSIGHT: Many new files added
|
||||
8 new files suggest a new feature (feat).
|
||||
```
|
||||
|
||||
**Deletion Heavy:**
|
||||
```
|
||||
INSIGHT: More deletions than insertions
|
||||
Significant code removal suggests refactoring or cleanup.
|
||||
```
|
||||
|
||||
**Test Heavy:**
|
||||
```
|
||||
INSIGHT: High test coverage
|
||||
40% of changes are in test files.
|
||||
Good practice to include tests with features.
|
||||
```
|
||||
|
||||
**Documentation Heavy:**
|
||||
```
|
||||
INSIGHT: Documentation focused
|
||||
60% of changes are documentation.
|
||||
Consider "docs" commit type.
|
||||
```
|
||||
|
||||
## Usage Examples
|
||||
|
||||
**Basic stats:**
|
||||
```bash
|
||||
/commit-analysis file-stats
|
||||
```
|
||||
|
||||
**JSON output:**
|
||||
```bash
|
||||
/commit-analysis file-stats format:json
|
||||
```
|
||||
|
||||
**Detailed breakdown:**
|
||||
```bash
|
||||
/commit-analysis file-stats detailed:true
|
||||
```
|
||||
|
||||
**JSON with details:**
|
||||
```bash
|
||||
/commit-analysis file-stats format:json detailed:true
|
||||
```
|
||||
|
||||
## Output Format
|
||||
|
||||
Return:
|
||||
- Overview statistics
|
||||
- Status breakdown
|
||||
- File type breakdown
|
||||
- Top changed files
|
||||
- Per-file details (if detailed:true)
|
||||
- Statistical insights
|
||||
- Format as specified (text or JSON)
|
||||
|
||||
## Error Handling
|
||||
|
||||
**No changes:**
|
||||
```
|
||||
NO CHANGES
|
||||
Working tree is clean. No statistics to display.
|
||||
```
|
||||
|
||||
**Invalid format parameter:**
|
||||
```
|
||||
ERROR: Invalid format
|
||||
Valid formats: text, json
|
||||
```
|
||||
|
||||
## Integration with Agent
|
||||
|
||||
The commit-assistant agent uses this operation to:
|
||||
1. Understand change magnitude
|
||||
2. Identify dominant change types
|
||||
3. Provide context for commit decisions
|
||||
4. Generate statistics for reports
|
||||
|
||||
## Usage Example
|
||||
|
||||
```bash
|
||||
# Agent gathers stats before analysis
|
||||
# User: "how big are my changes?"
|
||||
# Agent: Invokes file-stats
|
||||
# Operation: Returns comprehensive statistics
|
||||
# Agent: "You've changed 15 files with 500+ lines"
|
||||
```
|
||||
231
commands/commit-analysis/identify-scope.md
Normal file
231
commands/commit-analysis/identify-scope.md
Normal file
@@ -0,0 +1,231 @@
|
||||
---
|
||||
description: Identify the primary module or component affected by changes for commit scope
|
||||
---
|
||||
|
||||
# Operation: Identify Scope
|
||||
|
||||
Analyze git changes to determine the appropriate scope (module/component/area) for the conventional commit message.
|
||||
|
||||
## Parameters from $ARGUMENTS
|
||||
|
||||
No parameters required. Analyzes current changes.
|
||||
|
||||
## Workflow
|
||||
|
||||
### Step 1: Verify Repository and Changes
|
||||
|
||||
```bash
|
||||
git rev-parse --git-dir 2>/dev/null
|
||||
git status --short
|
||||
```
|
||||
|
||||
### Step 2: Analyze File Paths
|
||||
|
||||
Execute scope identifier script:
|
||||
|
||||
```bash
|
||||
git diff HEAD --name-only | .scripts/scope-identifier.sh
|
||||
```
|
||||
|
||||
The script analyzes file paths to identify affected modules.
|
||||
|
||||
### Step 3: Scope Detection Algorithm
|
||||
|
||||
**Directory-Based Scope:**
|
||||
```
|
||||
src/auth/* → scope: auth
|
||||
src/api/* → scope: api
|
||||
src/components/* → scope: components (or specific component)
|
||||
src/utils/* → scope: utils
|
||||
src/database/* → scope: database
|
||||
tests/* → scope: test (or module being tested)
|
||||
docs/* → scope: docs
|
||||
```
|
||||
|
||||
**Component-Based Scope:**
|
||||
```
|
||||
src/components/LoginForm.js → scope: login-form
|
||||
src/components/UserProfile/* → scope: user-profile
|
||||
src/api/users.js → scope: users or user-api
|
||||
src/auth/oauth.js → scope: oauth or auth
|
||||
```
|
||||
|
||||
**Multiple Scopes:**
|
||||
If multiple distinct scopes:
|
||||
```
|
||||
Primary: auth (5 files)
|
||||
Secondary: api (2 files)
|
||||
Recommendation: Split into separate commits or use broader scope
|
||||
```
|
||||
|
||||
### Step 4: Determine Scope Specificity
|
||||
|
||||
**Specific Scope** (preferred):
|
||||
- Targets single module/component
|
||||
- Example: "auth", "user-profile", "payment-api"
|
||||
|
||||
**Broad Scope**:
|
||||
- Multiple modules affected
|
||||
- Example: "api", "components", "core"
|
||||
|
||||
**No Scope** (optional):
|
||||
- Changes are too diverse
|
||||
- Use no scope in message
|
||||
|
||||
### Step 5: Format Scope Report
|
||||
|
||||
```
|
||||
SCOPE IDENTIFICATION
|
||||
═══════════════════════════════════════════════
|
||||
|
||||
PRIMARY SCOPE: <scope-name>
|
||||
CONFIDENCE: <High|Medium|Low>
|
||||
|
||||
REASONING:
|
||||
───────────────────────────────────────────────
|
||||
<explanation of scope selection>
|
||||
|
||||
AFFECTED AREAS:
|
||||
───────────────────────────────────────────────
|
||||
<scope>: X files
|
||||
- path/to/file1.js
|
||||
- path/to/file2.js
|
||||
|
||||
<other-scope>: X files (if applicable)
|
||||
- path/to/file3.js
|
||||
|
||||
FILE PATH ANALYSIS:
|
||||
───────────────────────────────────────────────
|
||||
src/auth/*: 5 files → scope: auth
|
||||
src/api/*: 2 files → scope: api
|
||||
tests/*: 3 files → scope based on tested module
|
||||
|
||||
RECOMMENDATION:
|
||||
───────────────────────────────────────────────
|
||||
Use scope: "<recommended-scope>"
|
||||
|
||||
Alternative: <if multiple scopes>
|
||||
- Split into commits: auth (5 files), api (2 files)
|
||||
- Use broader scope: "backend"
|
||||
- Use no scope (if too diverse)
|
||||
|
||||
═══════════════════════════════════════════════
|
||||
```
|
||||
|
||||
## Scope Naming Conventions
|
||||
|
||||
**Format:**
|
||||
- Lowercase
|
||||
- Hyphen-separated (kebab-case)
|
||||
- Concise (1-3 words)
|
||||
- Specific but not too granular
|
||||
|
||||
**Good Examples:**
|
||||
```
|
||||
auth
|
||||
user-api
|
||||
login-form
|
||||
payment-processing
|
||||
database
|
||||
ci-pipeline
|
||||
docs
|
||||
```
|
||||
|
||||
**Bad Examples:**
|
||||
```
|
||||
src/auth/oauth (too specific, includes path)
|
||||
Authentication (not lowercase)
|
||||
user_api (use hyphens, not underscores)
|
||||
the-entire-authentication-module-system (too long)
|
||||
```
|
||||
|
||||
## Common Scopes by Project Type
|
||||
|
||||
### Web Application:
|
||||
```
|
||||
auth, api, components, ui, pages, routing, state, utils, config, hooks
|
||||
```
|
||||
|
||||
### Backend API:
|
||||
```
|
||||
api, auth, database, middleware, routes, controllers, services, models, validation
|
||||
```
|
||||
|
||||
### Library/Package:
|
||||
```
|
||||
core, utils, types, cli, docs, build, test
|
||||
```
|
||||
|
||||
### Full Stack:
|
||||
```
|
||||
frontend, backend, api, database, auth, ci, docs
|
||||
```
|
||||
|
||||
## Multiple Scope Handling
|
||||
|
||||
**Case 1: Closely Related Scopes**
|
||||
```
|
||||
Changes in: auth/oauth.js, auth/providers.js, auth/middleware.js
|
||||
Recommendation: scope: "auth"
|
||||
```
|
||||
|
||||
**Case 2: Distinct Scopes**
|
||||
```
|
||||
Changes in: auth/* (5 files), api/* (3 files)
|
||||
Recommendation: Split commits
|
||||
- Commit 1: feat(auth): implement OAuth
|
||||
- Commit 2: feat(api): add user endpoints
|
||||
```
|
||||
|
||||
**Case 3: Very Broad Changes**
|
||||
```
|
||||
Changes in: 15 different directories
|
||||
Recommendation: Use broad scope or no scope
|
||||
- feat(core): major refactoring
|
||||
- feat: implement new architecture
|
||||
```
|
||||
|
||||
## Output Format
|
||||
|
||||
Return:
|
||||
- Primary scope name
|
||||
- Confidence level
|
||||
- Reasoning for scope selection
|
||||
- List of affected areas
|
||||
- Alternative recommendations if applicable
|
||||
|
||||
## Error Handling
|
||||
|
||||
**No changes:**
|
||||
```
|
||||
NO CHANGES
|
||||
Cannot identify scope from empty diff.
|
||||
```
|
||||
|
||||
**Unclear scope:**
|
||||
```
|
||||
SCOPE UNCLEAR
|
||||
Changes span multiple unrelated areas.
|
||||
Recommendations:
|
||||
- Split into focused commits
|
||||
- Use broader scope like "core" or "backend"
|
||||
- Use no scope
|
||||
```
|
||||
|
||||
## Integration with Agent
|
||||
|
||||
The commit-assistant agent uses this operation to:
|
||||
1. Determine scope for commit messages
|
||||
2. Validate user-provided scopes
|
||||
3. Suggest scope splitting if needed
|
||||
4. Guide users in scope selection
|
||||
|
||||
## Usage Example
|
||||
|
||||
```bash
|
||||
# Agent identifies scope automatically
|
||||
# User: "commit my auth changes"
|
||||
# Agent: Invokes identify-scope
|
||||
# Operation: Returns "auth" with high confidence
|
||||
# Agent: Uses in message "feat(auth): ..."
|
||||
```
|
||||
65
commands/commit-analysis/skill.md
Normal file
65
commands/commit-analysis/skill.md
Normal file
@@ -0,0 +1,65 @@
|
||||
---
|
||||
description: Analyze git changes to understand nature, scope, and commit type for intelligent message generation
|
||||
---
|
||||
|
||||
# Commit Analysis Skill - Change Analysis and Type Detection
|
||||
|
||||
Intelligent analysis of git changes to determine commit type, scope, and atomicity for semantic commit message generation.
|
||||
|
||||
## Operations
|
||||
|
||||
- **analyze** - Full analysis (type, scope, atomicity)
|
||||
- **detect-type** - Determine commit type (feat, fix, docs, etc.)
|
||||
- **identify-scope** - Identify affected module/component
|
||||
- **assess-atomicity** - Check if changes should be split
|
||||
- **file-stats** - Get file change statistics
|
||||
|
||||
## Router Logic
|
||||
|
||||
Parse $ARGUMENTS to determine which operation to perform:
|
||||
|
||||
1. Extract operation from first word of $ARGUMENTS
|
||||
2. Extract remaining arguments as operation parameters
|
||||
3. Route to appropriate instruction file:
|
||||
- "analyze" → Read `/home/danie/projects/plugins/architect/open-plugins/plugins/git-commit-assistant/commands/commit-analysis/analyze-changes.md`
|
||||
- "detect-type" → Read `/home/danie/projects/plugins/architect/open-plugins/plugins/git-commit-assistant/commands/commit-analysis/detect-type.md`
|
||||
- "identify-scope" → Read `/home/danie/projects/plugins/architect/open-plugins/plugins/git-commit-assistant/commands/commit-analysis/identify-scope.md`
|
||||
- "assess-atomicity" → Read `/home/danie/projects/plugins/architect/open-plugins/plugins/git-commit-assistant/commands/commit-analysis/assess-atomicity.md`
|
||||
- "file-stats" → Read `/home/danie/projects/plugins/architect/open-plugins/plugins/git-commit-assistant/commands/commit-analysis/file-stats.md`
|
||||
|
||||
4. Execute instructions with parameters
|
||||
5. Return structured analysis results
|
||||
|
||||
## Error Handling
|
||||
|
||||
- If operation is unknown, list available operations
|
||||
- If parameters are missing, show required format
|
||||
- If not a git repository, return clear error message
|
||||
- If no changes to analyze, inform user
|
||||
|
||||
## Usage Examples
|
||||
|
||||
```bash
|
||||
# Full analysis of current changes
|
||||
/commit-analysis analyze
|
||||
|
||||
# Detect commit type only
|
||||
/commit-analysis detect-type
|
||||
|
||||
# Identify affected scope
|
||||
/commit-analysis identify-scope
|
||||
|
||||
# Check if changes should be split
|
||||
/commit-analysis assess-atomicity
|
||||
|
||||
# Get file statistics
|
||||
/commit-analysis file-stats
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Base directory:** `/home/danie/projects/plugins/architect/open-plugins/plugins/git-commit-assistant/commands/commit-analysis`
|
||||
|
||||
**Current request:** $ARGUMENTS
|
||||
|
||||
Parse operation and route to appropriate instruction file.
|
||||
Reference in New Issue
Block a user