claude-git-hooks 2.3.0 → 2.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,125 @@ 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.4.0] - 2025-11-17
9
+
10
+ ### ⚠️ BREAKING CHANGES
11
+
12
+ - **Debug Mode** - Environment variable `DEBUG` no longer supported
13
+ - **What changed**: Removed `DEBUG` environment variable support from `lib/utils/logger.js`
14
+ - **Why**: Aligns with project philosophy "no environment variables" and provides better user experience
15
+ - **Migration**: Use `claude-hooks --debug true` instead of `DEBUG=1 git commit`
16
+ - **Alternative**: Set `"system": { "debug": true }` in `.claude/config.json`
17
+
18
+ ### 🔄 Changed
19
+
20
+ - **File Size Limit Increased** - Default `maxFileSize` increased from 100KB to 1MB
21
+ - **What changed**: `analysis.maxFileSize` now defaults to 1000000 (1MB) instead of 100000 (100KB)
22
+ - **Why**: Previous 100KB limit was too restrictive, rejected many legitimate source files
23
+ - **Files updated**:
24
+ - `lib/config.js:29` - Default configuration
25
+ - All preset configs in `templates/presets/*/config.json`
26
+ - `templates/config.example.json`
27
+ - **Impact**: More files will be analyzed without manual config adjustment
28
+ - **User action**: If you want stricter limits, set `"maxFileSize": 100000` in `.claude/config.json`
29
+
30
+ ### ✨ Added
31
+
32
+ - **Debug CLI Command** - New `--debug` flag for managing debug mode
33
+ - **Usage**: `claude-hooks --debug <true|false|status>`
34
+ - **Purpose**: Enables detailed logging for troubleshooting
35
+ - **Implementation**: Generic `updateConfig()` function in `bin/claude-hooks:1262`
36
+ - **Benefits**: Consistent with `--set-preset` pattern, no need to remember env var syntax
37
+
38
+ - **Generic Config Updater** - Reusable `updateConfig()` function
39
+ - **Purpose**: Centralized config update logic for all CLI commands
40
+ - **Location**: `bin/claude-hooks:1262`
41
+ - **Features**: Dot notation path support, custom validators, custom success messages
42
+ - **Extensibility**: Easy to add new config commands (`--set-max-files`, `--set-timeout`, etc.)
43
+
44
+ ### 🔄 Changed
45
+
46
+ - **setPreset() Refactored** - Now uses generic `updateConfig()` function
47
+ - **Effect**: Less code duplication, consistent error handling
48
+ - **Location**: `bin/claude-hooks:1349`
49
+
50
+ - **Debug Mode Activation** - Hooks now enable debug from config
51
+ - **Files**: `lib/hooks/pre-commit.js:185`, `lib/hooks/prepare-commit-msg.js:124`
52
+ - **Effect**: Debug logs appear when `config.system.debug` is true
53
+
54
+ ### 📚 Documentation
55
+
56
+ - **Help Text Updated** - Added `--debug` command documentation
57
+ - **Location**: `bin/claude-hooks:1170`
58
+ - **Includes**: Command description, examples, debug mode section
59
+
60
+ - **README.md Updated** - Debug command documented in multiple sections
61
+ - **Cheatsheet**: Added debug commands to "Comandos Frecuentes" (line 52-56)
62
+ - **Tips**: Updated tip #4 with CLI command (line 269)
63
+ - **Features**: Updated debug mode description (line 492)
64
+
65
+ ## [2.3.1] - 2025-11-13
66
+
67
+ ### 🔄 Changed
68
+
69
+ - **Configuration Priority** - Updated merge order: `defaults < user config < preset config`
70
+ - **Rationale**: User sets general preferences in `.claude/config.json`, preset provides tech-stack-specific overrides (highest priority)
71
+ - **Effect**: Presets now correctly override user settings (e.g., preset's `model: sonnet` wins over user's `model: haiku`)
72
+ - **Files updated**: `lib/config.js:116` (merge logic), README.md:222 (documentation)
73
+
74
+ ### ✨ Added
75
+
76
+ - **Installation Diagnostics Utility** - New `lib/utils/installation-diagnostics.js`
77
+ - **Purpose**: Reusable error diagnostics with actionable remediation steps
78
+ - **Exports**: `formatError()`, `getInstallationDiagnostics()`, `isInstallationHealthy()`
79
+ - **Use case**: Detects installation in wrong directory (common cause of "presets not found" errors)
80
+ - **Extensible**: Documented future enhancements (file permissions, Claude CLI check, etc.)
81
+
82
+ - **Enhanced Error Messages** - Better guidance when installation fails
83
+ - **Presets not found** (`lib/utils/preset-loader.js:194`): Shows current vs repo root directory
84
+ - **Hook scripts missing** (`templates/pre-commit:76`, `templates/prepare-commit-msg:76`): Early `.claude/` check with remediation steps
85
+ - **npm package issues**: Suggests verifying `npm list -g claude-git-hooks`
86
+
87
+ - **Bash Wrapper Early Validation** - Hooks now check `.claude/` exists before attempting execution
88
+ - **Why**: Fails fast with helpful message if installation incomplete or performed from wrong directory
89
+ - **Effect**: Users immediately know to `cd` to repo root and reinstall
90
+
91
+ - **Claude Error Diagnostics** - New `lib/utils/claude-diagnostics.js`
92
+ - **Purpose**: Detects and formats Claude CLI errors with actionable solutions
93
+ - **Error types**: Rate limit, authentication, network, invalid response, generic
94
+ - **Exports**: `detectClaudeError()`, `formatClaudeError()`, `ClaudeErrorType`, `isRecoverableError()`
95
+ - **Integration**: `lib/utils/claude-client.js:147` automatically detects and formats errors
96
+ - **Effect**: Users see clear guidance (e.g., "Rate limit resets in 2 hours, switch to haiku model")
97
+
98
+ ### 📚 Documentation
99
+
100
+ - **CUSTOMIZATION_GUIDE.md** - Comprehensive preset creation guide in `/templates`
101
+ - Visual flowchart showing prompt assembly (8-step diagram)
102
+ - Step-by-step preset creation tutorial
103
+ - Placeholder system reference with examples
104
+ - Preset kickstart prompt for Claude-assisted generation
105
+ - **Burst limit warning**: Explains why git hooks hit rate limits when manual CLI doesn't
106
+ - Referenced in README.md:333 for discoverability
107
+
108
+ - **Utility Modules Reference** - New section in README.md:596
109
+ - Table of all `lib/utils/` modules with purpose and key exports
110
+ - Usage examples for other Claude instances
111
+ - Promotes code reuse across projects
112
+
113
+ - **README-NPM.md** - Complete rewrite for npm package page
114
+ - **Length**: 266 lines (up from 145 lines, but more focused)
115
+ - **Updated**: v2.3.0 presets, v2.2.0 config centralization, v2.0.0 cross-platform
116
+ - **Added**: Configuration priority explanation, troubleshooting, "What's New" section
117
+ - **Removed**: Outdated v1.x references, environment variable examples
118
+
119
+ ### 🎯 User Experience
120
+
121
+ - **Clearer error context**: Errors now show current directory vs repository root
122
+ - **Actionable solutions**: Every error includes specific commands to fix the issue
123
+ - **Installation verification**: Early checks prevent confusing downstream errors
124
+ - **Better documentation**: Users can find utility functions and customization guides easily
125
+ - **Claude error clarity**: Rate limits, auth failures, and network errors now show specific remediation steps
126
+
8
127
  ## [2.3.0] - 2025-11-11
9
128
 
10
129
  ### ✨ Added
package/README.md CHANGED
@@ -48,6 +48,12 @@ claude-hooks --set-preset <name>
48
48
 
49
49
  # Mostrar preset actual
50
50
  claude-hooks preset current
51
+
52
+ # Activar modo debug
53
+ claude-hooks --debug true
54
+
55
+ # Ver estado de debug
56
+ claude-hooks --debug status
51
57
  ```
52
58
 
53
59
  ### 📦 Instalación y Gestión
@@ -127,7 +133,7 @@ cat > .claude/config.json << 'EOF'
127
133
  {
128
134
  "preset": "backend",
129
135
  "analysis": {
130
- "maxFileSize": 150000,
136
+ "maxFileSize": 1000000,
131
137
  "maxFiles": 12,
132
138
  "timeout": 150000
133
139
  },
@@ -224,11 +230,13 @@ EOF
224
230
  ```
225
231
  defaults (lib/config.js)
226
232
 
227
- preset config (templates/presets/backend/config.json)
233
+ user config (.claude/config.json) ← General preferences
228
234
 
229
- user config (.claude/config.json) ← MÁXIMA PRIORIDAD
235
+ preset config (.claude/presets/{name}/config.json) ← MÁXIMA PRIORIDAD (tech-stack specific)
230
236
  ```
231
237
 
238
+ **Rationale**: User sets general preferences, preset provides tech-stack-specific overrides.
239
+
232
240
  **Nota v2.2.0+:** Variables de entorno ya NO son soportadas. Usar `.claude/config.json` en su lugar.
233
241
 
234
242
  ### 🎯 Casos de Uso Específicos
@@ -258,9 +266,9 @@ git commit -m "fix: resolver issues"
258
266
  1. **Mensaje automático**: Usa `"auto"` como mensaje para que Claude lo genere
259
267
  2. **Skip auth**: Usa `--skip-auth` en CI/CD o desarrollo local
260
268
  3. **Force install**: Usa `--force` para reinstalar sin confirmación
261
- 4. **Debug**: Activa en `.claude/config.json`: `{"system": {"debug": true}}`
262
- 5. **Archivos grandes**: Se omiten automáticamente archivos > 100KB
263
- 6. **Límite de archivos**: Máximo 10 archivos por commit (configurable)
269
+ 4. **Debug**: Activa con `claude-hooks --debug true` o en `.claude/config.json`: `{"system": {"debug": true}}`
270
+ 5. **Archivos grandes**: Se omiten automáticamente archivos > 1MB
271
+ 6. **Límite de archivos**: Máximo 30 archivos por commit (configurable)
264
272
 
265
273
  ### 🚀 Parallel Analysis (v2.2.0+)
266
274
 
@@ -324,6 +332,16 @@ git commit -m "fix: resolver issues"
324
332
  - `.claude/CLAUDE_PRE_COMMIT_SONAR.md` - Criterios (backend/frontend/data/db)
325
333
  - `.claude/CLAUDE_ANALYSIS_PROMPT_SONAR.md` - Template del prompt
326
334
 
335
+ **Crear o modificar presets personalizados:**
336
+
337
+ ```bash
338
+ # Ver guía completa de customización
339
+ cat templates/CUSTOMIZATION_GUIDE.md
340
+
341
+ # O en GitHub
342
+ # https://github.com/pablorovito/claude-git-hooks/blob/main/templates/CUSTOMIZATION_GUIDE.md
343
+ ```
344
+
327
345
  **Ejemplo:**
328
346
 
329
347
  ```bash
@@ -423,8 +441,8 @@ Si no existe un `.gitignore`, se creará uno nuevo. Si ya existe, las entradas s
423
441
  1. **Intercepta cada intento de commit**
424
442
  2. **Extrae y filtra archivos modificados**:
425
443
  - Solo analiza: Java, XML, properties, yml, yaml
426
- - Omite archivos mayores a 100KB
427
- - Límite de 10 archivos por commit
444
+ - Omite archivos mayores a 1MB
445
+ - Límite de 30 archivos por commit
428
446
  3. **Construye prompt inteligente**:
429
447
  - Usa template de prompt desde `.claude/CLAUDE_ANALYSIS_PROMPT*.md`
430
448
  - Lee las pautas desde `.claude/CLAUDE_PRE_COMMIT*.md`
@@ -450,7 +468,7 @@ Si no existe un `.gitignore`, se creará uno nuevo. Si ya existe, las entradas s
450
468
  - `"auto"`
451
469
  2. **Analiza los cambios del staging area**:
452
470
  - Lista archivos modificados con estadísticas
453
- - Incluye diffs completos para archivos < 100KB
471
+ - Incluye diffs completos para archivos < 1MB
454
472
  3. **Genera mensaje en formato Conventional Commits**:
455
473
  - Determina tipo: feat, fix, docs, style, refactor, test, chore
456
474
  - Crea título conciso y descriptivo
@@ -471,7 +489,7 @@ Si no existe un `.gitignore`, se creará uno nuevo. Si ya existe, las entradas s
471
489
  - 📝 Archivo `.claude-pr-analysis.json`
472
490
  - **Auto-actualización**: Verificación automática de versiones antes de cada commit con prompt interactivo para actualizar
473
491
  - **Comando update**: `claude-hooks update` para actualizar manualmente a la última versión
474
- - **Modo debug**: `DEBUG=1 git commit` guarda respuestas en `debug-claude-response.json`
492
+ - **Modo debug**: `claude-hooks --debug true` activa logging detallado para troubleshooting
475
493
  - **Análisis de PR**: Nuevo comando `analyze-diff` para generar información de Pull Requests
476
494
  - **Validación de dependencias**: Verifica que Claude CLI esté autenticado antes de ejecutar
477
495
  - **⚠️ 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.
@@ -518,13 +536,13 @@ claude-hooks status
518
536
 
519
537
  En `lib/hooks/pre-commit.js`:
520
538
 
521
- - **`MAX_FILE_SIZE`**: Tamaño máximo de archivo a analizar (default: 100KB)
522
- - **`MAX_FILES`**: Número máximo de archivos por commit (default: 10)
539
+ - **`MAX_FILE_SIZE`**: Tamaño máximo de archivo a analizar (default: 1MB)
540
+ - **`MAX_FILES`**: Número máximo de archivos por commit (default: 30)
523
541
  - **`ALLOWED_EXTENSIONS`**: Extensiones permitidas (default: .java, .xml, .properties, .yml, .yaml)
524
542
 
525
543
  En `lib/hooks/prepare-commit-msg.js`:
526
544
 
527
- - **`MAX_FILE_SIZE`**: Tamaño máximo para incluir diff completo (default: 100KB)
545
+ - **`MAX_FILE_SIZE`**: Tamaño máximo para incluir diff completo (default: 1MB)
528
546
 
529
547
  ### Pautas de Evaluación
530
548
 
@@ -556,16 +574,20 @@ claude-git-hooks/
556
574
  ├── bin/
557
575
  │ └── claude-hooks # CLI principal (ES6 modules)
558
576
  ├── lib/ # 🆕 Código Node.js modular
577
+ │ ├── config.js # Configuración centralizada con merge
559
578
  │ ├── hooks/
560
579
  │ │ ├── pre-commit.js # Hook de análisis (Node.js)
561
580
  │ │ └── prepare-commit-msg.js # Hook de mensajes (Node.js)
562
581
  │ └── utils/
563
582
  │ ├── logger.js # Sistema de logging centralizado
564
583
  │ ├── git-operations.js # Operaciones git abstractas
565
- │ ├── file-operations.js # I/O con filtro SKIP_ANALYSIS_LINE
584
+ │ ├── file-utils.js # Utilidades de sistema de archivos
566
585
  │ ├── claude-client.js # Cliente Claude CLI
567
586
  │ ├── prompt-builder.js # Constructor de prompts
568
- └── resolution-prompt.js # Generador de resolution prompts
587
+ ├── resolution-prompt.js # Generador de resolution prompts
588
+ │ ├── preset-loader.js # Cargador de presets
589
+ │ ├── installation-diagnostics.js # Diagnósticos de instalación
590
+ │ └── claude-diagnostics.js # Diagnósticos de errores Claude CLI
569
591
  ├── templates/
570
592
  │ ├── pre-commit # Bash wrapper (llama a lib/hooks/pre-commit.js)
571
593
  │ ├── prepare-commit-msg # Bash wrapper (llama a lib/hooks/prepare-commit-msg.js)
@@ -588,6 +610,68 @@ claude-git-hooks/
588
610
  └── .gitignore # Archivos ignorados por git
589
611
  ```
590
612
 
613
+ ### 🔌 Utility Modules Reference
614
+
615
+ **Purpose**: Reusable modules for extending claude-hooks or building similar tools
616
+
617
+ #### Core Utilities
618
+
619
+ | Module | Purpose | Key Exports | Usage Context |
620
+ |--------|---------|-------------|---------------|
621
+ | **`config.js`** | Centralized configuration management | `getConfig()`, `defaults` | Priority merging: defaults < user < preset |
622
+ | **`logger.js`** | Structured logging with debug support | `info()`, `warning()`, `error()`, `debug()` | Console output with context tracking |
623
+ | **`git-operations.js`** | Git command abstractions | `getRepoRoot()`, `getStagedFiles()`, `getDiff()` | Safe git operations with error handling |
624
+ | **`file-utils.js`** | File system operations | `ensureDir()`, `writeFile()` | Repo-root-relative path handling |
625
+ | **`claude-client.js`** | Claude CLI integration | `analyzeCode()`, `analyzeCodeParallel()` | Prompt execution with timeout/retry |
626
+ | **`prompt-builder.js`** | Template-based prompts | `buildAnalysisPrompt()`, `loadTemplate()` | Dynamic prompt construction from .md files |
627
+ | **`preset-loader.js`** | Preset system | `loadPreset()`, `listPresets()`, `loadTemplate()` | Metadata, config, template loading |
628
+ | **`resolution-prompt.js`** | Issue resolution prompts | `generateResolutionPrompt()` | AI-friendly error remediation prompts |
629
+ | **`installation-diagnostics.js`** | Installation error diagnostics | `formatError()`, `getInstallationDiagnostics()` | Installation error formatting with remediation |
630
+ | **`claude-diagnostics.js`** | Claude CLI error diagnostics | `detectClaudeError()`, `formatClaudeError()` | Rate limit, auth, network error detection |
631
+
632
+ #### Using Utilities in Other Claude Instances
633
+
634
+ **Example: Check installation health**
635
+ ```javascript
636
+ import { formatError } from './lib/utils/installation-diagnostics.js';
637
+
638
+ try {
639
+ // ... operation that may fail
640
+ } catch (error) {
641
+ console.error(formatError('Operation failed', ['Additional context line']));
642
+ process.exit(1);
643
+ }
644
+ ```
645
+
646
+ **Example: Load configuration**
647
+ ```javascript
648
+ import { getConfig } from './lib/config.js';
649
+
650
+ const config = await getConfig();
651
+ const maxFiles = config.analysis.maxFiles;
652
+ ```
653
+
654
+ **Example: Execute git operations**
655
+ ```javascript
656
+ import { getRepoRoot, getStagedFiles } from './lib/utils/git-operations.js';
657
+
658
+ const repoRoot = getRepoRoot();
659
+ const files = getStagedFiles({ extensions: ['.js', '.ts'] });
660
+ ```
661
+
662
+ **Example: Build custom prompts**
663
+ ```javascript
664
+ import { buildAnalysisPrompt } from './lib/utils/prompt-builder.js';
665
+
666
+ const prompt = await buildAnalysisPrompt({
667
+ templateName: 'CUSTOM_PROMPT.md',
668
+ files: filesData,
669
+ metadata: { REPO_NAME: 'my-repo' }
670
+ });
671
+ ```
672
+
673
+ **Note**: All utilities follow single-responsibility principle and include JSDoc documentation inline.
674
+
591
675
  ### Configuración del Entorno de Desarrollo
592
676
 
593
677
  ```bash
package/bin/claude-hooks CHANGED
@@ -468,6 +468,7 @@ async function install(args) {
468
468
  console.log(' 📝 Edit .claude/config.json to customize settings');
469
469
  console.log(' 🎯 Use presets: backend, frontend, fullstack, database, ai, default');
470
470
  console.log(' 🚀 Enable parallel analysis: set subagents.enabled = true');
471
+ console.log(' 🐛 Enable debug mode: claude-hooks --debug true');
471
472
  console.log('\n📖 Example config.json:');
472
473
  console.log(' {');
473
474
  console.log(' "preset": "backend",');
@@ -1167,6 +1168,7 @@ Commands:
1167
1168
  presets List all available presets
1168
1169
  --set-preset <name> Set the active preset
1169
1170
  preset current Show the current active preset
1171
+ --debug <value> Set debug mode (true, false, or status)
1170
1172
  --version, -v Show the current version
1171
1173
  help Show this help
1172
1174
 
@@ -1185,6 +1187,8 @@ Examples:
1185
1187
  claude-hooks presets # List available presets
1186
1188
  claude-hooks --set-preset backend # Set backend preset
1187
1189
  claude-hooks preset current # Show current preset
1190
+ claude-hooks --debug true # Enable debug mode
1191
+ claude-hooks --debug status # Check debug status
1188
1192
 
1189
1193
  Commit use cases:
1190
1194
  git commit -m "message" # Manual message + blocking analysis
@@ -1236,6 +1240,12 @@ Parallel Analysis (v2.2.0+):
1236
1240
  - batchSize: 4+ → Fewer API calls but slower
1237
1241
  - Speed improvement: up to 4x faster with batchSize: 1
1238
1242
 
1243
+ Debug Mode:
1244
+ Enable detailed logging for troubleshooting:
1245
+ - CLI: claude-hooks --debug true
1246
+ - Config: "system": { "debug": true } in .claude/config.json
1247
+ - Check status: claude-hooks --debug status
1248
+
1239
1249
  Customization:
1240
1250
  Override prompts by copying to .claude/:
1241
1251
  cp templates/COMMIT_MESSAGE.md .claude/
@@ -1247,6 +1257,68 @@ More information: https://github.com/pablorovito/claude-git-hooks
1247
1257
  `);
1248
1258
  }
1249
1259
 
1260
+ // Configuration Management Functions
1261
+
1262
+ /**
1263
+ * Updates a configuration value in .claude/config.json
1264
+ * Why: Centralized config update logic for all CLI commands
1265
+ *
1266
+ * @param {string} propertyPath - Dot notation path (e.g., 'preset', 'system.debug')
1267
+ * @param {any} value - Value to set
1268
+ * @param {Object} options - Optional settings
1269
+ * @param {Function} options.validator - Custom validation function, receives value, throws on invalid
1270
+ * @param {Function} options.successMessage - Function that receives value and returns success message
1271
+ */
1272
+ async function updateConfig(propertyPath, value, options = {}) {
1273
+ const { validator, successMessage } = options;
1274
+
1275
+ try {
1276
+ // Validate value if validator provided
1277
+ if (validator) {
1278
+ await validator(value);
1279
+ }
1280
+
1281
+ // Get repo root
1282
+ const repoRoot = execSync('git rev-parse --show-toplevel', { encoding: 'utf8' }).trim();
1283
+ const configDir = path.join(repoRoot, '.claude');
1284
+ const configPath = path.join(configDir, 'config.json');
1285
+
1286
+ // Ensure .claude directory exists
1287
+ if (!fs.existsSync(configDir)) {
1288
+ fs.mkdirSync(configDir, { recursive: true });
1289
+ }
1290
+
1291
+ // Load existing config or create new
1292
+ let config = {};
1293
+ if (fs.existsSync(configPath)) {
1294
+ config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
1295
+ }
1296
+
1297
+ // Set value at propertyPath (support dot notation like 'system.debug')
1298
+ const pathParts = propertyPath.split('.');
1299
+ let current = config;
1300
+ for (let i = 0; i < pathParts.length - 1; i++) {
1301
+ const part = pathParts[i];
1302
+ if (!current[part] || typeof current[part] !== 'object') {
1303
+ current[part] = {};
1304
+ }
1305
+ current = current[part];
1306
+ }
1307
+ current[pathParts[pathParts.length - 1]] = value;
1308
+
1309
+ // Save config
1310
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
1311
+
1312
+ // Show success message
1313
+ const message = successMessage ? successMessage(value) : 'Configuration updated';
1314
+ success(message);
1315
+ info(`Configuration saved to ${configPath}`);
1316
+ } catch (err) {
1317
+ error(`Failed to update configuration: ${err.message}`);
1318
+ process.exit(1);
1319
+ }
1320
+ }
1321
+
1250
1322
  // Preset Management Functions
1251
1323
 
1252
1324
  /**
@@ -1282,6 +1354,7 @@ async function showPresets() {
1282
1354
 
1283
1355
  /**
1284
1356
  * Sets the active preset
1357
+ * Why: Configures tech-stack specific analysis settings
1285
1358
  */
1286
1359
  async function setPreset(presetName) {
1287
1360
  if (!presetName) {
@@ -1289,45 +1362,24 @@ async function setPreset(presetName) {
1289
1362
  return;
1290
1363
  }
1291
1364
 
1292
- try {
1293
- // Verify preset exists
1294
- const presets = await listPresets();
1295
- const preset = presets.find(p => p.name === presetName);
1296
-
1297
- if (!preset) {
1298
- error(`Preset "${presetName}" not found`);
1299
- info('Available presets:');
1300
- presets.forEach(p => console.log(` - ${p.name}`));
1301
- process.exit(1);
1302
- }
1303
-
1304
- // Update .claude/config.json
1305
- const repoRoot = execSync('git rev-parse --show-toplevel', { encoding: 'utf8' }).trim();
1306
- const configDir = path.join(repoRoot, '.claude');
1307
- const configPath = path.join(configDir, 'config.json');
1308
-
1309
- // Ensure .claude directory exists
1310
- if (!fs.existsSync(configDir)) {
1311
- fs.mkdirSync(configDir, { recursive: true });
1312
- }
1313
-
1314
- // Load existing config or create new
1315
- let config = {};
1316
- if (fs.existsSync(configPath)) {
1317
- config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
1365
+ await updateConfig('preset', presetName, {
1366
+ validator: async (name) => {
1367
+ const presets = await listPresets();
1368
+ const preset = presets.find(p => p.name === name);
1369
+ if (!preset) {
1370
+ error(`Preset "${name}" not found`);
1371
+ info('Available presets:');
1372
+ presets.forEach(p => console.log(` - ${p.name}`));
1373
+ throw new Error(`Invalid preset: ${name}`);
1374
+ }
1375
+ return preset;
1376
+ },
1377
+ successMessage: async (name) => {
1378
+ const presets = await listPresets();
1379
+ const preset = presets.find(p => p.name === name);
1380
+ return `Preset '${preset.displayName}' activated`;
1318
1381
  }
1319
-
1320
- // Set preset
1321
- config.preset = presetName;
1322
-
1323
- // Save config
1324
- fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
1325
-
1326
- success(`Preset '${preset.displayName}' activated`);
1327
- info(`Configuration saved to ${configPath}`);
1328
- } catch (err) {
1329
- error(`Failed to set preset: ${err.message}`);
1330
- }
1382
+ });
1331
1383
  }
1332
1384
 
1333
1385
  /**
@@ -1354,6 +1406,45 @@ async function currentPreset() {
1354
1406
  }
1355
1407
  }
1356
1408
 
1409
+ /**
1410
+ * Sets debug mode
1411
+ * Why: Enables detailed logging for troubleshooting
1412
+ */
1413
+ async function setDebug(value) {
1414
+ if (!value) {
1415
+ error('Please specify a value: claude-hooks --debug <true|false|status>');
1416
+ return;
1417
+ }
1418
+
1419
+ const normalizedValue = value.toLowerCase();
1420
+
1421
+ // Handle status check
1422
+ if (normalizedValue === 'status') {
1423
+ try {
1424
+ const config = await getConfig();
1425
+ const isEnabled = config.system.debug || false;
1426
+ console.log('');
1427
+ info(`Debug mode: ${isEnabled ? colors.green + 'enabled' + colors.reset : colors.red + 'disabled' + colors.reset}`);
1428
+ console.log('');
1429
+ } catch (err) {
1430
+ error(`Failed to check debug status: ${err.message}`);
1431
+ }
1432
+ return;
1433
+ }
1434
+
1435
+ // Validate and convert to boolean
1436
+ if (normalizedValue !== 'true' && normalizedValue !== 'false') {
1437
+ error('Invalid value. Use: true, false, or status');
1438
+ return;
1439
+ }
1440
+
1441
+ const debugValue = normalizedValue === 'true';
1442
+
1443
+ await updateConfig('system.debug', debugValue, {
1444
+ successMessage: (val) => `Debug mode ${val ? 'enabled' : 'disabled'}`
1445
+ });
1446
+ }
1447
+
1357
1448
  // Main
1358
1449
  async function main() {
1359
1450
  const args = process.argv.slice(2);
@@ -1395,6 +1486,9 @@ async function main() {
1395
1486
  error(`Unknown preset subcommand: ${args[1]}`);
1396
1487
  }
1397
1488
  break;
1489
+ case '--debug':
1490
+ await setDebug(args[1]);
1491
+ break;
1398
1492
  case '--version':
1399
1493
  case '-v':
1400
1494
  case 'version':
package/lib/config.js CHANGED
@@ -2,13 +2,14 @@
2
2
  * File: config.js
3
3
  * Purpose: Centralized configuration management
4
4
  *
5
- * Priority: .claude/config.json > defaults
5
+ * Priority: preset config > .claude/config.json > defaults
6
6
  *
7
7
  * Key features:
8
8
  * - Single source of truth for all configurable values
9
9
  * - No environment variables (except OS for platform detection)
10
10
  * - Preset-aware (allowedExtensions come from preset templates)
11
- * - Override via .claude/config.json per project
11
+ * - User config (.claude/config.json) provides general preferences per project
12
+ * - Preset config provides tech-stack-specific overrides (highest priority)
12
13
  */
13
14
 
14
15
  import fs from 'fs';
@@ -25,9 +26,9 @@ const __dirname = path.dirname(__filename);
25
26
  const defaults = {
26
27
  // Analysis configuration
27
28
  analysis: {
28
- maxFileSize: 100000, // 100KB - max file size to analyze
29
- maxFiles: 10, // Max number of files per commit
30
- timeout: 120000, // 2 minutes - Claude analysis timeout
29
+ maxFileSize: 1000000, // 1MB - max file size to analyze
30
+ maxFiles: 20, // Max number of files per commit
31
+ timeout: 300000, // 3 minutes - Claude analysis timeout
31
32
  contextLines: 3, // Git diff context lines
32
33
  ignoreExtensions: [], // Extensions to exclude (e.g., ['.min.js', '.lock'])
33
34
  // NOTE: allowedExtensions comes from preset/template, not here
@@ -36,14 +37,14 @@ const defaults = {
36
37
  // Commit message generation
37
38
  commitMessage: {
38
39
  autoKeyword: 'auto', // Keyword to trigger auto-generation
39
- timeout: 180000,
40
+ timeout: 300000,
40
41
  },
41
42
 
42
43
  // Subagent configuration (parallel analysis)
43
44
  subagents: {
44
- enabled: true, // Enable parallel file analysis
45
+ enabled: false, // Enable parallel file analysis
45
46
  model: 'haiku', // haiku (fast), sonnet (balanced), opus (thorough)
46
- batchSize: 3, // Parallel subagents per batch
47
+ batchSize: 1, // Parallel subagents per batch
47
48
  },
48
49
 
49
50
  // Template paths
@@ -79,9 +80,9 @@ const defaults = {
79
80
 
80
81
  /**
81
82
  * Loads user configuration from .claude/config.json
82
- * Merges with defaults and preset config (preset -> user config takes priority)
83
+ * Merges with defaults and preset config (preset takes highest priority)
83
84
  *
84
- * Priority: defaults < preset config < user config
85
+ * Priority: defaults < user config < preset config
85
86
  *
86
87
  * @param {string} baseDir - Base directory to search for config (default: cwd)
87
88
  * @returns {Promise<Object>} Merged configuration
@@ -112,8 +113,8 @@ const loadUserConfig = async (baseDir = process.cwd()) => {
112
113
  }
113
114
  }
114
115
 
115
- // Merge: defaults < preset < user
116
- return deepMerge(deepMerge(defaults, presetConfig), userConfig);
116
+ // Merge: defaults < user < preset
117
+ return deepMerge(deepMerge(defaults, userConfig), presetConfig);
117
118
  };
118
119
 
119
120
  /**