claude-git-hooks 1.3.0 → 1.4.1

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 CHANGED
@@ -5,6 +5,33 @@ 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.0] - 2025-08-29
9
+
10
+ ### Added
11
+ - 🎯 Prompts externalizados en archivos `.md` para facilitar personalización
12
+ - 🤖 Generación automática de prompt AI-friendly para resolución de problemas críticos
13
+ - 📝 Nuevos templates de prompts: `CLAUDE_ANALYSIS_PROMPT.md`, `CLAUDE_ANALYSIS_PROMPT_SONAR.md`, `CLAUDE_RESOLUTION_PROMPT.md`
14
+ - 🔍 Localización precisa en blockingIssues (archivo, línea, método, severidad)
15
+ - 📋 Archivo `claude_resolution_prompt.md` generado automáticamente con issues para resolver
16
+ - 🚀 Flag `--skip-auth` para omitir verificación de autenticación en instalación
17
+ - 📖 Ejemplos detallados de respuestas JSON con blocking issues en README
18
+
19
+ ### Changed
20
+ - 🏗️ Estandarización de `blockingIssues` a formato objeto (nunca strings)
21
+ - 📦 Separación de prompts del código para mayor mantenibilidad
22
+ - 🔧 Hook pre-commit simplificado sin fallbacks complejos
23
+ - 📁 Instalador actualizado para copiar todos los templates de prompts
24
+
25
+ ### Fixed
26
+ - 🐛 Consistencia en el formato de respuesta JSON para ambos modos
27
+ - 🔧 Mejor manejo de errores cuando faltan archivos de configuración
28
+
29
+ ### Technical
30
+ - 🏗️ Función `generate_resolution_prompt()` para crear prompts de resolución
31
+ - 📝 Templates de prompts con placeholders reemplazables
32
+ - 🎯 Estructura JSON estricta para blockingIssues con campos obligatorios
33
+ - 🔄 Instalación en modo force actualiza todos los templates
34
+
8
35
  ## [1.3.0] - 2025-08-28
9
36
 
10
37
  ### Added
package/README.md CHANGED
@@ -10,6 +10,9 @@ Este directorio contiene un pre-commit hook que utiliza Claude CLI para revisar
10
10
  - **`.gitattributes`** - Configuración para mantener line endings correctos
11
11
  - **`.claude/CLAUDE_PRE_COMMIT.md`** - Pautas de evaluación formato estándar
12
12
  - **`.claude/CLAUDE_PRE_COMMIT_SONAR.md`** - Pautas de evaluación formato SonarQube
13
+ - **`.claude/CLAUDE_ANALYSIS_PROMPT.md`** - Template de prompt para análisis estándar
14
+ - **`.claude/CLAUDE_ANALYSIS_PROMPT_SONAR.md`** - Template de prompt para análisis SonarQube
15
+ - **`.claude/CLAUDE_RESOLUTION_PROMPT.md`** - Template para generar prompt de resolución AI
13
16
 
14
17
  ## 🔧 Configuración Previa Importante
15
18
 
@@ -64,13 +67,19 @@ claude-hooks install
64
67
  ```
65
68
 
66
69
  El comando `claude-hooks install` ahora incluye:
70
+
67
71
  - ✅ Verificación completa de dependencias del sistema
68
72
  - ✅ Instalación automática de paquetes faltantes (jq, curl)
69
73
  - ✅ Configuración de Git (line endings WSL/Windows)
70
- - ✅ Verificación de autenticación Claude con entretenimiento
74
+ - ✅ Verificación de autenticación Claude con entretenimiento (omitible con `--skip-auth`)
71
75
  - ✅ Instalación de hooks y archivos de pautas
72
76
  - ✅ Actualización automática de .gitignore con archivos de Claude
73
77
 
78
+ **Opciones de instalación:**
79
+
80
+ - `--force`: Reinstala aunque los hooks ya existan
81
+ - `--skip-auth`: Omite la verificación de autenticación de Claude (útil para CI/CD)
82
+
74
83
  #### Añadir como Dependencia de Desarrollo
75
84
 
76
85
  ```bash
@@ -108,10 +117,14 @@ El comando `claude-hooks install` crea los siguientes archivos y directorios:
108
117
 
109
118
  1. **`.git/hooks/pre-commit`** - Hook de análisis de código
110
119
  2. **`.git/hooks/prepare-commit-msg`** - Hook de generación de mensajes
111
- 3. **`.claude/`** - Directorio para archivos de configuración
120
+ 3. **`.git/hooks/check-version.sh`** - Script de verificación de versión
121
+ 4. **`.claude/`** - Directorio para archivos de configuración
112
122
  - `CLAUDE_PRE_COMMIT.md` - Pautas de evaluación estándar
113
123
  - `CLAUDE_PRE_COMMIT_SONAR.md` - Pautas de evaluación SonarQube
114
- 4. **`.claude-analysis-mode`** - Archivo de preferencia de modo (creado al primer uso)
124
+ - `CLAUDE_ANALYSIS_PROMPT.md` - Template de prompt para análisis estándar
125
+ - `CLAUDE_ANALYSIS_PROMPT_SONAR.md` - Template de prompt para análisis SonarQube
126
+ - `CLAUDE_RESOLUTION_PROMPT.md` - Template para prompt de resolución AI
127
+ 5. **`.claude-analysis-mode`** - Archivo de preferencia de modo (creado al primer uso)
115
128
 
116
129
  ### Actualización automática de .gitignore
117
130
 
@@ -122,9 +135,11 @@ Durante la instalación, Claude Hooks actualiza automáticamente tu `.gitignore`
122
135
  .claude/
123
136
  .claude-analysis-mode
124
137
  debug-claude-response.json
138
+ claude_resolution_prompt.md
125
139
  ```
126
140
 
127
141
  Esto asegura que:
142
+
128
143
  - Los archivos de configuración de Claude específicos del proyecto no se suban al repositorio
129
144
  - Los archivos de debug temporales se ignoren
130
145
  - Cada desarrollador pueda tener sus propias preferencias de análisis
@@ -144,17 +159,28 @@ Si no existe un `.gitignore`, se creará uno nuevo. Si ya existe, las entradas s
144
159
  - **Estándar**: Formato clásico con score y recomendaciones detalladas
145
160
  - **SonarQube**: Simula salida de SonarQube con Quality Gate, métricas y clasificación de issues
146
161
  4. **Construye prompt inteligente**:
147
- - Lee las pautas desde `.claude/CLAUDE_PRE_COMMIT.md` o `.claude/CLAUDE_PRE_COMMIT_SONAR.md`
162
+ - Usa template de prompt desde `.claude/CLAUDE_ANALYSIS_PROMPT*.md`
163
+ - Lee las pautas desde `.claude/CLAUDE_PRE_COMMIT*.md`
148
164
  - Incluye el diff completo para archivos nuevos
149
165
  - Muestra solo cambios para archivos existentes
150
166
  5. **Envía a Claude CLI para revisión**
151
- 6. **Procesa respuesta JSON**:
167
+ 6. **Procesa respuesta JSON estructurada**:
168
+ - blockingIssues siempre como objetos con localización precisa
152
169
  - En modo estándar: evalúa `approved`, `score`, `recommendations`
153
170
  - En modo SonarQube: verifica `QUALITY_GATE`, muestra métricas y issues por severidad
154
171
  7. **Decisión final**:
155
- - Si hay problemas críticos o quality gate falla commit bloqueado
172
+ - Si hay problemas críticos genera prompt AI de resolución y bloquea commit
156
173
  - Si todo está bien → commit procede
157
174
 
175
+ #### 🤖 Generación de Prompt de Resolución AI
176
+
177
+ Cuando se detectan problemas críticos:
178
+
179
+ - Se genera automáticamente un archivo `claude_resolution_prompt.md`
180
+ - Contiene información estructurada y AI-friendly de todos los issues
181
+ - Incluye localización precisa (archivo, línea, método)
182
+ - Puede copiarse a otra instancia de Claude para resolución automática
183
+
158
184
  ### Hook prepare-commit-msg (Generación automática de mensajes)
159
185
 
160
186
  1. **Se activa cuando el mensaje es**:
@@ -233,11 +259,13 @@ unset CLAUDE_ANALYSIS_MODE
233
259
  #### 📋 Diferencias entre Modos
234
260
 
235
261
  **Modo Estándar**:
262
+
236
263
  - Análisis con puntuación del 1-10
237
264
  - Recomendaciones detalladas por categoría
238
265
  - Formato tradicional fácil de leer
239
266
 
240
267
  **Modo SonarQube**:
268
+
241
269
  - Quality Gate (PASSED/FAILED)
242
270
  - Métricas: Reliability, Security, Maintainability
243
271
  - Issues clasificados por severidad (Blocker, Critical, Major, Minor, Info)
@@ -266,13 +294,98 @@ DEBUG=1 git commit -m "mensaje"
266
294
 
267
295
  ## 📊 Formato de Respuesta
268
296
 
269
- Claude responde con un JSON que incluye:
297
+ Claude responde con un JSON estructurado que incluye:
298
+
299
+ - `approved`: Si el commit es aprobado (boolean)
300
+ - `score`: Puntuación del 1-10 (integer)
301
+ - `blockingIssues`: Array de objetos con problemas críticos:
302
+ - `description`: Descripción del problema
303
+ - `file`: Archivo afectado
304
+ - `line`: Línea del problema
305
+ - `method`: Método o clase afectada
306
+ - `severity`: Severidad (critical, high, etc.)
307
+ - `recommendations`: Array de strings con sugerencias no bloqueantes
308
+ - `details`: Objeto con comentarios por categoría (security, performance, etc.)
309
+
310
+ ### Ejemplos de Respuestas con Problemas Críticos
311
+
312
+ #### Modo Estándar - Commit Bloqueado
313
+
314
+ ```json
315
+ {
316
+ "approved": false,
317
+ "score": 3,
318
+ "blockingIssues": [
319
+ {
320
+ "description": "SQL Injection vulnerability: concatenación directa de strings en query",
321
+ "file": "src/main/java/UserRepository.java",
322
+ "line": 45,
323
+ "method": "findUserByName",
324
+ "severity": "critical"
325
+ },
326
+ {
327
+ "description": "Posible NullPointerException: variable 'user' no validada",
328
+ "file": "src/main/java/UserService.java",
329
+ "line": 78,
330
+ "method": "processUser",
331
+ "severity": "high"
332
+ }
333
+ ],
334
+ "recommendations": [
335
+ "Usar PreparedStatement en lugar de concatenación de strings",
336
+ "Agregar validación de null antes de acceder a propiedades"
337
+ ]
338
+ }
339
+ ```
340
+
341
+ #### Modo SonarQube - Quality Gate Failed
342
+
343
+ ```json
344
+ {
345
+ "QUALITY_GATE": "FAILED",
346
+ "approved": false,
347
+ "score": 4,
348
+ "metrics": {
349
+ "reliability": "D",
350
+ "security": "E",
351
+ "maintainability": "C"
352
+ },
353
+ "issues": {
354
+ "blocker": 1,
355
+ "critical": 2,
356
+ "major": 3,
357
+ "minor": 1
358
+ },
359
+ "blockingIssues": [
360
+ {
361
+ "description": "Security Hotspot: Hardcoded credentials detected",
362
+ "file": "src/main/resources/application.yml",
363
+ "line": 23,
364
+ "method": "datasource.password",
365
+ "severity": "blocker"
366
+ },
367
+ {
368
+ "description": "Resource leak: Connection not closed in finally block",
369
+ "file": "src/main/java/DatabaseUtil.java",
370
+ "line": 112,
371
+ "method": "executeQuery",
372
+ "severity": "critical"
373
+ }
374
+ ],
375
+ "details": [
376
+ {
377
+ "severity": "BLOCKER",
378
+ "type": "VULNERABILITY",
379
+ "file": "src/main/resources/application.yml",
380
+ "line": 23,
381
+ "message": "Never store passwords in plain text",
382
+ "rule": "java:S2068"
383
+ }
384
+ ]
385
+ }
386
+ ```
270
387
 
271
- - `approved`: Si el commit es aprobado
272
- - `score`: Puntuación del 1-10
273
- - `commitMessage`: Mensaje de commit generado (type, title, body)
274
- - `recommendations`: Recomendaciones de mejora
275
- - `blockingIssues`: Problemas que bloquean el commit
388
+ Cuando se detectan estos problemas críticos, se genera automáticamente un archivo `claude_resolution_prompt.md` con toda la información necesaria para que otra instancia de Claude pueda resolver los issues de forma eficiente.
276
389
 
277
390
  ## 🔄 Actualización y Gestión
278
391
 
@@ -395,11 +508,24 @@ Este problema suele ocurrir por conflictos de configuración de line endings:
395
508
 
396
509
  ## 📝 Personalización
397
510
 
398
- Puedes modificar las pautas de evaluación editando los archivos en el directorio `.claude/`:
399
- - `.claude/CLAUDE_PRE_COMMIT.md` - Para el modo estándar
400
- - `.claude/CLAUDE_PRE_COMMIT_SONAR.md` - Para el modo SonarQube
511
+ ### Archivos de Configuración en `.claude/`
512
+
513
+ #### Pautas de Evaluación
514
+
515
+ - **`CLAUDE_PRE_COMMIT.md`** - Criterios de evaluación para modo estándar
516
+ - **`CLAUDE_PRE_COMMIT_SONAR.md`** - Criterios para modo SonarQube
517
+
518
+ #### Templates de Prompts
401
519
 
402
- Estos archivos son específicos de tu proyecto y puedes adaptarlos a los estándares de tu equipo.
520
+ - **`CLAUDE_ANALYSIS_PROMPT.md`** - Estructura del prompt de análisis estándar
521
+ - **`CLAUDE_ANALYSIS_PROMPT_SONAR.md`** - Estructura del prompt SonarQube
522
+ - **`CLAUDE_RESOLUTION_PROMPT.md`** - Template para generar prompts de resolución
523
+
524
+ Todos estos archivos son personalizables y específicos de tu proyecto. Puedes:
525
+
526
+ - Modificar los criterios de evaluación según estándares del equipo
527
+ - Ajustar la estructura de los prompts para obtener respuestas más precisas
528
+ - Personalizar el formato de salida del prompt de resolución
403
529
 
404
530
  ## 🔄 Arquitectura del Sistema
405
531
 
@@ -574,11 +700,3 @@ git commit -m "auto"
574
700
  3. **Commit** tus cambios: `git commit -m "feat: nueva funcionalidad"`
575
701
  4. **Push** al branch: `git push origin feature/nueva-funcionalidad`
576
702
  5. **Abrir Pull Request**
577
-
578
- ### Roadmap
579
-
580
- - [ ] Soporte para más lenguajes (Python, JavaScript, etc.)
581
- - [ ] Configuración más granular por proyecto
582
- - [ ] Integration con IDEs populares
583
- - [ ] Métricas de uso y performance
584
- - [ ] Tests automatizados
package/bin/claude-hooks CHANGED
@@ -339,6 +339,7 @@ async function install(args) {
339
339
  }
340
340
 
341
341
  const isForce = args.includes('--force');
342
+ const skipAuth = args.includes('--skip-auth');
342
343
 
343
344
  if (isForce) {
344
345
  info('Instalando Claude Git Hooks (modo force)...');
@@ -364,7 +365,7 @@ async function install(args) {
364
365
  }
365
366
 
366
367
  // Verificar dependencias con instalación automática
367
- await checkAndInstallDependencies(sudoPassword);
368
+ await checkAndInstallDependencies(sudoPassword, skipAuth);
368
369
 
369
370
  const templatesPath = getTemplatesPath();
370
371
  const hooksPath = '.git/hooks';
@@ -411,15 +412,26 @@ async function install(args) {
411
412
  success('.claude directory created');
412
413
  }
413
414
 
414
- // Copiar archivos de pautas a .claude si no existen
415
- const guidelines = ['CLAUDE_PRE_COMMIT.md', 'CLAUDE_PRE_COMMIT_SONAR.md'];
416
- guidelines.forEach(guideline => {
417
- const destPath = path.join(claudeDir, guideline);
418
- if (!fs.existsSync(destPath)) {
419
- const sourcePath = path.join(templatesPath, guideline);
415
+ // Copiar archivos de pautas y prompts a .claude
416
+ const claudeFiles = [
417
+ 'CLAUDE_PRE_COMMIT.md',
418
+ 'CLAUDE_PRE_COMMIT_SONAR.md',
419
+ 'CLAUDE_ANALYSIS_PROMPT.md',
420
+ 'CLAUDE_ANALYSIS_PROMPT_SONAR.md',
421
+ 'CLAUDE_RESOLUTION_PROMPT.md'
422
+ ];
423
+
424
+ claudeFiles.forEach(file => {
425
+ const destPath = path.join(claudeDir, file);
426
+ const sourcePath = path.join(templatesPath, file);
427
+
428
+ // En modo force o si no existe, copiar el archivo
429
+ if (isForce || !fs.existsSync(destPath)) {
420
430
  if (fs.existsSync(sourcePath)) {
421
431
  fs.copyFileSync(sourcePath, destPath);
422
- success(`${guideline} creado en .claude/`);
432
+ success(`${file} instalado en .claude/`);
433
+ } else {
434
+ warning(`Archivo de template no encontrado: ${file}`);
423
435
  }
424
436
  }
425
437
  });
@@ -438,7 +450,7 @@ async function install(args) {
438
450
  }
439
451
 
440
452
  // Verificar dependencias completas (como setup-wsl.sh)
441
- async function checkAndInstallDependencies(sudoPassword = null) {
453
+ async function checkAndInstallDependencies(sudoPassword = null, skipAuth = false) {
442
454
  info('Verificando dependencias del sistema...');
443
455
 
444
456
  // Verificar Node.js
@@ -522,8 +534,12 @@ async function checkAndInstallDependencies(sudoPassword = null) {
522
534
  // Verificar e instalar Claude CLI
523
535
  await checkAndInstallClaude();
524
536
 
525
- // Verificar autenticación de Claude
526
- await checkClaudeAuth();
537
+ // Verificar autenticación de Claude (si no se salta)
538
+ if (!skipAuth) {
539
+ await checkClaudeAuth();
540
+ } else {
541
+ warning('Saltando verificación de autenticación de Claude (--skip-auth)');
542
+ }
527
543
 
528
544
  // Limpiar contraseña de memoria
529
545
  sudoPassword = null;
@@ -619,7 +635,8 @@ function updateGitignore() {
619
635
  '# Claude Git Hooks',
620
636
  '.claude/',
621
637
  '.claude-analysis-mode',
622
- 'debug-claude-response.json'
638
+ 'debug-claude-response.json',
639
+ 'claude_resolution_prompt.md'
623
640
  ];
624
641
 
625
642
  let gitignoreContent = '';
@@ -970,7 +987,9 @@ Claude Git Hooks - Análisis de código y mensajes automáticos con Claude CLI
970
987
  Uso: claude-hooks <comando> [opciones]
971
988
 
972
989
  Comandos:
973
- install Instala los hooks en el repositorio actual
990
+ install [opciones] Instala los hooks en el repositorio actual
991
+ --force Reinstala aunque ya existan
992
+ --skip-auth Salta la verificación de autenticación de Claude
974
993
  update Actualiza a la última versión disponible
975
994
  uninstall Desinstala los hooks del repositorio
976
995
  enable [hook] Habilita hooks (todos o uno específico)
@@ -985,6 +1004,7 @@ Hooks disponibles:
985
1004
 
986
1005
  Ejemplos:
987
1006
  claude-hooks install # Instala todos los hooks
1007
+ claude-hooks install --skip-auth # Instala sin verificar autenticación
988
1008
  claude-hooks update # Actualiza a la última versión
989
1009
  claude-hooks set-mode sonar # Cambiar a modo SonarQube
990
1010
  claude-hooks set-mode standard # Cambiar a modo estándar
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-git-hooks",
3
- "version": "1.3.0",
3
+ "version": "1.4.1",
4
4
  "description": "Git hooks con Claude CLI para análisis de código y generación automática de mensajes de commit",
5
5
  "main": "lib/index.js",
6
6
  "bin": {
@@ -38,4 +38,4 @@
38
38
  "CHANGELOG.md",
39
39
  "LICENSE"
40
40
  ]
41
- }
41
+ }
@@ -0,0 +1,44 @@
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:
@@ -0,0 +1,61 @@
1
+ Eres un revisor de código senior con experiencia en proyectos Spring Boot empresariales y métricas SonarQube.
2
+
3
+ Tu tarea es analizar los siguientes cambios de código desde una perspectiva de calidad similar a SonarQube 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 de SonarQube:
6
+
7
+ ```json
8
+ {
9
+ "QUALITY_GATE": "PASSED", // PASSED o FAILED
10
+ "approved": true, // compatibilidad con modo estándar
11
+ "score": 1-10, // calificación general
12
+ "metrics": {
13
+ "reliability": "A", // A, B, C, D, E
14
+ "security": "A", // A, B, C, D, E
15
+ "maintainability": "A", // A, B, C, D, E
16
+ "coverage": 85, // porcentaje de cobertura estimado
17
+ "duplications": 2, // porcentaje de duplicación estimado
18
+ "complexity": 15 // complejidad ciclomática estimada
19
+ },
20
+ "issues": {
21
+ "blocker": 0, // cantidad de issues bloqueantes
22
+ "critical": 0, // cantidad de issues críticos
23
+ "major": 0, // cantidad de issues mayores
24
+ "minor": 0, // cantidad de issues menores
25
+ "info": 0 // cantidad de issues informativos
26
+ },
27
+ "details": [ // detalle de cada issue encontrado con localización
28
+ {
29
+ "severity": "CRITICAL", // BLOCKER, CRITICAL, MAJOR, MINOR, INFO
30
+ "type": "BUG", // BUG, VULNERABILITY, CODE_SMELL
31
+ "file": "src/main/java/Example.java",
32
+ "line": 42,
33
+ "method": "processData", // método o clase afectada
34
+ "message": "Null pointer dereference possible",
35
+ "rule": "java:S2259" // regla de SonarQube (opcional)
36
+ }
37
+ ],
38
+ "blockingIssues": [ // SIEMPRE array de objetos con issues BLOCKER y CRITICAL
39
+ {
40
+ "description": "texto descriptivo del problema",
41
+ "file": "path/to/file.java",
42
+ "line": 123,
43
+ "method": "methodName",
44
+ "severity": "critical" // solo "blocker" o "critical" aquí
45
+ }
46
+ ],
47
+ "securityHotspots": 0 // cantidad de security hotspots
48
+ }
49
+ ```
50
+
51
+ ✅ Importante:
52
+ - blockingIssues SIEMPRE debe ser un array de objetos, NUNCA un array de strings
53
+ - blockingIssues debe contener TODOS los issues BLOCKER y CRITICAL del array details
54
+ - Cada blockingIssue DEBE incluir: description, file, line, method, severity
55
+ - El QUALITY_GATE debe ser FAILED si hay issues BLOCKER o CRITICAL
56
+ - Los ratings (A-E) deben reflejar la calidad real del código
57
+ - Para cada issue en details, SIEMPRE incluye file, line y method para localización precisa
58
+ - No uses texto fuera del JSON
59
+ - Sé preciso con las localizaciones para facilitar la resolución automatizada
60
+
61
+ A continuación se detallan las pautas y los cambios:
@@ -0,0 +1,46 @@
1
+ # AI Resolution Assistant Prompt
2
+
3
+ You are an expert code reviewer tasked with resolving critical issues identified in a code review. Your goal is to provide precise, minimal, and efficient fixes.
4
+
5
+ ## Context
6
+ Repository: {{REPO_NAME}}
7
+ Branch: {{BRANCH_NAME}}
8
+ Commit: {{COMMIT_SHA}}
9
+ Files analyzed: {{FILE_COUNT}}
10
+ Analysis mode: {{ANALYSIS_MODE}}
11
+
12
+ ## Critical Issues to Resolve
13
+
14
+ {{BLOCKING_ISSUES}}
15
+
16
+ ## Affected Files Content
17
+
18
+ {{FILE_CONTENTS}}
19
+
20
+ ## Instructions
21
+
22
+ 1. For each critical issue:
23
+ - Navigate to the exact file and line number specified
24
+ - Understand the context and the problem
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
33
+
34
+ 3. Output format:
35
+ - Provide exact code changes using diff format
36
+ - Include file path, line numbers, and context
37
+ - Explain each fix briefly (one line max)
38
+
39
+ ## Fix Priority
40
+ 1. Security vulnerabilities (highest)
41
+ 2. Null pointer / runtime errors
42
+ 3. Logic errors
43
+ 4. Performance issues
44
+ 5. Code quality issues (lowest)
45
+
46
+ Begin fixing the issues in order of severity.
@@ -56,6 +56,99 @@ if [ -n "$CHECK_VERSION_SCRIPT" ]; then
56
56
  check_version
57
57
  fi
58
58
 
59
+ # Función para generar prompt de resolución AI-friendly
60
+ generate_resolution_prompt() {
61
+ local RESOLUTION_FILE="./claude_resolution_prompt.md"
62
+ local RESOLUTION_TEMPLATE=".claude/CLAUDE_RESOLUTION_PROMPT.md"
63
+
64
+ if [ ! -f "$RESOLUTION_TEMPLATE" ]; then
65
+ warning "No se encontró template de resolución: $RESOLUTION_TEMPLATE"
66
+ return
67
+ fi
68
+
69
+ # Obtener información del contexto
70
+ local REPO_NAME=$(basename $(git rev-parse --show-toplevel))
71
+ local BRANCH_NAME=$(git rev-parse --abbrev-ref HEAD)
72
+ local COMMIT_SHA="pending"
73
+ local FILE_COUNT=$(echo "$JAVA_FILES" | wc -l)
74
+
75
+ # Formatear los blocking issues para el prompt de resolución
76
+ local ISSUES_FORMATTED=""
77
+ local issue_num=1
78
+
79
+ # Usar un archivo temporal para acumular los issues
80
+ local TEMP_ISSUES=$(mktemp)
81
+
82
+ # Parsear cada blocking issue como objeto JSON
83
+ echo "$JSON_RESPONSE" | jq -c '.blockingIssues[]?' 2>/dev/null | while IFS= read -r issue; do
84
+ if [ -n "$issue" ]; then
85
+ local desc=$(echo "$issue" | jq -r '.description')
86
+ local file=$(echo "$issue" | jq -r '.file')
87
+ local line=$(echo "$issue" | jq -r '.line')
88
+ local method=$(echo "$issue" | jq -r '.method')
89
+ local severity=$(echo "$issue" | jq -r '.severity')
90
+
91
+ echo "### Issue #${issue_num} [${severity^^}]" >> "$TEMP_ISSUES"
92
+ echo "**Description:** ${desc}" >> "$TEMP_ISSUES"
93
+ echo "**Location:** ${file}:${line}" >> "$TEMP_ISSUES"
94
+ echo "**Method/Class:** ${method}" >> "$TEMP_ISSUES"
95
+ echo "" >> "$TEMP_ISSUES"
96
+ issue_num=$((issue_num + 1))
97
+ fi
98
+ done
99
+
100
+ # Leer el contenido acumulado
101
+ ISSUES_FORMATTED=$(cat "$TEMP_ISSUES")
102
+ rm -f "$TEMP_ISSUES"
103
+
104
+ # Generar el prompt desde el template
105
+ cp "$RESOLUTION_TEMPLATE" "$RESOLUTION_FILE"
106
+
107
+ # Reemplazar placeholders - usar comillas dobles y escapar caracteres especiales
108
+ sed -i "s|{{REPO_NAME}}|${REPO_NAME}|g" "$RESOLUTION_FILE"
109
+ sed -i "s|{{BRANCH_NAME}}|${BRANCH_NAME}|g" "$RESOLUTION_FILE"
110
+ sed -i "s|{{COMMIT_SHA}}|${COMMIT_SHA}|g" "$RESOLUTION_FILE"
111
+ sed -i "s|{{FILE_COUNT}}|${FILE_COUNT}|g" "$RESOLUTION_FILE"
112
+ sed -i "s|{{ANALYSIS_MODE}}|${ANALYSIS_MODE:-standard}|g" "$RESOLUTION_FILE"
113
+
114
+ # Crear archivo temporal para issues formateados
115
+ local TEMP_ISSUES_FILE=$(mktemp)
116
+ echo "$ISSUES_FORMATTED" > "$TEMP_ISSUES_FILE"
117
+
118
+ # Reemplazar {{BLOCKING_ISSUES}} con el contenido
119
+ if [ -n "$ISSUES_FORMATTED" ]; then
120
+ sed -i "/{{BLOCKING_ISSUES}}/r $TEMP_ISSUES_FILE" "$RESOLUTION_FILE"
121
+ fi
122
+ sed -i "s|{{BLOCKING_ISSUES}}||g" "$RESOLUTION_FILE"
123
+ rm -f "$TEMP_ISSUES_FILE"
124
+
125
+ # Agregar contenido de archivos afectados
126
+ local TEMP_FILES=$(mktemp)
127
+ echo "$JSON_RESPONSE" | jq -r '.blockingIssues[].file' 2>/dev/null | sort -u | while IFS= read -r file; do
128
+ if [ -f "$file" ]; then
129
+ echo "### File: $file" >> "$TEMP_FILES"
130
+ echo "" >> "$TEMP_FILES"
131
+ echo '```' >> "$TEMP_FILES"
132
+ cat "$file" >> "$TEMP_FILES"
133
+ echo '```' >> "$TEMP_FILES"
134
+ echo "" >> "$TEMP_FILES"
135
+ fi
136
+ done
137
+
138
+ # Reemplazar {{FILE_CONTENTS}} con el contenido
139
+ if [ -s "$TEMP_FILES" ]; then
140
+ sed -i "/{{FILE_CONTENTS}}/r $TEMP_FILES" "$RESOLUTION_FILE"
141
+ fi
142
+ sed -i "s|{{FILE_CONTENTS}}||g" "$RESOLUTION_FILE"
143
+ rm -f "$TEMP_FILES"
144
+
145
+ echo
146
+ echo -e "${YELLOW}=== PROMPT DE RESOLUCIÓN AI GENERADO ===${NC}"
147
+ echo -e "${GREEN}Se ha generado un prompt AI-friendly en: ${BLUE}$RESOLUTION_FILE${NC}"
148
+ echo -e "${YELLOW}Copia este archivo a una nueva instancia de Claude para resolver los problemas automáticamente.${NC}"
149
+ echo
150
+ }
151
+
59
152
  # Detectar qué archivo de pautas usar
60
153
  # Prioridad: variable de entorno > archivo > pregunta interactiva
61
154
  if [ -n "$CLAUDE_ANALYSIS_MODE" ]; then
@@ -92,9 +185,11 @@ if [ "$ANALYSIS_MODE" != "standard" ] && [ "$ANALYSIS_MODE" != "sonar" ]; then
92
185
  if [ "$REPLY" = "2" ]; then
93
186
  ANALYSIS_MODE="sonar"
94
187
  GUIDELINES_FILE=".claude/CLAUDE_PRE_COMMIT_SONAR.md"
188
+ PROMPT_TEMPLATE=".claude/CLAUDE_ANALYSIS_PROMPT_SONAR.md"
95
189
  else
96
190
  ANALYSIS_MODE="standard"
97
191
  GUIDELINES_FILE=".claude/CLAUDE_PRE_COMMIT.md"
192
+ PROMPT_TEMPLATE=".claude/CLAUDE_ANALYSIS_PROMPT.md"
98
193
  fi
99
194
 
100
195
  # Guardar preferencia para futuros commits
@@ -106,12 +201,23 @@ else
106
201
  # Usar modo guardado
107
202
  if [ "$ANALYSIS_MODE" = "sonar" ]; then
108
203
  GUIDELINES_FILE=".claude/CLAUDE_PRE_COMMIT_SONAR.md"
204
+ PROMPT_TEMPLATE=".claude/CLAUDE_ANALYSIS_PROMPT_SONAR.md"
109
205
  log "Usando modo de análisis: SonarQube"
110
206
  else
111
207
  GUIDELINES_FILE=".claude/CLAUDE_PRE_COMMIT.md"
208
+ PROMPT_TEMPLATE=".claude/CLAUDE_ANALYSIS_PROMPT.md"
112
209
  log "Usando modo de análisis: Estándar"
113
210
  fi
114
211
  fi
212
+
213
+ # Verificar que el template de prompt existe
214
+ if [ ! -f "$PROMPT_TEMPLATE" ]; then
215
+ error "No se encontró el template de prompt: $PROMPT_TEMPLATE"
216
+ error "Los archivos de configuración de Claude parecen estar incompletos."
217
+ error "Por favor, reinstala claude-git-hooks ejecutando:"
218
+ error " claude-hooks install --force"
219
+ exit 1
220
+ fi
115
221
  # Función para limpiar archivos temporales
116
222
  cleanup() {
117
223
  rm -rf "$TEMP_DIR"
@@ -140,9 +246,10 @@ fi
140
246
 
141
247
  # Verificar si existe el archivo de pautas
142
248
  if [ ! -f "$GUIDELINES_FILE" ]; then
143
- warning "No se encontró el archivo de pautas: $GUIDELINES_FILE"
144
- warning "Saltando análisis de código"
145
- exit 0
249
+ error "No se encontró el archivo de pautas: $GUIDELINES_FILE"
250
+ error "Por favor, reinstala claude-git-hooks ejecutando:"
251
+ error " claude-hooks install --force"
252
+ exit 1
146
253
  fi
147
254
 
148
255
  log "Archivos Java/config a revisar: $(echo "$JAVA_FILES" | wc -l)"
@@ -150,42 +257,8 @@ log "Archivos Java/config a revisar: $(echo "$JAVA_FILES" | wc -l)"
150
257
  # Construir el prompt para análisis de código
151
258
  PROMPT_FILE="$TEMP_DIR/code_review_prompt.txt"
152
259
 
153
- cat > "$PROMPT_FILE" << 'EOF'
154
- Eres un revisor de código senior con experiencia en proyectos Spring Boot empresariales.
155
-
156
- 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.
157
-
158
- ⚠️ La respuesta debe ser un objeto JSON con esta estructura exacta:
159
-
160
- {
161
- "approved": true, // true si el commit puede aceptarse, false si debe bloquearse
162
- "score": 1-10, // calificación de calidad (entero)
163
- "blockingIssues": [ // lista de errores críticos (vacía si no hay)
164
- "texto descriptivo 1",
165
- "texto descriptivo 2"
166
- ],
167
- "recommendations": [ // sugerencias no bloqueantes
168
- "mejora 1",
169
- "mejora 2"
170
- ],
171
- "details": {
172
- "security": [ // comentarios específicos por área
173
- "observación sobre seguridad"
174
- ],
175
- "architecture": [ "..." ],
176
- "performance": [ "..." ],
177
- "maintainability": [ "..." ]
178
- }
179
- }
180
-
181
- ✅ Importante:
182
- - Usa listas aunque estén vacías (por ejemplo `"blockingIssues": []`)
183
- - No uses texto introductorio o explicaciones fuera del JSON
184
- - No omitas claves aunque estén vacías
185
- - Sé directo, claro y profesional en tus observaciones
186
-
187
- A continuación se detallan las pautas y los cambios:
188
- EOF
260
+ # Copiar el template de prompt
261
+ cat "$PROMPT_TEMPLATE" > "$PROMPT_FILE"
189
262
 
190
263
  # Agregar las pautas
191
264
  echo "=== PAUTAS DE EVALUACIÓN ===" >> "$PROMPT_FILE"
@@ -257,7 +330,14 @@ if $CLAUDE_CLI < "$PROMPT_FILE" > "$RESPONSE_FILE" 2>&1; then
257
330
  APPROVED=$(echo "$JSON_RESPONSE" | jq -r '.approved // false')
258
331
  SCORE=$(echo "$JSON_RESPONSE" | jq -r '.score // 0')
259
332
  RECOMMENDATIONS=$(echo "$JSON_RESPONSE" | jq -r '.recommendations[]?' 2>/dev/null | sed '/^$/d')
260
- BLOCKING_ISSUES=$(echo "$JSON_RESPONSE" | jq -r '.blockingIssues[]?' 2>/dev/null | sed '/^$/d')
333
+
334
+ # Parsear blockingIssues como objetos y extraer las descripciones
335
+ BLOCKING_ISSUES=""
336
+ BLOCKING_COUNT=$(echo "$JSON_RESPONSE" | jq '.blockingIssues | length' 2>/dev/null || echo "0")
337
+
338
+ if [ "$BLOCKING_COUNT" -gt 0 ]; then
339
+ BLOCKING_ISSUES=$(echo "$JSON_RESPONSE" | jq -r '.blockingIssues[].description' 2>/dev/null | sed '/^$/d')
340
+ fi
261
341
 
262
342
  # Verificar si estamos en modo SonarQube
263
343
  QUALITY_GATE=$(echo "$JSON_RESPONSE" | jq -r '.QUALITY_GATE // ""' 2>/dev/null)
@@ -356,6 +436,9 @@ if $CLAUDE_CLI < "$PROMPT_FILE" > "$RESPONSE_FILE" 2>&1; then
356
436
  echo
357
437
  echo "=== PROBLEMAS CRÍTICOS ==="
358
438
  echo "$BLOCKING_ISSUES" | sed 's/^/- /'
439
+
440
+ # Generar prompt de resolución AI-friendly
441
+ generate_resolution_prompt
359
442
  fi
360
443
  exit 1
361
444
  fi