claude-git-hooks 2.0.0 → 2.1.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,40 @@ 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
+ ## [2.1.0] - 2025-11-04
9
+
10
+ ### Changed
11
+
12
+ - 🔄 Renombrado marcador de exclusión de línea única: `// SKIP-ANALYSIS` → `// SKIP_ANALYSIS_LINE` para consistencia de nomenclatura
13
+ - 🐛 Corregido bug crítico en orden de detección de patrones que impedía funcionamiento de `SKIP_ANALYSIS_BLOCK`
14
+
15
+ ### Known Issues
16
+
17
+ - ⚠️ **SKIP_ANALYSIS marcado como EXPERIMENTAL/BROKEN**: Los marcadores de exclusión no funcionan correctamente porque el análisis se realiza sobre git diff en lugar del archivo completo. Marcadores agregados en commits anteriores no son detectados en cambios subsecuentes.
18
+
19
+ ### Migration Guide
20
+
21
+ Si utilizabas `// SKIP-ANALYSIS` en tu código, reemplázalo por `// SKIP_ANALYSIS_LINE`:
22
+
23
+ ```java
24
+ // Antes (deprecated):
25
+ // SKIP-ANALYSIS
26
+ private String legacyCode;
27
+
28
+ // Ahora:
29
+ // SKIP_ANALYSIS_LINE
30
+ private String legacyCode;
31
+ ```
32
+
33
+ El marcador de bloque `// SKIP_ANALYSIS_BLOCK` permanece sin cambios.
34
+
35
+ ## [2.0.1] - 2025-11-04
36
+
37
+ ### Fixed
38
+
39
+ - 🔧 Compatibilidad completa en Windows: corregidos line endings CRLF, validación WSL, y comparación de versiones sin dependencia bash
40
+ - 🔧 Operaciones de rutas utilizan módulo `path` nativo para mejor portabilidad multiplataforma
41
+
8
42
  ## [2.0.0] - 2025-10-30
9
43
 
10
44
  ### 🚀 BREAKING CHANGE: Migration from Bash to Node.js Hooks
package/README.md CHANGED
@@ -16,7 +16,7 @@
16
16
  - 🔍 **Análisis de código pre-commit**: Detecta issues críticos antes de que lleguen al repo
17
17
  - 💬 **Mensajes de commit automáticos**: Escribe "auto" y Claude genera el mensaje
18
18
  - 📋 **Generación de PRs**: Título, descripción y tests sugeridos con un solo comando
19
- - 🚫 **Skip inteligente**: Excluye código con comentarios SKIP-ANALYSIS
19
+ - ⚠️ **Skip inteligente** (EXPERIMENTAL/BROKEN): Exclusión de código con comentarios SKIP_ANALYSIS - no funciona correctamente con git diff
20
20
  - 🕵️‍♂️ **Paralelización**: Análisis asincrónico de archivos con sub agentes
21
21
  - 🔄 **Auto-actualización**: Se mantiene actualizado automáticamente
22
22
  - 🌍 **Cross-platform**: Windows, WSL, macOS, Linux sin configuración especial
@@ -85,10 +85,13 @@ git commit --no-verify -m "hotfix: corrección urgente"
85
85
  git commit --amend
86
86
  ```
87
87
 
88
- ### 🚫 Exclusión de Código del Análisis
88
+ ### ⚠️ Exclusión de Código del Análisis (EXPERIMENTAL/BROKEN)
89
89
 
90
90
  ```java
91
- // SKIP-ANALYSIS
91
+ // NOTA: Este feature NO funciona correctamente
92
+ // Los marcadores no son detectados si fueron agregados en commits anteriores
93
+
94
+ // SKIP_ANALYSIS_LINE
92
95
  private String legacyCode = "no analizar siguiente línea";
93
96
 
94
97
  // SKIP_ANALYSIS_BLOCK
@@ -347,21 +350,19 @@ Si no existe un `.gitignore`, se creará uno nuevo. Si ya existe, las entradas s
347
350
  - **Modo debug**: `DEBUG=1 git commit` guarda respuestas en `debug-claude-response.json`
348
351
  - **Análisis de PR**: Nuevo comando `analyze-diff` para generar información de Pull Requests
349
352
  - **Validación de dependencias**: Verifica que Claude CLI esté autenticado antes de ejecutar
350
- - **Exclusión de código del análisis con SKIP-ANALYSIS**: Puedes excluir código específico del análisis usando comentarios `// SKIP-ANALYSIS`:
353
+ - **⚠️ Exclusión de código del análisis (EXPERIMENTAL/BROKEN)**: Los marcadores `// SKIP_ANALYSIS_LINE` y `// SKIP_ANALYSIS_BLOCK` no funcionan correctamente. El hook analiza git diff en lugar del archivo completo, por lo que marcadores agregados en commits anteriores no son detectados en cambios subsecuentes.
351
354
 
352
355
  ```java
353
- // Excluir una sola línea
354
- // SKIP-ANALYSIS
355
- @Autowired private LegacyService legacyService; // Esta línea no será analizada
356
+ // NOTA: Este feature actualmente NO funciona de forma confiable
357
+ // SKIP_ANALYSIS_LINE
358
+ @Autowired private LegacyService legacyService;
356
359
 
357
- // Excluir un bloque de código
358
- // SKIP-ANALYSIS_BLOCK
360
+ // SKIP_ANALYSIS_BLOCK
359
361
  @Deprecated
360
362
  public void methodWithKnownIssues() {
361
- // Código legacy que no queremos que sea analizado
362
- System.out.println("Debug temporal");
363
+ System.out.println("Legacy code");
363
364
  }
364
- // SKIP-ANALYSIS_BLOCK
365
+ // SKIP_ANALYSIS_BLOCK
365
366
  ```
366
367
 
367
368
  ### Desactivar/Activar hooks
@@ -437,7 +438,7 @@ claude-git-hooks/
437
438
  │ └── utils/
438
439
  │ ├── logger.js # Sistema de logging centralizado
439
440
  │ ├── git-operations.js # Operaciones git abstractas
440
- │ ├── file-operations.js # I/O con filtro SKIP-ANALYSIS
441
+ │ ├── file-operations.js # I/O con filtro SKIP_ANALYSIS_LINE
441
442
  │ ├── claude-client.js # Cliente Claude CLI
442
443
  │ ├── prompt-builder.js # Constructor de prompts
443
444
  │ └── resolution-prompt.js # Generador de resolution prompts
package/bin/claude-hooks CHANGED
@@ -429,11 +429,10 @@ async function install(args) {
429
429
  console.log(' git commit -m "auto" # Generate message automatically');
430
430
  console.log(' git commit -m "message" # Analyze code before commit');
431
431
  console.log(' git commit --no-verify # Skip analysis completely');
432
- console.log('\nExclude code from analysis:');
433
- console.log(' // SKIP-ANALYSIS # Exclude the next line');
434
- console.log(' // SKIP_ANALYSIS_BLOCK # Exclude block until finding another equal one');
435
- console.log(' ...excluded code...');
436
- console.log(' // SKIP_ANALYSIS_BLOCK');
432
+ console.log('\n⚠️ Exclude code from analysis (EXPERIMENTAL/BROKEN):');
433
+ console.log(' // SKIP_ANALYSIS_LINE # Does NOT work reliably');
434
+ console.log(' // SKIP_ANALYSIS_BLOCK # Does NOT work reliably');
435
+ console.log(' // Reason: Analyzes git diff, not full file');
437
436
  console.log('\nNEW: Parallel analysis for faster multi-file commits:');
438
437
  console.log(' export CLAUDE_USE_SUBAGENTS=true # Enable subagents');
439
438
  console.log(' export CLAUDE_SUBAGENT_MODEL=haiku # haiku/sonnet/opus');
@@ -1064,36 +1063,24 @@ function setMode(mode) {
1064
1063
  }
1065
1064
  }
1066
1065
 
1067
- // Función para comparar versiones usando el script compartido
1066
+ // Cross-platform version comparison (semver)
1067
+ // Why: Pure JavaScript, no bash dependency
1068
+ // Returns: 0 if equal, 1 if v1 > v2, -1 if v1 < v2
1068
1069
  function compareVersions(v1, v2) {
1069
- try {
1070
- // Usar el script compartido para mantener consistencia
1071
- const result = execSync(`bash -c 'source "${getTemplatesPath()}/check-version.sh" && compare_versions "${v1}" "${v2}"; echo $?'`, { encoding: 'utf8' }).trim();
1072
- const exitCode = parseInt(result);
1073
-
1074
- // Convertir los códigos de retorno del script bash a valores JS
1075
- if (exitCode === 0) return 0; // iguales
1076
- if (exitCode === 1) return 1; // v1 > v2
1077
- if (exitCode === 2) return -1; // v1 < v2
1078
-
1079
- // Fallback: comparación simple si el script falla
1080
- if (v1 === v2) return 0;
1081
- const sorted = [v1, v2].sort((a, b) => {
1082
- const aParts = a.split('.').map(Number);
1083
- const bParts = b.split('.').map(Number);
1084
- for (let i = 0; i < Math.max(aParts.length, bParts.length); i++) {
1085
- const aPart = aParts[i] || 0;
1086
- const bPart = bParts[i] || 0;
1087
- if (aPart !== bPart) return aPart - bPart;
1088
- }
1089
- return 0;
1090
- });
1091
- return v1 === sorted[1] ? 1 : -1;
1092
- } catch (e) {
1093
- // Si falla todo, usar comparación simple
1094
- if (v1 === v2) return 0;
1095
- return v1 > v2 ? 1 : -1;
1070
+ if (v1 === v2) return 0;
1071
+
1072
+ const v1Parts = v1.split('.').map(Number);
1073
+ const v2Parts = v2.split('.').map(Number);
1074
+
1075
+ for (let i = 0; i < Math.max(v1Parts.length, v2Parts.length); i++) {
1076
+ const v1Part = v1Parts[i] || 0;
1077
+ const v2Part = v2Parts[i] || 0;
1078
+
1079
+ if (v1Part > v2Part) return 1;
1080
+ if (v1Part < v2Part) return -1;
1096
1081
  }
1082
+
1083
+ return 0;
1097
1084
  }
1098
1085
 
1099
1086
  // Update command - update to the latest version
@@ -1189,11 +1176,10 @@ Analyze-diff use case:
1189
1176
  → PR Description: "## Summary\n- Added JWT authentication..."
1190
1177
  → Suggested branch: "feature/user-authentication"
1191
1178
 
1192
- Exclude code from analysis:
1193
- // SKIP-ANALYSIS # Exclude the next line from analysis
1194
- // SKIP_ANALYSIS_BLOCK # Exclude block until finding another equal one
1195
- ...excluded code...
1196
- // SKIP_ANALYSIS_BLOCK
1179
+ ⚠️ Exclude code from analysis (EXPERIMENTAL/BROKEN):
1180
+ // SKIP_ANALYSIS_LINE # Does NOT work reliably
1181
+ // SKIP_ANALYSIS_BLOCK # Does NOT work reliably
1182
+ Reason: Analyzes git diff, not full file
1197
1183
 
1198
1184
  Performance optimization (NEW in v1.5.5):
1199
1185
  export CLAUDE_USE_SUBAGENTS=true # Enable parallel analysis for 3+ files
@@ -205,7 +205,7 @@ const main = async () => {
205
205
  // Get diff
206
206
  let diff = getFileDiff(filePath);
207
207
 
208
- // Apply SKIP-ANALYSIS filtering
208
+ // Apply SKIP_ANALYSIS filtering
209
209
  diff = filterSkipAnalysis(diff);
210
210
 
211
211
  // Check if new file
@@ -121,11 +121,21 @@ const readFile = async (filePath, { maxSize = 100000, encoding = 'utf8' } = {})
121
121
  };
122
122
 
123
123
  /**
124
- * Filters SKIP-ANALYSIS patterns from code content
124
+ * Filters SKIP_ANALYSIS patterns from code content
125
125
  * Why: Allows developers to exclude specific code from analysis
126
126
  *
127
+ * ⚠️ KNOWN ISSUE (EXPERIMENTAL/BROKEN):
128
+ * This feature does NOT work reliably. The pre-commit hook analyzes git diff
129
+ * instead of full file content. Markers added in previous commits are NOT
130
+ * present in subsequent diffs, so they are not detected.
131
+ *
132
+ * Example of failure:
133
+ * - Commit 1: Add // SKIP_ANALYSIS_BLOCK markers
134
+ * - Commit 2: Modify line inside block
135
+ * - Result: Diff only shows modified line, NOT the markers → filter fails
136
+ *
127
137
  * Supports two patterns:
128
- * 1. Single line: // SKIP-ANALYSIS (excludes next line)
138
+ * 1. Single line: // SKIP_ANALYSIS_LINE (excludes next line)
129
139
  * 2. Block: // SKIP_ANALYSIS_BLOCK ... // SKIP_ANALYSIS_BLOCK (excludes block)
130
140
  *
131
141
  * @param {string} content - File content to filter
@@ -134,7 +144,7 @@ const readFile = async (filePath, { maxSize = 100000, encoding = 'utf8' } = {})
134
144
  const filterSkipAnalysis = (content) => {
135
145
  logger.debug(
136
146
  'file-operations - filterSkipAnalysis',
137
- 'Filtering SKIP-ANALYSIS patterns',
147
+ 'Filtering SKIP_ANALYSIS patterns',
138
148
  { originalLength: content.length }
139
149
  );
140
150
 
@@ -145,11 +155,8 @@ const filterSkipAnalysis = (content) => {
145
155
  // Why: Use map instead of filter to preserve line numbers for error reporting
146
156
  // Empty lines maintain original line number mapping
147
157
  const filteredLines = lines.map((line) => {
148
- // Detect single-line SKIP-ANALYSIS
149
- if (line.includes('// SKIP-ANALYSIS')) {
150
- skipNext = true;
151
- return ''; // Preserve line number
152
- }
158
+ // IMPORTANT: Check specific pattern first (SKIP_ANALYSIS_BLOCK)
159
+ // before general pattern (SKIP_ANALYSIS_LINE) to avoid substring match issues
153
160
 
154
161
  // Detect SKIP_ANALYSIS_BLOCK (toggle block state)
155
162
  if (line.includes('// SKIP_ANALYSIS_BLOCK')) {
@@ -157,12 +164,18 @@ const filterSkipAnalysis = (content) => {
157
164
  return ''; // Preserve line number
158
165
  }
159
166
 
167
+ // Detect single-line SKIP_ANALYSIS_LINE (must check AFTER block check)
168
+ if (line.includes('// SKIP_ANALYSIS_LINE')) {
169
+ skipNext = true;
170
+ return ''; // Preserve line number
171
+ }
172
+
160
173
  // Skip lines inside block
161
174
  if (inSkipBlock) {
162
175
  return '';
163
176
  }
164
177
 
165
- // Skip next line after single SKIP-ANALYSIS
178
+ // Skip next line after single SKIP_ANALYSIS_LINE
166
179
  if (skipNext) {
167
180
  skipNext = false;
168
181
  return '';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-git-hooks",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "Git hooks with Claude CLI for code analysis and automatic commit messages",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",