Initial commit
This commit is contained in:
15
.claude-plugin/plugin.json
Normal file
15
.claude-plugin/plugin.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "qa",
|
||||
"description": "Quality assurance : PHPStan automatisé, tests, linters avec skills spécialisés",
|
||||
"version": "1.2.0",
|
||||
"author": {
|
||||
"name": "Aurélien Tournayre",
|
||||
"email": "aurelien.tournayre@gmail.com"
|
||||
},
|
||||
"skills": [
|
||||
"./skills"
|
||||
],
|
||||
"commands": [
|
||||
"./commands"
|
||||
]
|
||||
}
|
||||
3
README.md
Normal file
3
README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# qa
|
||||
|
||||
Quality assurance : PHPStan automatisé, tests, linters avec skills spécialisés
|
||||
6
commands/elegant-objects.md
Normal file
6
commands/elegant-objects.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
description: Vérifie la conformité aux principes Elegant Objects (fichier ou fichiers modifiés)
|
||||
argument-hint: "[fichier.php] (optionnel, sinon analyse les fichiers modifiés dans la branche)"
|
||||
---
|
||||
|
||||
You must use the Skill tool to invoke the "qa:elegant-objects" skill.
|
||||
5
commands/phpstan.md
Normal file
5
commands/phpstan.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
description: Résoudre les erreurs PHPStan en utilisant l'agent phpstan-error-resolver
|
||||
---
|
||||
|
||||
You must use the Skill tool to invoke the "phpstan-resolver" skill.
|
||||
61
plugin.lock.json
Normal file
61
plugin.lock.json
Normal file
@@ -0,0 +1,61 @@
|
||||
{
|
||||
"$schema": "internal://schemas/plugin.lock.v1.json",
|
||||
"pluginId": "gh:atournayre/claude-marketplace:qa",
|
||||
"normalized": {
|
||||
"repo": null,
|
||||
"ref": "refs/tags/v20251128.0",
|
||||
"commit": "138dced66315e433e19da6e3f1d39d500d9e4b2f",
|
||||
"treeHash": "976a76ebdb12942b969e859bf7d5c97518952f23d461c86f03bd6b2dd453d939",
|
||||
"generatedAt": "2025-11-28T10:14:00.215464Z",
|
||||
"toolVersion": "publish_plugins.py@0.2.0"
|
||||
},
|
||||
"origin": {
|
||||
"remote": "git@github.com:zhongweili/42plugin-data.git",
|
||||
"branch": "master",
|
||||
"commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390",
|
||||
"repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data"
|
||||
},
|
||||
"manifest": {
|
||||
"name": "qa",
|
||||
"description": "Quality assurance : PHPStan automatisé, tests, linters avec skills spécialisés",
|
||||
"version": "1.2.0"
|
||||
},
|
||||
"content": {
|
||||
"files": [
|
||||
{
|
||||
"path": "README.md",
|
||||
"sha256": "83011278f384a96a5571adc935faa5e7066a0c8693d382c267c30cd5c14581e7"
|
||||
},
|
||||
{
|
||||
"path": ".claude-plugin/plugin.json",
|
||||
"sha256": "c25df66cddb8a514cbd5335426b8b03cb2d8f0f6b7734eb5d1fd21e702f87f54"
|
||||
},
|
||||
{
|
||||
"path": "commands/phpstan.md",
|
||||
"sha256": "b5a61aaf73e2d808ceea123db72ff892003586b26048d8f46628ffd75814d585"
|
||||
},
|
||||
{
|
||||
"path": "commands/elegant-objects.md",
|
||||
"sha256": "5accfef0e1e1a312b990ac6b4a56e753fd30117ca24e8c380b5bff5aa6b07ad1"
|
||||
},
|
||||
{
|
||||
"path": "skills/elegant-objects/SKILL.md",
|
||||
"sha256": "cb010340643eba833fa436ada0fd061d27366e9de568bcd02727f65edfce6261"
|
||||
},
|
||||
{
|
||||
"path": "skills/phpstan-resolver/README.md",
|
||||
"sha256": "30b9f28224ceb138c4d4bc65dda65f3aebeb6ad2f3a1f2677739311af07fbf1c"
|
||||
},
|
||||
{
|
||||
"path": "skills/phpstan-resolver/SKILL.md",
|
||||
"sha256": "974d3aa83846d73f754cfce45c472901a29ad6b83fa6dc830a4485e628a5ee5b"
|
||||
}
|
||||
],
|
||||
"dirSha256": "976a76ebdb12942b969e859bf7d5c97518952f23d461c86f03bd6b2dd453d939"
|
||||
},
|
||||
"security": {
|
||||
"scannedAt": null,
|
||||
"scannerVersion": null,
|
||||
"flags": []
|
||||
}
|
||||
}
|
||||
159
skills/elegant-objects/SKILL.md
Normal file
159
skills/elegant-objects/SKILL.md
Normal file
@@ -0,0 +1,159 @@
|
||||
---
|
||||
name: elegant-objects
|
||||
description: >
|
||||
Vérifie la conformité du code PHP aux principes Elegant Objects de Yegor Bugayenko.
|
||||
Analyse un fichier spécifique ou tous les fichiers modifiés dans la branche.
|
||||
allowed-tools: [Bash, Read, Grep, Glob]
|
||||
model: sonnet
|
||||
---
|
||||
|
||||
# Elegant Objects Reviewer Skill
|
||||
|
||||
## Variables
|
||||
|
||||
```bash
|
||||
TARGET="$ARGUMENTS" # Fichier spécifique ou vide pour fichiers modifiés
|
||||
```
|
||||
|
||||
## Workflow
|
||||
|
||||
### Étape 1: Déterminer les fichiers à analyser
|
||||
|
||||
```bash
|
||||
if [ -n "$TARGET" ] && [ -f "$TARGET" ]; then
|
||||
# Fichier spécifique fourni
|
||||
FILES_TO_ANALYZE="$TARGET"
|
||||
echo "📁 Analyse du fichier: $TARGET"
|
||||
else
|
||||
# Fichiers PHP modifiés dans la branche
|
||||
BASE_BRANCH=$(git rev-parse --abbrev-ref HEAD@{upstream} 2>/dev/null || echo "main")
|
||||
FILES_TO_ANALYZE=$(git diff --name-only "$BASE_BRANCH"...HEAD -- '*.php' 2>/dev/null || git diff --name-only HEAD -- '*.php')
|
||||
|
||||
if [ -z "$FILES_TO_ANALYZE" ]; then
|
||||
echo "⚠️ Aucun fichier PHP modifié détecté"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "📁 Fichiers PHP modifiés dans la branche:"
|
||||
echo "$FILES_TO_ANALYZE" | while read f; do echo " - $f"; done
|
||||
fi
|
||||
```
|
||||
|
||||
### Étape 2: Analyser chaque fichier
|
||||
|
||||
Pour chaque fichier PHP, vérifier les règles Elegant Objects.
|
||||
|
||||
#### Règles de conception des classes
|
||||
|
||||
1. **Classes final** - Toutes les classes doivent être `final` (sauf abstraites)
|
||||
2. **Attributs max 4** - Chaque classe encapsule 1 à 4 attributs maximum
|
||||
3. **Pas de getters** - Éviter les méthodes `getX()` (modèle anémique)
|
||||
4. **Pas de setters** - Éviter les méthodes `setX()` (mutabilité)
|
||||
5. **Pas de méthodes statiques** - Strictement interdites dans les classes
|
||||
6. **Pas de classes utilitaires** - Classes avec uniquement des méthodes statiques interdites
|
||||
7. **Noms sans -er** - Noms de classes ne finissant pas par -er (Manager, Handler, Helper...)
|
||||
8. **Constructeur unique** - Un seul constructeur principal par classe
|
||||
9. **Constructeurs simples** - Ne contiennent que des affectations
|
||||
|
||||
#### Règles de méthodes
|
||||
|
||||
1. **Pas de retour null** - Les méthodes ne doivent jamais retourner `null`
|
||||
2. **Pas d'argument null** - `null` ne doit pas être passé en argument
|
||||
3. **Corps sans lignes vides** - Les corps de méthodes sans lignes vides
|
||||
4. **Corps sans commentaires** - Les corps de méthodes sans commentaires inline
|
||||
5. **Noms verbes simples** - Noms de méthodes sont des verbes simples (pas composés)
|
||||
6. **CQRS** - Séparation commandes (void) et queries (retour valeur)
|
||||
|
||||
#### Règles de style
|
||||
|
||||
1. **Messages sans point final** - Messages d'erreur/log sans point final
|
||||
2. **Messages une phrase** - Messages d'erreur/log en une seule phrase
|
||||
3. **Fail fast** - Exceptions lancées au plus tôt
|
||||
|
||||
#### Règles de tests
|
||||
|
||||
1. **Une assertion par test** - Chaque test ne contient qu'une assertion
|
||||
2. **Assertion dernière** - L'assertion est la dernière instruction
|
||||
3. **Pas de setUp/tearDown** - Ne pas utiliser ces méthodes
|
||||
4. **Noms français** - Noms de tests en français décrivant le comportement
|
||||
5. **Messages négatifs** - Assertions avec messages d'échec négatifs
|
||||
6. **Pas de constantes partagées** - Pas de littéraux statiques partagés
|
||||
|
||||
### Étape 3: Générer le rapport
|
||||
|
||||
Format du rapport:
|
||||
|
||||
```
|
||||
## Score de conformité Elegant Objects
|
||||
|
||||
Score global: X/100
|
||||
|
||||
## Violations critiques (bloquantes)
|
||||
|
||||
### [Règle violée]
|
||||
- **Fichier:** /chemin/fichier.php:ligne
|
||||
- **Problème:** Description précise
|
||||
- **Suggestion:** Code corrigé ou approche
|
||||
|
||||
## Violations majeures (à corriger)
|
||||
|
||||
[Même format]
|
||||
|
||||
## Recommandations (améliorations)
|
||||
|
||||
[Même format]
|
||||
|
||||
## Statistiques
|
||||
|
||||
- Fichiers analysés: X
|
||||
- Classes analysées: Y
|
||||
- Méthodes analysées: Z
|
||||
- Tests analysés: W
|
||||
- Total violations: N
|
||||
|
||||
## Prochaines étapes
|
||||
|
||||
Liste priorisée des corrections à effectuer
|
||||
```
|
||||
|
||||
## Calcul du score
|
||||
|
||||
- Violation critique: -10 points
|
||||
- Violation majeure: -5 points
|
||||
- Recommandation: -2 points
|
||||
- Score de base: 100
|
||||
|
||||
## Patterns à détecter (regex)
|
||||
|
||||
```php
|
||||
# Classes non-final
|
||||
/^class\s+\w+/ # sans 'final' avant
|
||||
|
||||
# Getters
|
||||
/public\s+function\s+get[A-Z]\w*\s*\(/
|
||||
|
||||
# Setters
|
||||
/public\s+function\s+set[A-Z]\w*\s*\(/
|
||||
|
||||
# Méthodes statiques
|
||||
/public\s+static\s+function/
|
||||
|
||||
# Noms en -er
|
||||
/class\s+\w+(er|or|Manager|Handler|Helper|Builder|Factory|Provider|Controller|Processor)\b/
|
||||
|
||||
# Retour null
|
||||
/return\s+null\s*;/
|
||||
|
||||
# Lignes vides dans méthodes
|
||||
/\{\s*\n\s*\n/ # ouverture suivie de ligne vide
|
||||
|
||||
# Commentaires dans corps
|
||||
/^\s+\/\// # à l'intérieur des méthodes
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- Ignorer fichiers vendor/, var/, cache/
|
||||
- Contexte framework Symfony considéré (Controllers tolérés)
|
||||
- Prioriser violations par criticité
|
||||
- Proposer code corrigé quand possible
|
||||
69
skills/phpstan-resolver/README.md
Normal file
69
skills/phpstan-resolver/README.md
Normal 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
|
||||
250
skills/phpstan-resolver/SKILL.md
Normal file
250
skills/phpstan-resolver/SKILL.md
Normal 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
|
||||
Reference in New Issue
Block a user