Initial commit

This commit is contained in:
Zhongwei Li
2025-11-29 17:59:01 +08:00
commit dbe64cbfbb
8 changed files with 568 additions and 0 deletions

View File

@@ -0,0 +1,69 @@
# PHPStan Error Resolver Skill
Résout automatiquement les erreurs PHPStan en boucle jusqu'à zéro erreur ou stagnation.
## Fonctionnalités
- Détection automatique des erreurs PHPStan
- Groupement des erreurs par fichier
- Résolution par batch (5 erreurs max par fichier par itération)
- Boucle de résolution avec vérification après chaque correction
- Détection de stagnation (erreurs qui ne diminuent plus)
- Rapport détaillé avec taux de succès
## Usage
Via la commande délégante :
```bash
/qa:phpstan
```
Ou directement via le skill :
```bash
# Utiliser l'outil Task avec le skill phpstan-resolver
```
## Workflow
1. Analyse PHPStan initiale
2. Groupement erreurs par fichier
3. Pour chaque fichier avec erreurs :
- Batch de 5 erreurs max
- Délégation à agent `@phpstan-error-resolver`
- Correction via Edit tool
4. Re-exécution PHPStan pour vérification
5. Répétition jusqu'à :
- Zéro erreur (succès total)
- Stagnation (erreurs ne diminuent plus)
- Max itérations (10)
## Configuration
- `ERROR_BATCH_SIZE`: 5 erreurs par fichier par itération
- `MAX_ITERATIONS`: 10 itérations maximum
- `PHPSTAN_CONFIG`: phpstan.neon ou phpstan.neon.dist
## Dépendances
- PHPStan installé (`./vendor/bin/phpstan`)
- Configuration PHPStan valide
- Agent `@phpstan-error-resolver` disponible
- `jq` pour parsing JSON
## Rapport généré
```yaml
details:
total_errors_initial: [nombre]
total_errors_final: [nombre]
errors_fixed: [nombre]
success_rate: "[%]"
iterations: [nombre]
```
## Notes
- Utilise format JSON de PHPStan pour parsing précis
- Évite boucles infinies avec max itérations
- Détecte stagnation automatiquement
- Rapport détaillé même en cas d'échec partiel

View File

@@ -0,0 +1,250 @@
---
name: phpstan-resolver
description: >
Résout automatiquement les erreurs PHPStan détectées dans le projet en analysant
et corrigeant les problèmes de types stricts, annotations generics, array shapes
et collections Doctrine. Boucle jusqu'à zéro erreur ou stagnation.
allowed-tools: [Task, Bash, Read, Edit, Grep, Glob, TodoWrite]
model: claude-opus-4-1-20250805
---
# PHPStan Error Resolver Skill
## Variables
```bash
PHPSTAN_CONFIG="phpstan.neon" # ou phpstan.neon.dist
PHPSTAN_BIN="./vendor/bin/phpstan"
ERROR_BATCH_SIZE=5
MAX_ITERATIONS=10
```
## Workflow
### Étape 0: Timing
```bash
START_TIME=$(date +%s)
date
```
### Étape 1: Vérification Environnement
```bash
# Vérifier PHPStan installé
if [ ! -f "$PHPSTAN_BIN" ]; then
echo "❌ PHPStan non trouvé: $PHPSTAN_BIN"
exit 1
fi
# Vérifier config PHPStan
if [ ! -f "$PHPSTAN_CONFIG" ] && [ ! -f "phpstan.neon.dist" ]; then
echo "❌ Configuration PHPStan introuvable"
exit 1
fi
# Utiliser phpstan.neon.dist si phpstan.neon absent
if [ ! -f "$PHPSTAN_CONFIG" ]; then
PHPSTAN_CONFIG="phpstan.neon.dist"
fi
echo "✅ Environnement PHPStan valide"
echo " Config: $PHPSTAN_CONFIG"
```
### Étape 2: Exécution Initiale PHPStan
```bash
echo "🔍 Analyse PHPStan initiale..."
# Exécuter PHPStan
$PHPSTAN_BIN analyze --no-progress --error-format=json > /tmp/phpstan_initial.json
# Parser résultat
TOTAL_ERRORS_INITIAL=$(jq '.totals.file_errors' /tmp/phpstan_initial.json)
if [ "$TOTAL_ERRORS_INITIAL" -eq 0 ]; then
echo "✅ Aucune erreur PHPStan détectée"
exit 0
fi
echo "📊 Erreurs détectées: $TOTAL_ERRORS_INITIAL"
```
### Étape 3: TodoWrite Initialisation
```yaml
todos:
- content: "Analyser erreurs PHPStan"
status: "completed"
activeForm: "Analyse des erreurs PHPStan"
- content: "Grouper erreurs par fichier"
status: "pending"
activeForm: "Groupement des erreurs par fichier"
- content: "Résoudre erreurs (itération 1)"
status: "pending"
activeForm: "Résolution des erreurs (itération 1)"
- content: "Vérifier résolution"
status: "pending"
activeForm: "Vérification de la résolution"
```
### Étape 4: Groupement Erreurs par Fichier
Marquer todo #2 `in_progress`.
```bash
# Parser JSON et grouper par fichier
jq -r '.files | to_entries[] | "\(.key)|\(.value.messages | length)"' /tmp/phpstan_initial.json > /tmp/phpstan_files.txt
# Afficher groupement
echo "📁 Erreurs par fichier:"
cat /tmp/phpstan_files.txt | while IFS='|' read file count; do
echo " - $file: $count erreurs"
done
```
Marquer todo #2 `completed`.
### Étape 5: Boucle de Résolution
Marquer todo #3 `in_progress`.
```bash
ITERATION=1
ERRORS_CURRENT=$TOTAL_ERRORS_INITIAL
ERRORS_PREVIOUS=0
while [ $ITERATION -le $MAX_ITERATIONS ] && [ $ERRORS_CURRENT -gt 0 ] && [ $ERRORS_CURRENT -ne $ERRORS_PREVIOUS ]; do
echo ""
echo "🔄 Itération $ITERATION/$MAX_ITERATIONS"
echo " Erreurs: $ERRORS_CURRENT"
# Traiter chaque fichier avec erreurs
cat /tmp/phpstan_files.txt | while IFS='|' read file error_count; do
if [ "$error_count" -gt 0 ]; then
echo " 📝 Traitement: $file ($error_count erreurs)"
# Extraire erreurs pour ce fichier
jq -r --arg file "$file" '.files[$file].messages[] | "\(.line)|\(.message)"' /tmp/phpstan_initial.json > /tmp/phpstan_file_errors.txt
# Limiter batch size
head -n $ERROR_BATCH_SIZE /tmp/phpstan_file_errors.txt > /tmp/phpstan_batch.txt
# Déléguer à agent phpstan-error-resolver
echo "Utiliser agent @phpstan-error-resolver avec:"
echo "Fichier: $file"
echo "Erreurs:"
cat /tmp/phpstan_batch.txt
# L'agent lit le fichier, analyse erreurs, applique corrections via Edit
fi
done
# Re-exécuter PHPStan
echo " 🔍 Vérification post-correction..."
$PHPSTAN_BIN analyze --no-progress --error-format=json > /tmp/phpstan_iteration_${ITERATION}.json
ERRORS_PREVIOUS=$ERRORS_CURRENT
ERRORS_CURRENT=$(jq '.totals.file_errors' /tmp/phpstan_iteration_${ITERATION}.json)
echo " 📊 Résultat: $ERRORS_CURRENT erreurs restantes"
# Mettre à jour fichiers avec erreurs
jq -r '.files | to_entries[] | "\(.key)|\(.value.messages | length)"' /tmp/phpstan_iteration_${ITERATION}.json > /tmp/phpstan_files.txt
ITERATION=$((ITERATION + 1))
done
```
Marquer todo #3 `completed`.
### Étape 6: Analyse Résultat Final
Marquer todo #4 `in_progress`.
```bash
ERRORS_FIXED=$((TOTAL_ERRORS_INITIAL - ERRORS_CURRENT))
SUCCESS_RATE=$(awk "BEGIN {printf \"%.1f\", ($ERRORS_FIXED / $TOTAL_ERRORS_INITIAL) * 100}")
echo ""
echo "📊 Résumé Final:"
echo " - Erreurs initiales: $TOTAL_ERRORS_INITIAL"
echo " - Erreurs restantes: $ERRORS_CURRENT"
echo " - Erreurs corrigées: $ERRORS_FIXED"
echo " - Taux de succès: ${SUCCESS_RATE}%"
echo " - Itérations: $((ITERATION - 1))/$MAX_ITERATIONS"
# Identifier fichiers non résolus
if [ $ERRORS_CURRENT -gt 0 ]; then
echo ""
echo "⚠️ Fichiers avec erreurs restantes:"
cat /tmp/phpstan_files.txt | while IFS='|' read file count; do
if [ "$count" -gt 0 ]; then
echo " - $file: $count erreurs"
fi
done
fi
```
Marquer todo #4 `completed`.
### Étape 7: Rapport Final
```bash
END_TIME=$(date +%s)
DURATION=$((END_TIME - START_TIME))
if [ $DURATION -lt 60 ]; then
DURATION_STR="${DURATION}s"
elif [ $DURATION -lt 3600 ]; then
MINUTES=$((DURATION / 60))
SECONDS=$((DURATION % 60))
DURATION_STR="${MINUTES}m ${SECONDS}s"
else
HOURS=$((DURATION / 3600))
MINUTES=$(((DURATION % 3600) / 60))
SECONDS=$((DURATION % 60))
DURATION_STR="${HOURS}h ${MINUTES}m ${SECONDS}s"
fi
echo "⏱️ Durée: $DURATION_STR"
```
```yaml
task: "Résolution des erreurs PHPStan"
status: "terminé"
details:
total_errors_initial: $TOTAL_ERRORS_INITIAL
total_errors_final: $ERRORS_CURRENT
errors_fixed: $ERRORS_FIXED
success_rate: "${SUCCESS_RATE}%"
iterations: $((ITERATION - 1))
files:
fixed:
- [Liste des fichiers corrigés]
failed:
- [Liste des fichiers non résolus]
statistics:
success_rate: "${SUCCESS_RATE}%"
execution_time: "$DURATION_STR"
phpstan_level: "[Niveau détecté depuis config]"
notes:
- "Toutes les erreurs PHPStan ont été analysées"
- "Les corrections ont été appliquées automatiquement"
- "Relancer si erreurs restantes avec contexte différent"
```
## Error Handling
- PHPStan non trouvé → ARRÊT (exit 1)
- Config PHPStan absente → ARRÊT (exit 1)
- Stagnation (erreurs ne diminuent plus) → ARRÊT avec rapport
- Max itérations atteint → ARRÊT avec rapport
## Notes
- Utilise l'agent `@phpstan-error-resolver` pour corrections
- Batch size de 5 erreurs par fichier par itération
- Maximum 10 itérations pour éviter boucles infinies
- Parser JSON via `jq`
- Marquer CHAQUE todo completed immédiatement après succès