claude-git-hooks 1.2.4 → 1.3.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 +25 -0
- package/README.md +16 -4
- package/bin/claude-hooks +184 -2
- package/package.json +1 -1
- package/templates/check-version.sh +266 -0
- package/templates/pre-commit +27 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,31 @@ 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.3.0] - 2025-08-28
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- 🚀 Nuevo comando `claude-hooks update` para actualizar a la última versión disponible
|
|
12
|
+
- 🔄 Verificación automática de versión antes de cada commit con prompt interactivo
|
|
13
|
+
- 📜 Script compartido `check-version.sh` para evitar duplicación de código
|
|
14
|
+
- ✨ Prompt interactivo compatible con todas las consolas para aceptar actualizaciones
|
|
15
|
+
- 📊 Mensajes informativos detallados durante el proceso de verificación y actualización
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
- 🎯 El hook `pre-commit` ahora verifica automáticamente si hay actualizaciones disponibles
|
|
19
|
+
- 📦 La instalación ahora incluye el script `check-version.sh` en `.git/hooks/`
|
|
20
|
+
- 🔧 Mejorada la UX con mensajes claros sobre el estado de la versión
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
- 🐛 Corregido el parsing de versión desde NPM API (usaba endpoint incorrecto)
|
|
24
|
+
- 🔧 Mejorada la compatibilidad del prompt interactivo para consolas IntelliJ/WSL
|
|
25
|
+
- 📝 Múltiples métodos de fallback para leer input del usuario
|
|
26
|
+
|
|
27
|
+
### Technical
|
|
28
|
+
- 🏗️ Función `getLatestVersion()` ahora usa `dist-tags.latest` de NPM API
|
|
29
|
+
- 🔄 Función `checkVersionAndPromptUpdate()` reutilizable para verificación
|
|
30
|
+
- 📁 Script compartido para evitar duplicación de lógica de verificación
|
|
31
|
+
- 🎯 Fallback a `npm view` si la API de NPM falla
|
|
32
|
+
|
|
8
33
|
## [1.2.4] - 2025-08-22
|
|
9
34
|
|
|
10
35
|
### Fixed
|
package/README.md
CHANGED
|
@@ -93,11 +93,11 @@ Luego añade esto a tu `package.json`:
|
|
|
93
93
|
|
|
94
94
|
## 🤖 Características
|
|
95
95
|
|
|
96
|
-
**✨ Auto-actualización
|
|
96
|
+
**✨ Auto-actualización**: Verifica automáticamente si hay nuevas versiones disponibles antes de cada commit y ofrece actualizar con un simple prompt interactivo.
|
|
97
97
|
|
|
98
98
|
**Hooks disponibles**:
|
|
99
99
|
|
|
100
|
-
- `pre-commit`: Análisis de código con Claude (solo archivos Java/config)
|
|
100
|
+
- `pre-commit`: Análisis de código con Claude (solo archivos Java/config) con verificación automática de versión
|
|
101
101
|
- `prepare-commit-msg`: Generación automática de mensajes de commit
|
|
102
102
|
|
|
103
103
|
## 📁 Gestión de Archivos
|
|
@@ -172,7 +172,8 @@ Si no existe un `.gitignore`, se creará uno nuevo. Si ya existe, las entradas s
|
|
|
172
172
|
|
|
173
173
|
### Características adicionales
|
|
174
174
|
|
|
175
|
-
- **Auto-actualización**:
|
|
175
|
+
- **Auto-actualización**: Verificación automática de versiones antes de cada commit con prompt interactivo para actualizar
|
|
176
|
+
- **Comando update**: `claude-hooks update` para actualizar manualmente a la última versión
|
|
176
177
|
- **Modo debug**: `DEBUG=1 git commit` guarda respuestas en `debug-claude-response.json`
|
|
177
178
|
- **Configuración persistente**: Guarda preferencias en `.claude-analysis-mode`
|
|
178
179
|
- **Validación de dependencias**: Verifica que Claude CLI esté autenticado antes de ejecutar
|
|
@@ -273,7 +274,18 @@ Claude responde con un JSON que incluye:
|
|
|
273
274
|
- `recommendations`: Recomendaciones de mejora
|
|
274
275
|
- `blockingIssues`: Problemas que bloquean el commit
|
|
275
276
|
|
|
276
|
-
## 🔄
|
|
277
|
+
## 🔄 Actualización y Gestión
|
|
278
|
+
|
|
279
|
+
### Actualizar a la última versión
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
# Actualizar manualmente a la última versión
|
|
283
|
+
claude-hooks update
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
El comando `update` descarga e instala automáticamente la última versión disponible desde NPM, y luego reinstala los hooks con las nuevas características.
|
|
287
|
+
|
|
288
|
+
### Desactivar/Activar hooks
|
|
277
289
|
|
|
278
290
|
```bash
|
|
279
291
|
# Desactivar todos los hooks
|
package/bin/claude-hooks
CHANGED
|
@@ -7,6 +7,86 @@ const os = require('os');
|
|
|
7
7
|
const readline = require('readline');
|
|
8
8
|
const https = require('https');
|
|
9
9
|
|
|
10
|
+
// Función para obtener la última versión desde NPM
|
|
11
|
+
function getLatestVersion(packageName) {
|
|
12
|
+
return new Promise((resolve, reject) => {
|
|
13
|
+
// Usar la API principal de NPM, no /latest
|
|
14
|
+
https.get(`https://registry.npmjs.org/${packageName}`, (res) => {
|
|
15
|
+
let data = '';
|
|
16
|
+
res.on('data', chunk => data += chunk);
|
|
17
|
+
res.on('end', () => {
|
|
18
|
+
try {
|
|
19
|
+
const json = JSON.parse(data);
|
|
20
|
+
// Obtener la versión del tag 'latest'
|
|
21
|
+
if (json['dist-tags'] && json['dist-tags'].latest) {
|
|
22
|
+
resolve(json['dist-tags'].latest);
|
|
23
|
+
} else {
|
|
24
|
+
reject(new Error('No se pudo obtener la versión'));
|
|
25
|
+
}
|
|
26
|
+
} catch (e) {
|
|
27
|
+
// Si falla, intentar con npm view
|
|
28
|
+
try {
|
|
29
|
+
const version = execSync(`npm view ${packageName} version`, { encoding: 'utf8' }).trim();
|
|
30
|
+
resolve(version);
|
|
31
|
+
} catch (npmError) {
|
|
32
|
+
reject(e);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
}).on('error', reject);
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Función para verificar versión (usada por los hooks)
|
|
41
|
+
async function checkVersionAndPromptUpdate() {
|
|
42
|
+
try {
|
|
43
|
+
const currentVersion = require('../package.json').version;
|
|
44
|
+
const latestVersion = await getLatestVersion('claude-git-hooks');
|
|
45
|
+
|
|
46
|
+
if (currentVersion === latestVersion) {
|
|
47
|
+
return true; // Ya actualizado
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
console.log('');
|
|
51
|
+
warning(`Nueva versión disponible: ${latestVersion} (actual: ${currentVersion})`);
|
|
52
|
+
|
|
53
|
+
// Prompt interactivo compatible con todas las consolas
|
|
54
|
+
const rl = readline.createInterface({
|
|
55
|
+
input: process.stdin,
|
|
56
|
+
output: process.stdout
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
return new Promise((resolve) => {
|
|
60
|
+
rl.question('¿Deseas actualizar ahora? (s/n): ', (answer) => {
|
|
61
|
+
rl.close();
|
|
62
|
+
|
|
63
|
+
if (answer.toLowerCase() === 's' || answer.toLowerCase() === 'si' || answer.toLowerCase() === 'sí' || answer.toLowerCase() === 'yes' || answer.toLowerCase() === 'y') {
|
|
64
|
+
info('Actualizando claude-git-hooks...');
|
|
65
|
+
try {
|
|
66
|
+
execSync('npm install -g claude-git-hooks@latest', { stdio: 'inherit' });
|
|
67
|
+
success('Actualización completada. Por favor, vuelve a ejecutar tu comando.');
|
|
68
|
+
process.exit(0); // Salir para que el usuario reinicie el proceso
|
|
69
|
+
} catch (e) {
|
|
70
|
+
error('Error al actualizar: ' + e.message);
|
|
71
|
+
resolve(false);
|
|
72
|
+
}
|
|
73
|
+
} else {
|
|
74
|
+
info('Actualización pospuesta. Puedes actualizar más tarde con: claude-hooks update');
|
|
75
|
+
resolve(true); // Continuar sin actualizar
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
} catch (e) {
|
|
80
|
+
// Si hay error verificando la versión, continuar sin bloquear
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Exportar para uso en hooks
|
|
86
|
+
if (typeof module !== 'undefined' && module.exports) {
|
|
87
|
+
module.exports = { checkVersionAndPromptUpdate };
|
|
88
|
+
}
|
|
89
|
+
|
|
10
90
|
// Colores para output
|
|
11
91
|
const colors = {
|
|
12
92
|
reset: '\x1b[0m',
|
|
@@ -258,7 +338,13 @@ async function install(args) {
|
|
|
258
338
|
error('No estás en un repositorio Git. Por favor, ejecuta este comando desde la raíz de un repositorio.');
|
|
259
339
|
}
|
|
260
340
|
|
|
261
|
-
|
|
341
|
+
const isForce = args.includes('--force');
|
|
342
|
+
|
|
343
|
+
if (isForce) {
|
|
344
|
+
info('Instalando Claude Git Hooks (modo force)...');
|
|
345
|
+
} else {
|
|
346
|
+
info('Instalando Claude Git Hooks...');
|
|
347
|
+
}
|
|
262
348
|
|
|
263
349
|
// Solicitar contraseña sudo al inicio si es necesario
|
|
264
350
|
let sudoPassword = null;
|
|
@@ -308,6 +394,16 @@ async function install(args) {
|
|
|
308
394
|
success(`${hook} instalado`);
|
|
309
395
|
});
|
|
310
396
|
|
|
397
|
+
// Copiar script de verificación de versión
|
|
398
|
+
const checkVersionSource = path.join(templatesPath, 'check-version.sh');
|
|
399
|
+
const checkVersionDest = path.join(hooksPath, 'check-version.sh');
|
|
400
|
+
|
|
401
|
+
if (fs.existsSync(checkVersionSource)) {
|
|
402
|
+
fs.copyFileSync(checkVersionSource, checkVersionDest);
|
|
403
|
+
fs.chmodSync(checkVersionDest, '755');
|
|
404
|
+
success('Script de verificación de versión instalado');
|
|
405
|
+
}
|
|
406
|
+
|
|
311
407
|
// Crear directorio .claude si no existe
|
|
312
408
|
const claudeDir = '.claude';
|
|
313
409
|
if (!fs.existsSync(claudeDir)) {
|
|
@@ -420,7 +516,7 @@ async function checkAndInstallDependencies(sudoPassword = null) {
|
|
|
420
516
|
if (missingTools.length === 0) {
|
|
421
517
|
success('Herramientas Unix estándar verificadas');
|
|
422
518
|
} else {
|
|
423
|
-
error(`Faltan herramientas Unix estándar: ${missingTools.join(', ')}`);
|
|
519
|
+
error(`Faltan herramientas Unix estándar: ${missingTools.join(', ')}. Reintenta instalación en una consola Ubuntu`);
|
|
424
520
|
}
|
|
425
521
|
|
|
426
522
|
// Verificar e instalar Claude CLI
|
|
@@ -785,6 +881,87 @@ function setMode(mode) {
|
|
|
785
881
|
}
|
|
786
882
|
}
|
|
787
883
|
|
|
884
|
+
// Función para comparar versiones usando el script compartido
|
|
885
|
+
function compareVersions(v1, v2) {
|
|
886
|
+
try {
|
|
887
|
+
// Usar el script compartido para mantener consistencia
|
|
888
|
+
const result = execSync(`bash -c 'source "${getTemplatesPath()}/check-version.sh" && compare_versions "${v1}" "${v2}"; echo $?'`, { encoding: 'utf8' }).trim();
|
|
889
|
+
const exitCode = parseInt(result);
|
|
890
|
+
|
|
891
|
+
// Convertir los códigos de retorno del script bash a valores JS
|
|
892
|
+
if (exitCode === 0) return 0; // iguales
|
|
893
|
+
if (exitCode === 1) return 1; // v1 > v2
|
|
894
|
+
if (exitCode === 2) return -1; // v1 < v2
|
|
895
|
+
|
|
896
|
+
// Fallback: comparación simple si el script falla
|
|
897
|
+
if (v1 === v2) return 0;
|
|
898
|
+
const sorted = [v1, v2].sort((a, b) => {
|
|
899
|
+
const aParts = a.split('.').map(Number);
|
|
900
|
+
const bParts = b.split('.').map(Number);
|
|
901
|
+
for (let i = 0; i < Math.max(aParts.length, bParts.length); i++) {
|
|
902
|
+
const aPart = aParts[i] || 0;
|
|
903
|
+
const bPart = bParts[i] || 0;
|
|
904
|
+
if (aPart !== bPart) return aPart - bPart;
|
|
905
|
+
}
|
|
906
|
+
return 0;
|
|
907
|
+
});
|
|
908
|
+
return v1 === sorted[1] ? 1 : -1;
|
|
909
|
+
} catch (e) {
|
|
910
|
+
// Si falla todo, usar comparación simple
|
|
911
|
+
if (v1 === v2) return 0;
|
|
912
|
+
return v1 > v2 ? 1 : -1;
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
// Comando update - actualizar a la última versión
|
|
917
|
+
async function update() {
|
|
918
|
+
info('Verificando última versión disponible...');
|
|
919
|
+
|
|
920
|
+
try {
|
|
921
|
+
const currentVersion = require('../package.json').version;
|
|
922
|
+
const latestVersion = await getLatestVersion('claude-git-hooks');
|
|
923
|
+
|
|
924
|
+
const comparison = compareVersions(currentVersion, latestVersion);
|
|
925
|
+
|
|
926
|
+
if (comparison === 0) {
|
|
927
|
+
success(`Ya tienes la última versión instalada (${currentVersion})`);
|
|
928
|
+
return;
|
|
929
|
+
} else if (comparison > 0) {
|
|
930
|
+
info(`Estás usando una versión de desarrollo (${currentVersion})`);
|
|
931
|
+
info(`Última versión publicada: ${latestVersion}`);
|
|
932
|
+
success(`Ya tienes la última versión instalada (${currentVersion})`);
|
|
933
|
+
return;
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
info(`Versión actual: ${currentVersion}`);
|
|
937
|
+
info(`Versión disponible: ${latestVersion}`);
|
|
938
|
+
|
|
939
|
+
// Actualizar el paquete
|
|
940
|
+
info('Actualizando claude-git-hooks...');
|
|
941
|
+
try {
|
|
942
|
+
execSync('npm install -g claude-git-hooks@latest', { stdio: 'inherit' });
|
|
943
|
+
success(`Actualizado exitosamente a la versión ${latestVersion}`);
|
|
944
|
+
|
|
945
|
+
// Reinstalar hooks con la nueva versión
|
|
946
|
+
info('Reinstalando hooks con la nueva versión...');
|
|
947
|
+
await install(['--force']);
|
|
948
|
+
|
|
949
|
+
} catch (updateError) {
|
|
950
|
+
error('Error al actualizar. Intenta ejecutar: npm install -g claude-git-hooks@latest');
|
|
951
|
+
}
|
|
952
|
+
} catch (e) {
|
|
953
|
+
warning('No se pudo verificar la última versión disponible');
|
|
954
|
+
warning('Intentando actualizar de todas formas...');
|
|
955
|
+
try {
|
|
956
|
+
execSync('npm install -g claude-git-hooks@latest', { stdio: 'inherit' });
|
|
957
|
+
success('Actualización completada');
|
|
958
|
+
await install(['--force']);
|
|
959
|
+
} catch (updateError) {
|
|
960
|
+
error('Error al actualizar: ' + updateError.message);
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
|
|
788
965
|
// Comando help
|
|
789
966
|
function showHelp() {
|
|
790
967
|
console.log(`
|
|
@@ -794,6 +971,7 @@ Uso: claude-hooks <comando> [opciones]
|
|
|
794
971
|
|
|
795
972
|
Comandos:
|
|
796
973
|
install Instala los hooks en el repositorio actual
|
|
974
|
+
update Actualiza a la última versión disponible
|
|
797
975
|
uninstall Desinstala los hooks del repositorio
|
|
798
976
|
enable [hook] Habilita hooks (todos o uno específico)
|
|
799
977
|
disable [hook] Deshabilita hooks (todos o uno específico)
|
|
@@ -807,6 +985,7 @@ Hooks disponibles:
|
|
|
807
985
|
|
|
808
986
|
Ejemplos:
|
|
809
987
|
claude-hooks install # Instala todos los hooks
|
|
988
|
+
claude-hooks update # Actualiza a la última versión
|
|
810
989
|
claude-hooks set-mode sonar # Cambiar a modo SonarQube
|
|
811
990
|
claude-hooks set-mode standard # Cambiar a modo estándar
|
|
812
991
|
claude-hooks disable pre-commit # Deshabilita solo pre-commit
|
|
@@ -826,6 +1005,9 @@ async function main() {
|
|
|
826
1005
|
case 'install':
|
|
827
1006
|
await install(args.slice(1));
|
|
828
1007
|
break;
|
|
1008
|
+
case 'update':
|
|
1009
|
+
await update();
|
|
1010
|
+
break;
|
|
829
1011
|
case 'uninstall':
|
|
830
1012
|
uninstall();
|
|
831
1013
|
break;
|
package/package.json
CHANGED
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Script compartido para verificar versión de claude-git-hooks
|
|
4
|
+
# Este script puede ser invocado desde cualquier hook
|
|
5
|
+
|
|
6
|
+
# Colores para output
|
|
7
|
+
RED='\033[0;31m'
|
|
8
|
+
GREEN='\033[0;32m'
|
|
9
|
+
YELLOW='\033[1;33m'
|
|
10
|
+
BLUE='\033[0;34m'
|
|
11
|
+
NC='\033[0m' # No Color
|
|
12
|
+
|
|
13
|
+
# Función para logging
|
|
14
|
+
log() {
|
|
15
|
+
echo -e "${GREEN}[VERSION-CHECK]${NC} $1"
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
error() {
|
|
19
|
+
echo -e "${RED}[ERROR]${NC} $1"
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
warning() {
|
|
23
|
+
echo -e "${YELLOW}[WARNING]${NC} $1"
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
info() {
|
|
27
|
+
echo -e "${BLUE}[INFO]${NC} $1"
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
# Función compartida para comparar versiones semánticas
|
|
31
|
+
# Retorna: 1 si v1 > v2, 2 si v1 < v2, 0 si son iguales
|
|
32
|
+
compare_versions() {
|
|
33
|
+
local v1="$1"
|
|
34
|
+
local v2="$2"
|
|
35
|
+
|
|
36
|
+
if [ -n "$DEBUG_VERSION" ]; then
|
|
37
|
+
echo "[DEBUG] compare_versions: comparando '$v1' con '$v2'"
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
# Si son exactamente iguales
|
|
41
|
+
if [ "$v1" = "$v2" ]; then
|
|
42
|
+
if [ -n "$DEBUG_VERSION" ]; then
|
|
43
|
+
echo "[DEBUG] compare_versions: versiones iguales, retornando 0"
|
|
44
|
+
fi
|
|
45
|
+
return 0
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
# Usar sort -V que entiende versiones semánticas correctamente
|
|
49
|
+
local sorted=$(printf "%s\n%s" "$v1" "$v2" | sort -V)
|
|
50
|
+
local smaller=$(echo "$sorted" | head -1)
|
|
51
|
+
local larger=$(echo "$sorted" | tail -1)
|
|
52
|
+
|
|
53
|
+
if [ -n "$DEBUG_VERSION" ]; then
|
|
54
|
+
echo "[DEBUG] compare_versions: sorted='$sorted', smaller='$smaller', larger='$larger'"
|
|
55
|
+
fi
|
|
56
|
+
|
|
57
|
+
if [ "$v1" = "$larger" ]; then
|
|
58
|
+
if [ -n "$DEBUG_VERSION" ]; then
|
|
59
|
+
echo "[DEBUG] compare_versions: v1 es mayor, retornando 1"
|
|
60
|
+
fi
|
|
61
|
+
return 1 # v1 es mayor que v2
|
|
62
|
+
else
|
|
63
|
+
if [ -n "$DEBUG_VERSION" ]; then
|
|
64
|
+
echo "[DEBUG] compare_versions: v1 es menor, retornando 2"
|
|
65
|
+
fi
|
|
66
|
+
return 2 # v1 es menor que v2 (cambié de 255 a 2 para evitar problemas con set -e)
|
|
67
|
+
fi
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
# Función principal de verificación
|
|
71
|
+
check_version() {
|
|
72
|
+
# Debug mode si está activado
|
|
73
|
+
if [ -n "$DEBUG_VERSION" ]; then
|
|
74
|
+
echo "[DEBUG] Iniciando verificación de versión..."
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
info "Verificando versión instalada..."
|
|
78
|
+
|
|
79
|
+
# Intentar obtener versión actual desde package.json global
|
|
80
|
+
CURRENT_VERSION=""
|
|
81
|
+
NPM_PREFIX=$(npm prefix -g 2>/dev/null || echo "/usr/local")
|
|
82
|
+
PACKAGE_JSON_PATHS=(
|
|
83
|
+
"$NPM_PREFIX/lib/node_modules/claude-git-hooks/package.json"
|
|
84
|
+
"/usr/lib/node_modules/claude-git-hooks/package.json"
|
|
85
|
+
"/usr/local/lib/node_modules/claude-git-hooks/package.json"
|
|
86
|
+
"$HOME/.npm-global/lib/node_modules/claude-git-hooks/package.json"
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
for path in "${PACKAGE_JSON_PATHS[@]}"; do
|
|
90
|
+
if [ -f "$path" ]; then
|
|
91
|
+
CURRENT_VERSION=$(grep '"version"' "$path" 2>/dev/null | sed 's/.*"version".*"\(.*\)".*/\1/')
|
|
92
|
+
break
|
|
93
|
+
fi
|
|
94
|
+
done
|
|
95
|
+
|
|
96
|
+
if [ -z "$CURRENT_VERSION" ]; then
|
|
97
|
+
warning "No se pudo determinar la versión actual"
|
|
98
|
+
return 0 # Continuar sin bloquear
|
|
99
|
+
fi
|
|
100
|
+
|
|
101
|
+
if [ -n "$DEBUG_VERSION" ]; then
|
|
102
|
+
echo "[DEBUG] Versión actual encontrada: $CURRENT_VERSION"
|
|
103
|
+
fi
|
|
104
|
+
|
|
105
|
+
# Obtener última versión desde NPM (usando npm view que es más confiable)
|
|
106
|
+
info "Verificando última versión disponible..."
|
|
107
|
+
|
|
108
|
+
# Método principal: usar npm view que es más confiable
|
|
109
|
+
if [ -n "$DEBUG_VERSION" ]; then
|
|
110
|
+
echo "[DEBUG] Ejecutando: npm view claude-git-hooks version"
|
|
111
|
+
fi
|
|
112
|
+
|
|
113
|
+
LATEST_VERSION=$(npm view claude-git-hooks version 2>/dev/null || echo "")
|
|
114
|
+
|
|
115
|
+
if [ -n "$DEBUG_VERSION" ]; then
|
|
116
|
+
echo "[DEBUG] npm view retornó: '$LATEST_VERSION'"
|
|
117
|
+
echo "[DEBUG] Longitud de LATEST_VERSION: ${#LATEST_VERSION}"
|
|
118
|
+
fi
|
|
119
|
+
|
|
120
|
+
# Si npm view falla, intentar con la API de NPM
|
|
121
|
+
if [ -z "$LATEST_VERSION" ]; then
|
|
122
|
+
# Obtener el JSON completo y extraer dist-tags.latest con jq si está disponible
|
|
123
|
+
if command -v jq &> /dev/null; then
|
|
124
|
+
LATEST_VERSION=$(curl -s https://registry.npmjs.org/claude-git-hooks 2>/dev/null | jq -r '."dist-tags".latest' 2>/dev/null || echo "")
|
|
125
|
+
if [ -n "$DEBUG_VERSION" ]; then
|
|
126
|
+
echo "[DEBUG] jq parsing retornó: '$LATEST_VERSION'"
|
|
127
|
+
fi
|
|
128
|
+
else
|
|
129
|
+
# Sin jq, usar método más robusto con sed
|
|
130
|
+
LATEST_VERSION=$(curl -s https://registry.npmjs.org/claude-git-hooks 2>/dev/null | sed -n 's/.*"dist-tags":{[^}]*"latest":"\([^"]*\)".*/\1/p' | head -1)
|
|
131
|
+
if [ -n "$DEBUG_VERSION" ]; then
|
|
132
|
+
echo "[DEBUG] sed parsing retornó: '$LATEST_VERSION'"
|
|
133
|
+
fi
|
|
134
|
+
fi
|
|
135
|
+
fi
|
|
136
|
+
|
|
137
|
+
# Validar que lo obtenido parece una versión (formato X.Y.Z)
|
|
138
|
+
if [ -n "$DEBUG_VERSION" ]; then
|
|
139
|
+
echo "[DEBUG] Validando versión: '$LATEST_VERSION'"
|
|
140
|
+
fi
|
|
141
|
+
|
|
142
|
+
if ! echo "$LATEST_VERSION" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+' ; then
|
|
143
|
+
if [ -n "$DEBUG_VERSION" ]; then
|
|
144
|
+
echo "[DEBUG] Versión obtenida no es válida: '$LATEST_VERSION'"
|
|
145
|
+
fi
|
|
146
|
+
warning "No se pudo obtener una versión válida del registro NPM"
|
|
147
|
+
return 0
|
|
148
|
+
fi
|
|
149
|
+
|
|
150
|
+
if [ -n "$DEBUG_VERSION" ]; then
|
|
151
|
+
echo "[DEBUG] Versión válida confirmada: '$LATEST_VERSION'"
|
|
152
|
+
fi
|
|
153
|
+
|
|
154
|
+
if [ -z "$LATEST_VERSION" ]; then
|
|
155
|
+
# Si no se puede obtener la versión, continuar sin bloquear
|
|
156
|
+
return 0
|
|
157
|
+
fi
|
|
158
|
+
|
|
159
|
+
if [ "$CURRENT_VERSION" = "$LATEST_VERSION" ]; then
|
|
160
|
+
log "Versión actual ($CURRENT_VERSION) está actualizada ✓"
|
|
161
|
+
return 0
|
|
162
|
+
fi
|
|
163
|
+
|
|
164
|
+
# Comparar versiones usando la función compartida
|
|
165
|
+
if [ -n "$DEBUG_VERSION" ]; then
|
|
166
|
+
echo "[DEBUG] Comparando versiones: '$CURRENT_VERSION' vs '$LATEST_VERSION'"
|
|
167
|
+
fi
|
|
168
|
+
|
|
169
|
+
# Deshabilitar set -e temporalmente para capturar el código de retorno
|
|
170
|
+
set +e
|
|
171
|
+
compare_versions "$CURRENT_VERSION" "$LATEST_VERSION"
|
|
172
|
+
comparison_result=$?
|
|
173
|
+
set -e
|
|
174
|
+
|
|
175
|
+
if [ -n "$DEBUG_VERSION" ]; then
|
|
176
|
+
echo "[DEBUG] Resultado de comparación: $comparison_result"
|
|
177
|
+
fi
|
|
178
|
+
|
|
179
|
+
if [ $comparison_result -eq 0 ]; then
|
|
180
|
+
# Las versiones son iguales
|
|
181
|
+
if [ -n "$DEBUG_VERSION" ]; then
|
|
182
|
+
echo "[DEBUG] Las versiones son iguales"
|
|
183
|
+
fi
|
|
184
|
+
log "Versión actual ($CURRENT_VERSION) está actualizada ✓"
|
|
185
|
+
return 0
|
|
186
|
+
elif [ $comparison_result -eq 1 ]; then
|
|
187
|
+
# La versión actual es mayor que la publicada (desarrollo local)
|
|
188
|
+
if [ -n "$DEBUG_VERSION" ]; then
|
|
189
|
+
echo "[DEBUG] Versión local ($CURRENT_VERSION) es más nueva que la publicada ($LATEST_VERSION)"
|
|
190
|
+
fi
|
|
191
|
+
log "Versión de desarrollo ($CURRENT_VERSION) > versión publicada ($LATEST_VERSION) ✓"
|
|
192
|
+
return 0
|
|
193
|
+
elif [ $comparison_result -eq 2 ]; then
|
|
194
|
+
# La versión publicada es mayor, continuar con prompt de actualización
|
|
195
|
+
if [ -n "$DEBUG_VERSION" ]; then
|
|
196
|
+
echo "[DEBUG] La versión publicada ($LATEST_VERSION) es más nueva que la local ($CURRENT_VERSION)"
|
|
197
|
+
fi
|
|
198
|
+
# Continuar con el prompt de actualización (no return aquí)
|
|
199
|
+
fi
|
|
200
|
+
|
|
201
|
+
if [ -n "$DEBUG_VERSION" ]; then
|
|
202
|
+
echo "[DEBUG] La versión publicada es más nueva, procediendo con prompt de actualización"
|
|
203
|
+
fi
|
|
204
|
+
|
|
205
|
+
# Solo mostrar actualización si la versión publicada es realmente más nueva
|
|
206
|
+
echo
|
|
207
|
+
warning "Nueva versión disponible: $LATEST_VERSION (actual: $CURRENT_VERSION)"
|
|
208
|
+
echo -e "${YELLOW}╭─────────────────────────────────────────────╮${NC}"
|
|
209
|
+
echo -e "${YELLOW}│${NC} Una nueva versión de claude-git-hooks está ${YELLOW}│${NC}"
|
|
210
|
+
echo -e "${YELLOW}│${NC} disponible con mejoras y correcciones ${YELLOW}│${NC}"
|
|
211
|
+
echo -e "${YELLOW}╰─────────────────────────────────────────────╯${NC}"
|
|
212
|
+
echo
|
|
213
|
+
|
|
214
|
+
# Leer respuesta del usuario de forma compatible con todas las consolas
|
|
215
|
+
echo -n "¿Deseas actualizar ahora? (s/n): "
|
|
216
|
+
|
|
217
|
+
# Intentar varios métodos de lectura para máxima compatibilidad
|
|
218
|
+
REPLY=""
|
|
219
|
+
|
|
220
|
+
# Método 1: Leer desde /dev/tty si existe
|
|
221
|
+
if [ -c /dev/tty ]; then
|
|
222
|
+
read -r REPLY </dev/tty 2>/dev/null || REPLY=""
|
|
223
|
+
fi
|
|
224
|
+
|
|
225
|
+
# Método 2: Si falla, intentar leer desde stdin estándar
|
|
226
|
+
if [ -z "$REPLY" ]; then
|
|
227
|
+
read -r REPLY 2>/dev/null || REPLY=""
|
|
228
|
+
fi
|
|
229
|
+
|
|
230
|
+
# Método 3: Si aún no tenemos respuesta, usar bash -c
|
|
231
|
+
if [ -z "$REPLY" ]; then
|
|
232
|
+
REPLY=$(bash -c 'read -r reply && echo "$reply"' 2>/dev/null || echo "")
|
|
233
|
+
fi
|
|
234
|
+
|
|
235
|
+
# Si ningún método funcionó, informar y continuar
|
|
236
|
+
if [ -z "$REPLY" ]; then
|
|
237
|
+
echo
|
|
238
|
+
info "No se pudo leer la respuesta. Continuando sin actualizar."
|
|
239
|
+
info "Para actualizar manualmente, ejecuta: claude-hooks update"
|
|
240
|
+
return 0
|
|
241
|
+
fi
|
|
242
|
+
|
|
243
|
+
if [ "$REPLY" = "s" ] || [ "$REPLY" = "S" ] || [ "$REPLY" = "si" ] || [ "$REPLY" = "SI" ] || [ "$REPLY" = "sí" ] || [ "$REPLY" = "SÍ" ] || [ "$REPLY" = "y" ] || [ "$REPLY" = "Y" ] || [ "$REPLY" = "yes" ] || [ "$REPLY" = "YES" ]; then
|
|
244
|
+
echo
|
|
245
|
+
info "Actualizando claude-git-hooks..."
|
|
246
|
+
|
|
247
|
+
if npm install -g claude-git-hooks@latest; then
|
|
248
|
+
echo
|
|
249
|
+
log "✅ Actualización completada exitosamente"
|
|
250
|
+
info "Por favor, vuelve a ejecutar tu comando git commit"
|
|
251
|
+
exit 0 # Salir para que el usuario reinicie con la nueva versión
|
|
252
|
+
else
|
|
253
|
+
error "Error al actualizar. Intenta manualmente con: npm install -g claude-git-hooks@latest"
|
|
254
|
+
return 1
|
|
255
|
+
fi
|
|
256
|
+
else
|
|
257
|
+
info "Actualización pospuesta. Puedes actualizar más tarde con: claude-hooks update"
|
|
258
|
+
echo
|
|
259
|
+
return 0
|
|
260
|
+
fi
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
# Si se ejecuta directamente (no como source), ejecutar la verificación
|
|
264
|
+
if [ "${BASH_SOURCE[0]}" = "${0}" ]; then
|
|
265
|
+
check_version
|
|
266
|
+
fi
|
package/templates/pre-commit
CHANGED
|
@@ -14,6 +14,7 @@ MAX_FILE_SIZE=100000 # 100KB máximo por archivo
|
|
|
14
14
|
RED='\033[0;31m'
|
|
15
15
|
GREEN='\033[0;32m'
|
|
16
16
|
YELLOW='\033[1;33m'
|
|
17
|
+
BLUE='\033[0;34m'
|
|
17
18
|
NC='\033[0m' # No Color
|
|
18
19
|
|
|
19
20
|
# Función para logging
|
|
@@ -29,6 +30,32 @@ warning() {
|
|
|
29
30
|
echo -e "${YELLOW}[WARNING]${NC} $1"
|
|
30
31
|
}
|
|
31
32
|
|
|
33
|
+
# Verificar versión al inicio (antes de cualquier análisis)
|
|
34
|
+
# Intentar encontrar el script check-version.sh
|
|
35
|
+
CHECK_VERSION_SCRIPT=""
|
|
36
|
+
# Buscar en múltiples ubicaciones posibles
|
|
37
|
+
SCRIPT_PATHS=(
|
|
38
|
+
"$(dirname "$0")/check-version.sh"
|
|
39
|
+
"/usr/local/lib/node_modules/claude-git-hooks/templates/check-version.sh"
|
|
40
|
+
"/usr/lib/node_modules/claude-git-hooks/templates/check-version.sh"
|
|
41
|
+
"$HOME/.npm-global/lib/node_modules/claude-git-hooks/templates/check-version.sh"
|
|
42
|
+
"$(npm prefix -g 2>/dev/null)/lib/node_modules/claude-git-hooks/templates/check-version.sh"
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
for path in "${SCRIPT_PATHS[@]}"; do
|
|
46
|
+
if [ -f "$path" ]; then
|
|
47
|
+
CHECK_VERSION_SCRIPT="$path"
|
|
48
|
+
break
|
|
49
|
+
fi
|
|
50
|
+
done
|
|
51
|
+
|
|
52
|
+
# Si encontramos el script, ejecutarlo
|
|
53
|
+
if [ -n "$CHECK_VERSION_SCRIPT" ]; then
|
|
54
|
+
# Source el script para tener acceso a la función
|
|
55
|
+
source "$CHECK_VERSION_SCRIPT"
|
|
56
|
+
check_version
|
|
57
|
+
fi
|
|
58
|
+
|
|
32
59
|
# Detectar qué archivo de pautas usar
|
|
33
60
|
# Prioridad: variable de entorno > archivo > pregunta interactiva
|
|
34
61
|
if [ -n "$CLAUDE_ANALYSIS_MODE" ]; then
|