claude-git-hooks 1.4.1 → 1.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +33 -0
- package/README.md +31 -14
- package/bin/claude-hooks +24 -13
- package/package.json +1 -1
- package/templates/CLAUDE_ANALYSIS_PROMPT_SONAR.md +47 -52
- package/templates/CLAUDE_PRE_COMMIT_SONAR.md +41 -96
- package/templates/CLAUDE_RESOLUTION_PROMPT.md +24 -37
- package/templates/pre-commit +60 -62
- package/templates/CLAUDE_ANALYSIS_PROMPT.md +0 -44
- package/templates/CLAUDE_PRE_COMMIT.md +0 -63
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,39 @@ Todos los cambios notables en este proyecto se documentarán en este archivo.
|
|
|
5
5
|
El formato está basado en [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
y este proyecto adhiere a [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.4.2] - 2025-09-08
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- 🚫 Comentario `// SKIP-ANALYSIS` para excluir código del análisis
|
|
12
|
+
- Una línea: excluye la siguiente línea
|
|
13
|
+
- Bloque: código entre dos comentarios `// SKIP-ANALYSIS` es excluido
|
|
14
|
+
- 📝 Excepciones para Spring Framework en criterios de evaluación
|
|
15
|
+
- `@Autowired` no es considerado issue bloqueante (máximo severidad MAJOR)
|
|
16
|
+
- Inyección de dependencias con field injection es aceptable
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
- 📋 Actualizada documentación con casos de uso de commits clarificados
|
|
20
|
+
- 🎯 Templates de prompts actualizados con reglas de Spring Framework
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
- 🔧 Clarificado que `git commit --no-verify -m "auto"` genera mensaje automático sin análisis
|
|
24
|
+
|
|
25
|
+
## [1.4.1] - 2025-09-04
|
|
26
|
+
|
|
27
|
+
### Changed
|
|
28
|
+
- 🚀 **BREAKING**: Eliminado modo estándar, ahora solo existe modo SonarQube
|
|
29
|
+
- ⚡ Prompts optimizados para Claude: reducción de ~80% en tokens manteniendo eficacia
|
|
30
|
+
- 🎯 Nuevo formato ultra-compacto de prompts usando notación concisa y directivas claras
|
|
31
|
+
- 📝 Templates simplificados: CLAUDE_ANALYSIS_PROMPT_SONAR.md, CLAUDE_PRE_COMMIT_SONAR.md, CLAUDE_RESOLUTION_PROMPT.md
|
|
32
|
+
|
|
33
|
+
### Fixed
|
|
34
|
+
- 🐛 Mejorada la lógica de escritura para mejor formación del prompt de resolución de problemas críticos
|
|
35
|
+
- 🔧 Corregido el formato del prompt AI-friendly para resolución de issues
|
|
36
|
+
|
|
37
|
+
### Removed
|
|
38
|
+
- 🗑️ Eliminados archivos del modo estándar: CLAUDE_PRE_COMMIT.md, CLAUDE_ANALYSIS_PROMPT.md
|
|
39
|
+
- 🗑️ Eliminada lógica de selección de modo (ahora siempre usa SonarQube)
|
|
40
|
+
|
|
8
41
|
## [1.4.0] - 2025-08-29
|
|
9
42
|
|
|
10
43
|
### Added
|
package/README.md
CHANGED
|
@@ -208,26 +208,50 @@ Cuando se detectan problemas críticos:
|
|
|
208
208
|
|
|
209
209
|
**IMPORTANTE**: Todos los comandos git deben ejecutarse desde WSL.
|
|
210
210
|
|
|
211
|
-
###
|
|
211
|
+
### Casos de uso de commits
|
|
212
212
|
|
|
213
213
|
```bash
|
|
214
214
|
# Desde WSL
|
|
215
215
|
git add .
|
|
216
|
-
git commit -m "feat: nueva funcionalidad"
|
|
217
|
-
```
|
|
218
216
|
|
|
219
|
-
|
|
217
|
+
# 1. Mensaje manual + análisis bloqueante
|
|
218
|
+
git commit -m "feat: nueva funcionalidad"
|
|
220
219
|
|
|
221
|
-
|
|
222
|
-
# Desde WSL
|
|
223
|
-
git add .
|
|
220
|
+
# 2. Mensaje automático + análisis bloqueante
|
|
224
221
|
git commit -m "auto" # Claude generará el mensaje automáticamente
|
|
222
|
+
|
|
223
|
+
# 3. Mensaje manual sin análisis
|
|
224
|
+
git commit --no-verify -m "fix: corrección urgente"
|
|
225
|
+
|
|
226
|
+
# 4. Mensaje automático sin análisis
|
|
227
|
+
git commit --no-verify -m "auto"
|
|
225
228
|
```
|
|
226
229
|
|
|
227
230
|
Claude analizará los cambios y generará un mensaje de commit siguiendo las convenciones (feat, fix, docs, etc.).
|
|
228
231
|
|
|
229
232
|
**⚠️ Si la generación automática falla**: El commit se cancelará completamente. Simplemente ejecuta `git commit -m "tu mensaje"` manualmente.
|
|
230
233
|
|
|
234
|
+
### Excluir código del análisis con SKIP-ANALYSIS
|
|
235
|
+
|
|
236
|
+
Puedes excluir código específico del análisis usando comentarios `// SKIP-ANALYSIS`:
|
|
237
|
+
|
|
238
|
+
```java
|
|
239
|
+
// Excluir una sola línea
|
|
240
|
+
// SKIP-ANALYSIS
|
|
241
|
+
@Autowired private LegacyService legacyService; // Esta línea no será analizada
|
|
242
|
+
|
|
243
|
+
// Excluir un bloque de código
|
|
244
|
+
// SKIP-ANALYSIS
|
|
245
|
+
@Deprecated
|
|
246
|
+
public void methodWithKnownIssues() {
|
|
247
|
+
// Código legacy que no queremos que sea analizado
|
|
248
|
+
System.out.println("Debug temporal");
|
|
249
|
+
}
|
|
250
|
+
// SKIP-ANALYSIS
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
**Nota**: El código entre comentarios `SKIP-ANALYSIS` no será enviado a Claude para su análisis.
|
|
254
|
+
|
|
231
255
|
### Modos de análisis 📊
|
|
232
256
|
|
|
233
257
|
Puedes elegir entre dos formatos de análisis:
|
|
@@ -278,13 +302,6 @@ unset CLAUDE_ANALYSIS_MODE
|
|
|
278
302
|
claude-hooks set-mode
|
|
279
303
|
```
|
|
280
304
|
|
|
281
|
-
### Saltar la revisión (usar con precaución)
|
|
282
|
-
|
|
283
|
-
```bash
|
|
284
|
-
# Desde WSL
|
|
285
|
-
git commit --no-verify -m "fix: corrección urgente"
|
|
286
|
-
```
|
|
287
|
-
|
|
288
305
|
### Modo debug
|
|
289
306
|
|
|
290
307
|
```bash
|
package/bin/claude-hooks
CHANGED
|
@@ -414,9 +414,7 @@ async function install(args) {
|
|
|
414
414
|
|
|
415
415
|
// Copiar archivos de pautas y prompts a .claude
|
|
416
416
|
const claudeFiles = [
|
|
417
|
-
'CLAUDE_PRE_COMMIT.md',
|
|
418
417
|
'CLAUDE_PRE_COMMIT_SONAR.md',
|
|
419
|
-
'CLAUDE_ANALYSIS_PROMPT.md',
|
|
420
418
|
'CLAUDE_ANALYSIS_PROMPT_SONAR.md',
|
|
421
419
|
'CLAUDE_RESOLUTION_PROMPT.md'
|
|
422
420
|
];
|
|
@@ -446,6 +444,12 @@ async function install(args) {
|
|
|
446
444
|
console.log('\nUso:');
|
|
447
445
|
console.log(' git commit -m "auto" # Genera mensaje automáticamente');
|
|
448
446
|
console.log(' git commit -m "mensaje" # Analiza código antes del commit');
|
|
447
|
+
console.log(' git commit --no-verify # Omite el análisis completamente');
|
|
448
|
+
console.log('\nExcluir código del análisis:');
|
|
449
|
+
console.log(' // SKIP-ANALYSIS # Excluye la siguiente línea');
|
|
450
|
+
console.log(' // SKIP-ANALYSIS # Entre dos comentarios excluye el bloque');
|
|
451
|
+
console.log(' ...código excluido...');
|
|
452
|
+
console.log(' // SKIP-ANALYSIS');
|
|
449
453
|
console.log('\nPara más opciones: claude-hooks --help');
|
|
450
454
|
}
|
|
451
455
|
|
|
@@ -870,31 +874,26 @@ function setMode(mode) {
|
|
|
870
874
|
error('No estás en un repositorio Git.');
|
|
871
875
|
}
|
|
872
876
|
|
|
873
|
-
const validModes = ['
|
|
877
|
+
const validModes = ['sonar'];
|
|
874
878
|
|
|
875
879
|
if (!mode) {
|
|
876
880
|
// Modo interactivo
|
|
877
|
-
console.log('\
|
|
878
|
-
console.log('
|
|
879
|
-
console.log('
|
|
880
|
-
console.log('\nEjemplo de uso: claude-hooks set-mode standard');
|
|
881
|
-
console.log(' claude-hooks set-mode sonar');
|
|
881
|
+
console.log('\nModo de análisis configurado:');
|
|
882
|
+
console.log('SonarQube - Formato con métricas y quality gate');
|
|
883
|
+
console.log('\nEjemplo de uso: claude-hooks set-mode sonar');
|
|
882
884
|
return;
|
|
883
885
|
}
|
|
884
886
|
|
|
885
887
|
if (!validModes.includes(mode)) {
|
|
886
|
-
error(`Modo inválido: ${mode}. Usa '
|
|
888
|
+
error(`Modo inválido: ${mode}. Usa 'sonar'`);
|
|
887
889
|
}
|
|
888
890
|
|
|
889
891
|
// Guardar el modo
|
|
890
892
|
fs.writeFileSync('.claude-analysis-mode', mode);
|
|
891
893
|
|
|
892
894
|
if (mode === 'sonar') {
|
|
893
|
-
success('Modo
|
|
895
|
+
success('Modo configurado: SonarQube');
|
|
894
896
|
info('Los commits usarán formato SonarQube con métricas y quality gate');
|
|
895
|
-
} else {
|
|
896
|
-
success('Modo cambiado a: Estándar');
|
|
897
|
-
info('Los commits usarán formato clásico con score y recomendaciones');
|
|
898
897
|
}
|
|
899
898
|
}
|
|
900
899
|
|
|
@@ -1012,6 +1011,18 @@ Ejemplos:
|
|
|
1012
1011
|
claude-hooks enable # Habilita todos los hooks
|
|
1013
1012
|
claude-hooks status # Ver estado actual
|
|
1014
1013
|
|
|
1014
|
+
Casos de uso de commits:
|
|
1015
|
+
git commit -m "mensaje" # Mensaje manual + análisis bloqueante
|
|
1016
|
+
git commit -m "auto" # Mensaje automático + análisis bloqueante
|
|
1017
|
+
git commit --no-verify -m "auto" # Mensaje automático sin análisis
|
|
1018
|
+
git commit --no-verify -m "msg" # Mensaje manual sin análisis
|
|
1019
|
+
|
|
1020
|
+
Excluir código del análisis:
|
|
1021
|
+
// SKIP-ANALYSIS # Excluye la siguiente línea del análisis
|
|
1022
|
+
// SKIP-ANALYSIS # Entre dos comentarios excluye el bloque
|
|
1023
|
+
...código excluido...
|
|
1024
|
+
// SKIP-ANALYSIS
|
|
1025
|
+
|
|
1015
1026
|
Más información: https://github.com/pablorovito/claude-git-hooks
|
|
1016
1027
|
`);
|
|
1017
1028
|
}
|
package/package.json
CHANGED
|
@@ -1,61 +1,56 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
⚠️ La respuesta debe ser un objeto JSON con esta estructura exacta de SonarQube:
|
|
1
|
+
ROLE:SeniorCodeReviewer,SonarQube-experienced
|
|
2
|
+
TASK:Analyze code->JSON only
|
|
3
|
+
CRITICAL:NoTextOutsideJSON,ValidJSON
|
|
6
4
|
|
|
5
|
+
OUTPUT_SCHEMA:
|
|
7
6
|
```json
|
|
8
7
|
{
|
|
9
|
-
"QUALITY_GATE":
|
|
10
|
-
"approved":
|
|
11
|
-
"score":
|
|
12
|
-
"metrics":
|
|
13
|
-
"reliability":
|
|
14
|
-
"security":
|
|
15
|
-
"maintainability":
|
|
16
|
-
"coverage":
|
|
17
|
-
"duplications":
|
|
18
|
-
"complexity":
|
|
8
|
+
"QUALITY_GATE":"PASSED|FAILED",
|
|
9
|
+
"approved":bool,
|
|
10
|
+
"score":1-10,
|
|
11
|
+
"metrics":{
|
|
12
|
+
"reliability":"A-E",
|
|
13
|
+
"security":"A-E",
|
|
14
|
+
"maintainability":"A-E",
|
|
15
|
+
"coverage":0-100,
|
|
16
|
+
"duplications":0-100,
|
|
17
|
+
"complexity":int
|
|
19
18
|
},
|
|
20
|
-
"issues":
|
|
21
|
-
"blocker":
|
|
22
|
-
"critical":
|
|
23
|
-
"major":
|
|
24
|
-
"minor":
|
|
25
|
-
"info":
|
|
19
|
+
"issues":{
|
|
20
|
+
"blocker":int,
|
|
21
|
+
"critical":int,
|
|
22
|
+
"major":int,
|
|
23
|
+
"minor":int,
|
|
24
|
+
"info":int
|
|
26
25
|
},
|
|
27
|
-
"details":
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
"severity": "critical" // solo "blocker" o "critical" aquí
|
|
45
|
-
}
|
|
46
|
-
],
|
|
47
|
-
"securityHotspots": 0 // cantidad de security hotspots
|
|
26
|
+
"details":[{
|
|
27
|
+
"severity":"BLOCKER|CRITICAL|MAJOR|MINOR|INFO",
|
|
28
|
+
"type":"BUG|VULNERABILITY|CODE_SMELL",
|
|
29
|
+
"file":"path",
|
|
30
|
+
"line":int,
|
|
31
|
+
"method":"name",
|
|
32
|
+
"message":"desc",
|
|
33
|
+
"rule":"optional"
|
|
34
|
+
}],
|
|
35
|
+
"blockingIssues":[{
|
|
36
|
+
"description":"text",
|
|
37
|
+
"file":"path",
|
|
38
|
+
"line":int,
|
|
39
|
+
"method":"name",
|
|
40
|
+
"severity":"blocker|critical"
|
|
41
|
+
}],
|
|
42
|
+
"securityHotspots":int
|
|
48
43
|
}
|
|
49
44
|
```
|
|
50
45
|
|
|
51
|
-
|
|
52
|
-
- blockingIssues
|
|
53
|
-
- blockingIssues
|
|
54
|
-
-
|
|
55
|
-
-
|
|
56
|
-
-
|
|
57
|
-
-
|
|
58
|
-
-
|
|
59
|
-
-
|
|
46
|
+
RULES:
|
|
47
|
+
- blockingIssues=ALWAYS_ARRAY_OF_OBJECTS(never_strings)
|
|
48
|
+
- blockingIssues=ALL(details.severity∈{BLOCKER,CRITICAL})
|
|
49
|
+
- Each_blockingIssue_MUST_have:description,file,line,method,severity
|
|
50
|
+
- QUALITY_GATE=FAILED if(blocker>0||critical>0)
|
|
51
|
+
- details:ALWAYS_include:file,line,method
|
|
52
|
+
- ratings:A(0issues),B(1-2minor),C(1major|3-5minor),D(2+major|1critical),E(1+blocker|2+critical)
|
|
53
|
+
- IMPORTANT: @Autowired usage in Spring is NOT a BLOCKER/CRITICAL issue (max severity: MAJOR)
|
|
54
|
+
- Spring dependency injection patterns (@Autowired) should NOT block commits
|
|
60
55
|
|
|
61
|
-
|
|
56
|
+
ANALYZE_BELOW:
|
|
@@ -1,96 +1,41 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
##
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
|
|
20
|
-
###
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
Responde ÚNICAMENTE con un JSON válido siguiendo esta estructura:
|
|
43
|
-
|
|
44
|
-
```json
|
|
45
|
-
{
|
|
46
|
-
"QUALITY_GATE": "PASSED/FAILED",
|
|
47
|
-
"metrics": {
|
|
48
|
-
"reliability": "A/B/C/D/E",
|
|
49
|
-
"security": "A/B/C/D/E",
|
|
50
|
-
"maintainability": "A/B/C/D/E",
|
|
51
|
-
"coverage": 75,
|
|
52
|
-
"duplications": 5,
|
|
53
|
-
"complexity": 15
|
|
54
|
-
},
|
|
55
|
-
"issues": {
|
|
56
|
-
"blocker": 0,
|
|
57
|
-
"critical": 0,
|
|
58
|
-
"major": 0,
|
|
59
|
-
"minor": 0,
|
|
60
|
-
"info": 0
|
|
61
|
-
},
|
|
62
|
-
"details": [
|
|
63
|
-
{
|
|
64
|
-
"severity": "CRITICAL",
|
|
65
|
-
"type": "BUG/VULNERABILITY/CODE_SMELL",
|
|
66
|
-
"message": "Descripción del problema",
|
|
67
|
-
"file": "archivo.java",
|
|
68
|
-
"line": 42
|
|
69
|
-
}
|
|
70
|
-
],
|
|
71
|
-
"securityHotspots": 0,
|
|
72
|
-
"approved": true/false,
|
|
73
|
-
"blockingIssues": ["Lista de problemas bloqueantes si existen"]
|
|
74
|
-
}
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
## Reglas para Quality Gate
|
|
78
|
-
|
|
79
|
-
- **PASSED** si:
|
|
80
|
-
- No hay issues BLOCKER
|
|
81
|
-
- Issues CRITICAL <= 1
|
|
82
|
-
- Todas las métricas son A o B
|
|
83
|
-
|
|
84
|
-
- **FAILED** si:
|
|
85
|
-
- Hay al menos 1 issue BLOCKER
|
|
86
|
-
- Issues CRITICAL > 1
|
|
87
|
-
- Alguna métrica es D o E
|
|
88
|
-
- Security hotspots > 0
|
|
89
|
-
|
|
90
|
-
## Rating de Métricas
|
|
91
|
-
|
|
92
|
-
- **A**: Excelente (0 issues)
|
|
93
|
-
- **B**: Bueno (1-2 issues minor)
|
|
94
|
-
- **C**: Aceptable (1 issue major o 3-5 minor)
|
|
95
|
-
- **D**: Pobre (2+ major o 1 critical)
|
|
96
|
-
- **E**: Muy pobre (1+ blocker o 2+ critical)
|
|
1
|
+
# SONARQUBE_EVAL_CRITERIA
|
|
2
|
+
|
|
3
|
+
## EXCEPTIONS_AND_ALLOWED_PATTERNS
|
|
4
|
+
### Spring Framework Patterns (NOT blocking issues)
|
|
5
|
+
- @Autowired for dependency injection is ALLOWED and NOT a blocking issue
|
|
6
|
+
- Field injection with @Autowired is acceptable in Spring Boot projects
|
|
7
|
+
- Constructor injection is preferred but @Autowired is NOT a blocker
|
|
8
|
+
|
|
9
|
+
## METRICS
|
|
10
|
+
### Reliability
|
|
11
|
+
- bugs,runtime_failures,exception_handling,race_conditions
|
|
12
|
+
|
|
13
|
+
### Security
|
|
14
|
+
- vulns,exposed_creds,input_validation,injection
|
|
15
|
+
|
|
16
|
+
### Maintainability
|
|
17
|
+
- code_smells,cyclomatic_complexity,duplication,tech_debt
|
|
18
|
+
- NOTE: @Autowired usage is NOT considered a code smell for blocking purposes
|
|
19
|
+
|
|
20
|
+
### Additional
|
|
21
|
+
- coverage:estimated_test_coverage(0-100)
|
|
22
|
+
- duplications:estimated_duplication(0-100)
|
|
23
|
+
- complexity:avg_cyclomatic_complexity
|
|
24
|
+
|
|
25
|
+
## SEVERITIES
|
|
26
|
+
- BLOCKER:fix_immediately
|
|
27
|
+
- CRITICAL:fix_before_release
|
|
28
|
+
- MAJOR:fix_soon
|
|
29
|
+
- MINOR:fix_eventually
|
|
30
|
+
- INFO:optional_improvement
|
|
31
|
+
|
|
32
|
+
## QUALITY_GATE
|
|
33
|
+
PASSED:no_blockers AND critical<=1 AND all_metrics∈{A,B}
|
|
34
|
+
FAILED:blocker>=1 OR critical>1 OR any_metric∈{D,E} OR security_hotspots>0
|
|
35
|
+
|
|
36
|
+
## RATINGS
|
|
37
|
+
A:0_issues
|
|
38
|
+
B:1-2_minor
|
|
39
|
+
C:1_major|3-5_minor
|
|
40
|
+
D:2+_major|1_critical
|
|
41
|
+
E:1+_blocker|2+_critical
|
|
@@ -1,46 +1,33 @@
|
|
|
1
|
-
#
|
|
1
|
+
# FIX_CRITICAL_ISSUES
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
Files analyzed: {{FILE_COUNT}}
|
|
10
|
-
Analysis mode: {{ANALYSIS_MODE}}
|
|
11
|
-
|
|
12
|
-
## Critical Issues to Resolve
|
|
3
|
+
CONTEXT:
|
|
4
|
+
repo:{{REPO_NAME}}
|
|
5
|
+
branch:{{BRANCH_NAME}}
|
|
6
|
+
commit:{{COMMIT_SHA}}
|
|
7
|
+
files:{{FILE_COUNT}}
|
|
8
|
+
mode:{{ANALYSIS_MODE}}
|
|
13
9
|
|
|
10
|
+
CRITICAL_ISSUES:
|
|
14
11
|
{{BLOCKING_ISSUES}}
|
|
15
12
|
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
AFFECTED_FILES:
|
|
18
14
|
{{FILE_CONTENTS}}
|
|
19
15
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
- Apply the minimal fix required
|
|
26
|
-
- Ensure the fix doesn't introduce new issues
|
|
27
|
-
|
|
28
|
-
2. Fix requirements:
|
|
29
|
-
- Make the smallest possible change to resolve the issue
|
|
30
|
-
- Maintain existing code style and conventions
|
|
31
|
-
- Don't refactor unrelated code
|
|
32
|
-
- Preserve all existing functionality
|
|
16
|
+
INSTRUCTIONS:
|
|
17
|
+
1.Navigate→exact_file:line
|
|
18
|
+
2.Apply_minimal_fix
|
|
19
|
+
3.Maintain_style/conventions
|
|
20
|
+
4.No_unrelated_refactoring
|
|
33
21
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
- Explain each fix briefly (one line max)
|
|
22
|
+
OUTPUT:
|
|
23
|
+
- diff_format
|
|
24
|
+
- one_line_explanation_max
|
|
38
25
|
|
|
39
|
-
|
|
40
|
-
1.
|
|
41
|
-
2.
|
|
42
|
-
3.
|
|
43
|
-
4.
|
|
44
|
-
5.
|
|
26
|
+
PRIORITY:
|
|
27
|
+
1.security_vulns
|
|
28
|
+
2.null_ptr/runtime
|
|
29
|
+
3.logic_errors
|
|
30
|
+
4.performance
|
|
31
|
+
5.code_quality
|
|
45
32
|
|
|
46
|
-
|
|
33
|
+
START_FIXING:
|
package/templates/pre-commit
CHANGED
|
@@ -109,7 +109,7 @@ generate_resolution_prompt() {
|
|
|
109
109
|
sed -i "s|{{BRANCH_NAME}}|${BRANCH_NAME}|g" "$RESOLUTION_FILE"
|
|
110
110
|
sed -i "s|{{COMMIT_SHA}}|${COMMIT_SHA}|g" "$RESOLUTION_FILE"
|
|
111
111
|
sed -i "s|{{FILE_COUNT}}|${FILE_COUNT}|g" "$RESOLUTION_FILE"
|
|
112
|
-
sed -i "s|{{ANALYSIS_MODE}}
|
|
112
|
+
sed -i "s|{{ANALYSIS_MODE}}|sonar|g" "$RESOLUTION_FILE"
|
|
113
113
|
|
|
114
114
|
# Crear archivo temporal para issues formateados
|
|
115
115
|
local TEMP_ISSUES_FILE=$(mktemp)
|
|
@@ -149,65 +149,17 @@ generate_resolution_prompt() {
|
|
|
149
149
|
echo
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
-
#
|
|
153
|
-
|
|
154
|
-
if [ -n "$CLAUDE_ANALYSIS_MODE" ]; then
|
|
155
|
-
ANALYSIS_MODE="$CLAUDE_ANALYSIS_MODE"
|
|
156
|
-
elif [ -f ".claude-analysis-mode" ]; then
|
|
157
|
-
ANALYSIS_MODE=$(cat .claude-analysis-mode)
|
|
158
|
-
else
|
|
159
|
-
ANALYSIS_MODE=""
|
|
160
|
-
fi
|
|
152
|
+
# Usar siempre modo SonarQube
|
|
153
|
+
ANALYSIS_MODE="sonar"
|
|
161
154
|
|
|
162
|
-
#
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
155
|
+
# Configurar archivos para modo SonarQube
|
|
156
|
+
GUIDELINES_FILE=".claude/CLAUDE_PRE_COMMIT_SONAR.md"
|
|
157
|
+
PROMPT_TEMPLATE=".claude/CLAUDE_ANALYSIS_PROMPT_SONAR.md"
|
|
158
|
+
log "Usando modo de análisis: SonarQube"
|
|
166
159
|
|
|
167
|
-
#
|
|
168
|
-
if [
|
|
169
|
-
echo
|
|
170
|
-
echo "🔍 Selecciona el formato de análisis de código:"
|
|
171
|
-
echo "1) Estándar - Formato clásico con recomendaciones"
|
|
172
|
-
echo "2) SonarQube - Formato similar a SonarQube con métricas"
|
|
173
|
-
echo
|
|
174
|
-
|
|
175
|
-
# Intentar leer desde terminal
|
|
176
|
-
if [ -t 0 ] && [ -c /dev/tty ]; then
|
|
177
|
-
read -p "Opción (1 o 2): " -n 1 -r </dev/tty
|
|
178
|
-
echo
|
|
179
|
-
else
|
|
180
|
-
# Si no hay terminal interactiva, usar modo estándar por defecto
|
|
181
|
-
echo "No se puede leer input interactivo, usando modo estándar por defecto"
|
|
182
|
-
REPLY="1"
|
|
183
|
-
fi
|
|
184
|
-
|
|
185
|
-
if [ "$REPLY" = "2" ]; then
|
|
186
|
-
ANALYSIS_MODE="sonar"
|
|
187
|
-
GUIDELINES_FILE=".claude/CLAUDE_PRE_COMMIT_SONAR.md"
|
|
188
|
-
PROMPT_TEMPLATE=".claude/CLAUDE_ANALYSIS_PROMPT_SONAR.md"
|
|
189
|
-
else
|
|
190
|
-
ANALYSIS_MODE="standard"
|
|
191
|
-
GUIDELINES_FILE=".claude/CLAUDE_PRE_COMMIT.md"
|
|
192
|
-
PROMPT_TEMPLATE=".claude/CLAUDE_ANALYSIS_PROMPT.md"
|
|
193
|
-
fi
|
|
194
|
-
|
|
195
|
-
# Guardar preferencia para futuros commits
|
|
196
|
-
echo "$ANALYSIS_MODE" > .claude-analysis-mode
|
|
197
|
-
echo -e "${GREEN}✓ Modo $ANALYSIS_MODE guardado para futuros commits${NC}"
|
|
198
|
-
echo -e "${YELLOW}Tip: Para cambiar el modo, ejecuta: .git/hooks/pre-commit --change-mode${NC}"
|
|
199
|
-
echo
|
|
200
|
-
else
|
|
201
|
-
# Usar modo guardado
|
|
202
|
-
if [ "$ANALYSIS_MODE" = "sonar" ]; then
|
|
203
|
-
GUIDELINES_FILE=".claude/CLAUDE_PRE_COMMIT_SONAR.md"
|
|
204
|
-
PROMPT_TEMPLATE=".claude/CLAUDE_ANALYSIS_PROMPT_SONAR.md"
|
|
205
|
-
log "Usando modo de análisis: SonarQube"
|
|
206
|
-
else
|
|
207
|
-
GUIDELINES_FILE=".claude/CLAUDE_PRE_COMMIT.md"
|
|
208
|
-
PROMPT_TEMPLATE=".claude/CLAUDE_ANALYSIS_PROMPT.md"
|
|
209
|
-
log "Usando modo de análisis: Estándar"
|
|
210
|
-
fi
|
|
160
|
+
# Guardar preferencia si no existe
|
|
161
|
+
if [ ! -f ".claude-analysis-mode" ]; then
|
|
162
|
+
echo "sonar" > .claude-analysis-mode
|
|
211
163
|
fi
|
|
212
164
|
|
|
213
165
|
# Verificar que el template de prompt existe
|
|
@@ -254,6 +206,46 @@ fi
|
|
|
254
206
|
|
|
255
207
|
log "Archivos Java/config a revisar: $(echo "$JAVA_FILES" | wc -l)"
|
|
256
208
|
|
|
209
|
+
# Función para filtrar contenido con SKIP-ANALYSIS
|
|
210
|
+
filter_skip_analysis() {
|
|
211
|
+
local file_content="$1"
|
|
212
|
+
local filtered_content=""
|
|
213
|
+
local skip_next_line=false
|
|
214
|
+
local inside_skip_block=false
|
|
215
|
+
|
|
216
|
+
while IFS= read -r line; do
|
|
217
|
+
# Detectar inicio de bloque SKIP-ANALYSIS
|
|
218
|
+
if echo "$line" | grep -q "// SKIP-ANALYSIS"; then
|
|
219
|
+
if [ "$inside_skip_block" = true ]; then
|
|
220
|
+
# Fin del bloque
|
|
221
|
+
inside_skip_block=false
|
|
222
|
+
else
|
|
223
|
+
# Inicio del bloque o línea única
|
|
224
|
+
inside_skip_block=true
|
|
225
|
+
skip_next_line=true
|
|
226
|
+
fi
|
|
227
|
+
continue
|
|
228
|
+
fi
|
|
229
|
+
|
|
230
|
+
# Si estamos dentro de un bloque, saltar la línea
|
|
231
|
+
if [ "$inside_skip_block" = true ]; then
|
|
232
|
+
continue
|
|
233
|
+
fi
|
|
234
|
+
|
|
235
|
+
# Si debemos saltar la siguiente línea (comentario único)
|
|
236
|
+
if [ "$skip_next_line" = true ]; then
|
|
237
|
+
skip_next_line=false
|
|
238
|
+
inside_skip_block=false
|
|
239
|
+
continue
|
|
240
|
+
fi
|
|
241
|
+
|
|
242
|
+
# Agregar línea al contenido filtrado
|
|
243
|
+
filtered_content="${filtered_content}${line}"$'\n'
|
|
244
|
+
done <<< "$file_content"
|
|
245
|
+
|
|
246
|
+
echo "$filtered_content"
|
|
247
|
+
}
|
|
248
|
+
|
|
257
249
|
# Construir el prompt para análisis de código
|
|
258
250
|
PROMPT_FILE="$TEMP_DIR/code_review_prompt.txt"
|
|
259
251
|
|
|
@@ -278,14 +270,20 @@ for FILE in $JAVA_FILES; do
|
|
|
278
270
|
|
|
279
271
|
echo -e "\n--- Archivo: $FILE ---" >> "$PROMPT_FILE"
|
|
280
272
|
|
|
281
|
-
#
|
|
273
|
+
# Obtener el diff y filtrarlo
|
|
274
|
+
DIFF_CONTENT=$(git diff --cached "$FILE" 2>/dev/null || echo "No se pudo obtener diff")
|
|
275
|
+
FILTERED_DIFF=$(filter_skip_analysis "$DIFF_CONTENT")
|
|
276
|
+
|
|
277
|
+
# Mostrar el diff filtrado del archivo
|
|
282
278
|
echo -e "\nDiff:" >> "$PROMPT_FILE"
|
|
283
|
-
|
|
279
|
+
echo "$FILTERED_DIFF" >> "$PROMPT_FILE"
|
|
284
280
|
|
|
285
|
-
# Si es un archivo nuevo, mostrar contenido completo
|
|
281
|
+
# Si es un archivo nuevo, mostrar contenido completo filtrado
|
|
286
282
|
if git diff --cached --name-status | grep "^A.*$FILE" > /dev/null; then
|
|
287
283
|
echo -e "\nContenido completo (archivo nuevo):" >> "$PROMPT_FILE"
|
|
288
|
-
git show ":$FILE"
|
|
284
|
+
FILE_CONTENT=$(git show ":$FILE" 2>/dev/null || cat "$FILE")
|
|
285
|
+
FILTERED_CONTENT=$(filter_skip_analysis "$FILE_CONTENT")
|
|
286
|
+
echo "$FILTERED_CONTENT" >> "$PROMPT_FILE"
|
|
289
287
|
fi
|
|
290
288
|
|
|
291
289
|
FILE_COUNT=$((FILE_COUNT + 1))
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
Eres un revisor de código senior con experiencia en proyectos Spring Boot empresariales.
|
|
2
|
-
|
|
3
|
-
Tu tarea es analizar los siguientes cambios de código y responder exclusivamente con un JSON válido, **sin ningún texto fuera del JSON**, sin introducciones ni explicaciones adicionales.
|
|
4
|
-
|
|
5
|
-
⚠️ La respuesta debe ser un objeto JSON con esta estructura exacta:
|
|
6
|
-
|
|
7
|
-
```json
|
|
8
|
-
{
|
|
9
|
-
"approved": true, // true si el commit puede aceptarse, false si debe bloquearse
|
|
10
|
-
"score": 1-10, // calificación de calidad (entero)
|
|
11
|
-
"blockingIssues": [ // SIEMPRE array de objetos, nunca strings
|
|
12
|
-
{
|
|
13
|
-
"description": "texto descriptivo del problema",
|
|
14
|
-
"file": "path/to/file.java",
|
|
15
|
-
"line": 123, // línea donde se detectó el problema
|
|
16
|
-
"method": "methodName", // método o clase afectada
|
|
17
|
-
"severity": "critical" // critical, high, medium, low
|
|
18
|
-
}
|
|
19
|
-
],
|
|
20
|
-
"recommendations": [ // sugerencias no bloqueantes (array de strings)
|
|
21
|
-
"mejora 1",
|
|
22
|
-
"mejora 2"
|
|
23
|
-
],
|
|
24
|
-
"details": {
|
|
25
|
-
"security": [ // comentarios específicos por área
|
|
26
|
-
"observación sobre seguridad"
|
|
27
|
-
],
|
|
28
|
-
"architecture": [ "..." ],
|
|
29
|
-
"performance": [ "..." ],
|
|
30
|
-
"maintainability": [ "..." ]
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
✅ Importante:
|
|
36
|
-
- blockingIssues SIEMPRE debe ser un array de objetos, NUNCA un array de strings
|
|
37
|
-
- Cada blockingIssue DEBE incluir: description, file, line, method, severity
|
|
38
|
-
- Usa listas vacías si no hay issues (ejemplo: `"blockingIssues": []`)
|
|
39
|
-
- No uses texto introductorio o explicaciones fuera del JSON
|
|
40
|
-
- No omitas claves aunque estén vacías
|
|
41
|
-
- Sé directo, claro y profesional en tus observaciones
|
|
42
|
-
- Los problemas críticos deben incluir contexto suficiente para que otra IA pueda resolverlos
|
|
43
|
-
|
|
44
|
-
A continuación se detallan las pautas y los cambios:
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
# Pautas de Evaluación de Código - Claude Pre-commit Hook
|
|
2
|
-
|
|
3
|
-
## Objetivo
|
|
4
|
-
Evaluar el código modificado antes del commit para asegurar calidad, mantenibilidad y adherencia a buenas prácticas.
|
|
5
|
-
|
|
6
|
-
## Criterios de Evaluación
|
|
7
|
-
|
|
8
|
-
### 1. Calidad del Código (40%)
|
|
9
|
-
- **Claridad y legibilidad**: El código es fácil de entender
|
|
10
|
-
- **Nombres descriptivos**: Variables, métodos y clases tienen nombres significativos
|
|
11
|
-
- **Estructura lógica**: El código está bien organizado
|
|
12
|
-
- **Principio DRY**: No hay duplicación innecesaria
|
|
13
|
-
- **Complejidad**: Funciones y métodos no son excesivamente complejos
|
|
14
|
-
|
|
15
|
-
### 2. Buenas Prácticas (30%)
|
|
16
|
-
- **SOLID principles**: Adherencia cuando aplique
|
|
17
|
-
- **Patrones de diseño**: Uso apropiado cuando sea necesario
|
|
18
|
-
- **Manejo de errores**: Excepciones manejadas correctamente
|
|
19
|
-
- **Validación de inputs**: Datos de entrada validados
|
|
20
|
-
- **Separación de concerns**: Responsabilidades bien definidas
|
|
21
|
-
|
|
22
|
-
### 3. Seguridad (20%)
|
|
23
|
-
- **No hay credenciales hardcodeadas**
|
|
24
|
-
- **Validación de datos de usuario**
|
|
25
|
-
- **No hay vulnerabilidades obvias** (SQL injection, XSS, etc.)
|
|
26
|
-
- **Manejo seguro de datos sensibles**
|
|
27
|
-
|
|
28
|
-
### 4. Performance (10%)
|
|
29
|
-
- **No hay operaciones obviamente ineficientes**
|
|
30
|
-
- **Uso apropiado de estructuras de datos**
|
|
31
|
-
- **Queries optimizadas** (cuando aplique)
|
|
32
|
-
|
|
33
|
-
## Formato de Respuesta Esperado
|
|
34
|
-
|
|
35
|
-
Responde ÚNICAMENTE con un JSON válido siguiendo esta estructura:
|
|
36
|
-
|
|
37
|
-
```json
|
|
38
|
-
{
|
|
39
|
-
"approved": true/false,
|
|
40
|
-
"score": 8,
|
|
41
|
-
"recommendations": [
|
|
42
|
-
"Sugerencia 1",
|
|
43
|
-
"Sugerencia 2"
|
|
44
|
-
],
|
|
45
|
-
"blockingIssues": [
|
|
46
|
-
"Problema crítico 1 (si existe)"
|
|
47
|
-
],
|
|
48
|
-
"details": "Información adicional detallada (opcional)"
|
|
49
|
-
}
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
## Reglas de Aprobación
|
|
53
|
-
|
|
54
|
-
- **approved = true** si score >= 7 Y no hay blockingIssues
|
|
55
|
-
- **approved = false** si score < 7 O hay blockingIssues
|
|
56
|
-
|
|
57
|
-
## Problemas que SIEMPRE son Blocking Issues
|
|
58
|
-
|
|
59
|
-
1. Credenciales o tokens hardcodeados
|
|
60
|
-
2. Vulnerabilidades de seguridad evidentes
|
|
61
|
-
3. Código que podría causar pérdida de datos
|
|
62
|
-
4. Errores de sintaxis o código que no compilaría
|
|
63
|
-
5. Eliminación de tests sin justificación
|