claude-git-hooks 1.3.0 → 1.4.0

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.0",
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": {
@@ -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,77 @@ 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
+ # Parsear cada blocking issue como objeto JSON
80
+ echo "$JSON_RESPONSE" | jq -c '.blockingIssues[]?' 2>/dev/null | while IFS= read -r issue; do
81
+ if [ -n "$issue" ]; then
82
+ local desc=$(echo "$issue" | jq -r '.description')
83
+ local file=$(echo "$issue" | jq -r '.file')
84
+ local line=$(echo "$issue" | jq -r '.line')
85
+ local method=$(echo "$issue" | jq -r '.method')
86
+ local severity=$(echo "$issue" | jq -r '.severity')
87
+
88
+ ISSUES_FORMATTED="${ISSUES_FORMATTED}### Issue #${issue_num} [${severity^^}]\n"
89
+ ISSUES_FORMATTED="${ISSUES_FORMATTED}**Description:** ${desc}\n"
90
+ ISSUES_FORMATTED="${ISSUES_FORMATTED}**Location:** ${file}:${line}\n"
91
+ ISSUES_FORMATTED="${ISSUES_FORMATTED}**Method/Class:** ${method}\n\n"
92
+ issue_num=$((issue_num + 1))
93
+ fi
94
+ done
95
+
96
+ # Generar el prompt desde el template
97
+ cp "$RESOLUTION_TEMPLATE" "$RESOLUTION_FILE"
98
+
99
+ # Reemplazar placeholders
100
+ sed -i "s|{{REPO_NAME}}|$REPO_NAME|g" "$RESOLUTION_FILE"
101
+ sed -i "s|{{BRANCH_NAME}}|$BRANCH_NAME|g" "$RESOLUTION_FILE"
102
+ sed -i "s|{{COMMIT_SHA}}|$COMMIT_SHA|g" "$RESOLUTION_FILE"
103
+ sed -i "s|{{FILE_COUNT}}|$FILE_COUNT|g" "$RESOLUTION_FILE"
104
+ sed -i "s|{{ANALYSIS_MODE}}|$ANALYSIS_MODE|g" "$RESOLUTION_FILE"
105
+
106
+ # Agregar los issues formateados
107
+ sed -i "/{{BLOCKING_ISSUES}}/r /dev/stdin" "$RESOLUTION_FILE" <<< "$ISSUES_FORMATTED"
108
+ sed -i "s|{{BLOCKING_ISSUES}}||g" "$RESOLUTION_FILE"
109
+
110
+ # Agregar contenido de archivos afectados
111
+ local FILES_CONTENT=""
112
+ echo "$JSON_RESPONSE" | jq -r '.blockingIssues[].file' 2>/dev/null | sort -u | while IFS= read -r file; do
113
+ if [ -f "$file" ]; then
114
+ FILES_CONTENT="${FILES_CONTENT}### File: $file\n\n\`\`\`\n"
115
+ FILES_CONTENT="${FILES_CONTENT}$(cat "$file")\n"
116
+ FILES_CONTENT="${FILES_CONTENT}\`\`\`\n\n"
117
+ fi
118
+ done
119
+
120
+ sed -i "/{{FILE_CONTENTS}}/r /dev/stdin" "$RESOLUTION_FILE" <<< "$FILES_CONTENT"
121
+ sed -i "s|{{FILE_CONTENTS}}||g" "$RESOLUTION_FILE"
122
+
123
+ echo
124
+ echo -e "${YELLOW}=== PROMPT DE RESOLUCIÓN AI GENERADO ===${NC}"
125
+ echo -e "${GREEN}Se ha generado un prompt AI-friendly en: ${BLUE}$RESOLUTION_FILE${NC}"
126
+ echo -e "${YELLOW}Copia este archivo a una nueva instancia de Claude para resolver los problemas automáticamente.${NC}"
127
+ echo
128
+ }
129
+
59
130
  # Detectar qué archivo de pautas usar
60
131
  # Prioridad: variable de entorno > archivo > pregunta interactiva
61
132
  if [ -n "$CLAUDE_ANALYSIS_MODE" ]; then
@@ -92,9 +163,11 @@ if [ "$ANALYSIS_MODE" != "standard" ] && [ "$ANALYSIS_MODE" != "sonar" ]; then
92
163
  if [ "$REPLY" = "2" ]; then
93
164
  ANALYSIS_MODE="sonar"
94
165
  GUIDELINES_FILE=".claude/CLAUDE_PRE_COMMIT_SONAR.md"
166
+ PROMPT_TEMPLATE=".claude/CLAUDE_ANALYSIS_PROMPT_SONAR.md"
95
167
  else
96
168
  ANALYSIS_MODE="standard"
97
169
  GUIDELINES_FILE=".claude/CLAUDE_PRE_COMMIT.md"
170
+ PROMPT_TEMPLATE=".claude/CLAUDE_ANALYSIS_PROMPT.md"
98
171
  fi
99
172
 
100
173
  # Guardar preferencia para futuros commits
@@ -106,12 +179,23 @@ else
106
179
  # Usar modo guardado
107
180
  if [ "$ANALYSIS_MODE" = "sonar" ]; then
108
181
  GUIDELINES_FILE=".claude/CLAUDE_PRE_COMMIT_SONAR.md"
182
+ PROMPT_TEMPLATE=".claude/CLAUDE_ANALYSIS_PROMPT_SONAR.md"
109
183
  log "Usando modo de análisis: SonarQube"
110
184
  else
111
185
  GUIDELINES_FILE=".claude/CLAUDE_PRE_COMMIT.md"
186
+ PROMPT_TEMPLATE=".claude/CLAUDE_ANALYSIS_PROMPT.md"
112
187
  log "Usando modo de análisis: Estándar"
113
188
  fi
114
189
  fi
190
+
191
+ # Verificar que el template de prompt existe
192
+ if [ ! -f "$PROMPT_TEMPLATE" ]; then
193
+ error "No se encontró el template de prompt: $PROMPT_TEMPLATE"
194
+ error "Los archivos de configuración de Claude parecen estar incompletos."
195
+ error "Por favor, reinstala claude-git-hooks ejecutando:"
196
+ error " claude-hooks install --force"
197
+ exit 1
198
+ fi
115
199
  # Función para limpiar archivos temporales
116
200
  cleanup() {
117
201
  rm -rf "$TEMP_DIR"
@@ -140,9 +224,10 @@ fi
140
224
 
141
225
  # Verificar si existe el archivo de pautas
142
226
  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
227
+ error "No se encontró el archivo de pautas: $GUIDELINES_FILE"
228
+ error "Por favor, reinstala claude-git-hooks ejecutando:"
229
+ error " claude-hooks install --force"
230
+ exit 1
146
231
  fi
147
232
 
148
233
  log "Archivos Java/config a revisar: $(echo "$JAVA_FILES" | wc -l)"
@@ -150,42 +235,8 @@ log "Archivos Java/config a revisar: $(echo "$JAVA_FILES" | wc -l)"
150
235
  # Construir el prompt para análisis de código
151
236
  PROMPT_FILE="$TEMP_DIR/code_review_prompt.txt"
152
237
 
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
238
+ # Copiar el template de prompt
239
+ cat "$PROMPT_TEMPLATE" > "$PROMPT_FILE"
189
240
 
190
241
  # Agregar las pautas
191
242
  echo "=== PAUTAS DE EVALUACIÓN ===" >> "$PROMPT_FILE"
@@ -257,7 +308,14 @@ if $CLAUDE_CLI < "$PROMPT_FILE" > "$RESPONSE_FILE" 2>&1; then
257
308
  APPROVED=$(echo "$JSON_RESPONSE" | jq -r '.approved // false')
258
309
  SCORE=$(echo "$JSON_RESPONSE" | jq -r '.score // 0')
259
310
  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')
311
+
312
+ # Parsear blockingIssues como objetos y extraer las descripciones
313
+ BLOCKING_ISSUES=""
314
+ BLOCKING_COUNT=$(echo "$JSON_RESPONSE" | jq '.blockingIssues | length' 2>/dev/null || echo "0")
315
+
316
+ if [ "$BLOCKING_COUNT" -gt 0 ]; then
317
+ BLOCKING_ISSUES=$(echo "$JSON_RESPONSE" | jq -r '.blockingIssues[].description' 2>/dev/null | sed '/^$/d')
318
+ fi
261
319
 
262
320
  # Verificar si estamos en modo SonarQube
263
321
  QUALITY_GATE=$(echo "$JSON_RESPONSE" | jq -r '.QUALITY_GATE // ""' 2>/dev/null)
@@ -356,6 +414,9 @@ if $CLAUDE_CLI < "$PROMPT_FILE" > "$RESPONSE_FILE" 2>&1; then
356
414
  echo
357
415
  echo "=== PROBLEMAS CRÍTICOS ==="
358
416
  echo "$BLOCKING_ISSUES" | sed 's/^/- /'
417
+
418
+ # Generar prompt de resolución AI-friendly
419
+ generate_resolution_prompt
359
420
  fi
360
421
  exit 1
361
422
  fi