claude-git-hooks 2.4.0 → 2.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/README.md +34 -29
- package/bin/claude-hooks +16 -8
- package/lib/utils/claude-client.js +40 -11
- package/package.json +1 -1
- package/templates/config.example.json +41 -41
- package/templates/presets/ai/config.json +12 -12
- package/templates/presets/ai/preset.json +31 -36
- package/templates/presets/backend/ANALYSIS_PROMPT.md +23 -28
- package/templates/presets/backend/PRE_COMMIT_GUIDELINES.md +41 -3
- package/templates/presets/backend/config.json +12 -12
- package/templates/presets/database/config.json +12 -12
- package/templates/presets/default/config.json +12 -12
- package/templates/presets/frontend/config.json +12 -12
- package/templates/presets/fullstack/config.json +12 -12
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
|
+
## [2.4.1] - 2025-11-19
|
|
9
|
+
|
|
10
|
+
### 🐛 Fixed
|
|
11
|
+
|
|
12
|
+
- **Git Bash Windows Support** - Claude hooks now works correctly on Git Bash in Windows
|
|
13
|
+
- **What changed**:
|
|
14
|
+
- `--skip-auth` now skips both Claude CLI verification AND authentication (previously only auth)
|
|
15
|
+
- Windows detection now tries native Claude first, WSL as fallback
|
|
16
|
+
- `spawn()` now uses `shell: true` to resolve `.cmd`/`.bat` executables
|
|
17
|
+
- **Why**:
|
|
18
|
+
- Installation with `--skip-auth` was failing before copying `.md` files and presets
|
|
19
|
+
- Code assumed Claude must always run via WSL on Windows, ignoring native installations
|
|
20
|
+
- Git Bash runs Node.js natively on Windows, not in WSL
|
|
21
|
+
- `spawn()` without shell couldn't find Windows batch files
|
|
22
|
+
- **Files updated**:
|
|
23
|
+
- `bin/claude-hooks:512-518` - Skip auth now skips Claude CLI check
|
|
24
|
+
- `bin/claude-hooks:532-544` - Native Windows Claude detection
|
|
25
|
+
- `lib/utils/claude-client.js:75-115` - Smart platform detection with fallback
|
|
26
|
+
- `lib/utils/claude-client.js:145-148` - Added `shell: true` for Windows compatibility
|
|
27
|
+
- **Impact**: Git Bash users on Windows can now use native Claude (via npm/NVM) instead of requiring WSL
|
|
28
|
+
|
|
29
|
+
### 🎯 User Experience
|
|
30
|
+
|
|
31
|
+
- **Installation**: `claude-hooks install --skip-auth` now completes successfully, installing all templates and presets
|
|
32
|
+
- **NVM Compatibility**: Works with Claude CLI installed via npm in current Node version (NVM managed)
|
|
33
|
+
- **Flexible Setup**: Automatically detects and uses best available Claude CLI method (native Windows or WSL)
|
|
34
|
+
|
|
8
35
|
## [2.4.0] - 2025-11-17
|
|
9
36
|
|
|
10
37
|
### ⚠️ BREAKING CHANGES
|
package/README.md
CHANGED
|
@@ -102,6 +102,10 @@ git commit --no-verify -m "hotfix: corrección urgente"
|
|
|
102
102
|
git commit --amend
|
|
103
103
|
```
|
|
104
104
|
|
|
105
|
+
## 📆 Próximos Desarrollos
|
|
106
|
+
|
|
107
|
+
Toda idea es bienvenida, aunque parezca espantosa. Si hay bugs, incluirlos también. Dónde? en https://github.com/mscope-S-L/git-hooks/issues/new.
|
|
108
|
+
|
|
105
109
|
### ⚠️ Exclusión de Código del Análisis (EXPERIMENTAL/BROKEN)
|
|
106
110
|
|
|
107
111
|
```java
|
|
@@ -155,14 +159,14 @@ EOF
|
|
|
155
159
|
|
|
156
160
|
#### 🎯 Presets Disponibles
|
|
157
161
|
|
|
158
|
-
| Preset | Extensiones de Archivo | Caso de Uso
|
|
159
|
-
| ------------- | -------------------------------------------------------------------------- |
|
|
160
|
-
| **backend** | `.java`, `.xml`, `.yml`, `.yaml` | APIs Spring Boot
|
|
161
|
-
| **frontend** | `.js`, `.jsx`, `.ts`, `.tsx`, `.css`, `.scss`, `.html` | Apps React
|
|
162
|
-
| **fullstack** | Todos backend + frontend | Apps full-stack
|
|
163
|
-
| **database** | `.sql` | Scripts de BD
|
|
164
|
-
| **ai** | `.js`, `.json`, `.md`, `.sh` | Herramientas CLI
|
|
165
|
-
| **default** | `.js`, `.sh`, `.py`, `.rb`, `.pl`, `.sql`, `.yaml`, `.json`, `.xml`, `.md` | Propósito general| Lenguajes mixtos |
|
|
162
|
+
| Preset | Extensiones de Archivo | Caso de Uso | Tech Stack |
|
|
163
|
+
| ------------- | -------------------------------------------------------------------------- | ----------------- | ---------------------------- |
|
|
164
|
+
| **backend** | `.java`, `.xml`, `.yml`, `.yaml` | APIs Spring Boot | Spring Boot, JPA, SQL Server |
|
|
165
|
+
| **frontend** | `.js`, `.jsx`, `.ts`, `.tsx`, `.css`, `.scss`, `.html` | Apps React | React, Redux, Material-UI |
|
|
166
|
+
| **fullstack** | Todos backend + frontend | Apps full-stack | Spring Boot + React |
|
|
167
|
+
| **database** | `.sql` | Scripts de BD | SQL Server, T-SQL |
|
|
168
|
+
| **ai** | `.js`, `.json`, `.md`, `.sh` | Herramientas CLI | Node.js, Claude API |
|
|
169
|
+
| **default** | `.js`, `.sh`, `.py`, `.rb`, `.pl`, `.sql`, `.yaml`, `.json`, `.xml`, `.md` | Propósito general | Lenguajes mixtos |
|
|
166
170
|
|
|
167
171
|
---
|
|
168
172
|
|
|
@@ -421,9 +425,6 @@ Durante la instalación, Claude Hooks actualiza automáticamente tu `.gitignore`
|
|
|
421
425
|
```gitignore
|
|
422
426
|
# Claude Git Hooks
|
|
423
427
|
.claude/
|
|
424
|
-
debug-claude-response.json
|
|
425
|
-
claude_resolution_prompt.md
|
|
426
|
-
.claude-pr-analysis.json
|
|
427
428
|
```
|
|
428
429
|
|
|
429
430
|
Esto asegura que:
|
|
@@ -616,34 +617,36 @@ claude-git-hooks/
|
|
|
616
617
|
|
|
617
618
|
#### Core Utilities
|
|
618
619
|
|
|
619
|
-
| Module
|
|
620
|
-
|
|
621
|
-
| **`config.js`**
|
|
622
|
-
| **`logger.js`**
|
|
623
|
-
| **`git-operations.js`**
|
|
624
|
-
| **`file-utils.js`**
|
|
625
|
-
| **`claude-client.js`**
|
|
626
|
-
| **`prompt-builder.js`**
|
|
627
|
-
| **`preset-loader.js`**
|
|
628
|
-
| **`resolution-prompt.js`**
|
|
629
|
-
| **`installation-diagnostics.js`** | Installation error diagnostics
|
|
630
|
-
| **`claude-diagnostics.js`**
|
|
620
|
+
| Module | Purpose | Key Exports | Usage Context |
|
|
621
|
+
| --------------------------------- | ------------------------------------- | ------------------------------------------------- | ---------------------------------------------- |
|
|
622
|
+
| **`config.js`** | Centralized configuration management | `getConfig()`, `defaults` | Priority merging: defaults < user < preset |
|
|
623
|
+
| **`logger.js`** | Structured logging with debug support | `info()`, `warning()`, `error()`, `debug()` | Console output with context tracking |
|
|
624
|
+
| **`git-operations.js`** | Git command abstractions | `getRepoRoot()`, `getStagedFiles()`, `getDiff()` | Safe git operations with error handling |
|
|
625
|
+
| **`file-utils.js`** | File system operations | `ensureDir()`, `writeFile()` | Repo-root-relative path handling |
|
|
626
|
+
| **`claude-client.js`** | Claude CLI integration | `analyzeCode()`, `analyzeCodeParallel()` | Prompt execution with timeout/retry |
|
|
627
|
+
| **`prompt-builder.js`** | Template-based prompts | `buildAnalysisPrompt()`, `loadTemplate()` | Dynamic prompt construction from .md files |
|
|
628
|
+
| **`preset-loader.js`** | Preset system | `loadPreset()`, `listPresets()`, `loadTemplate()` | Metadata, config, template loading |
|
|
629
|
+
| **`resolution-prompt.js`** | Issue resolution prompts | `generateResolutionPrompt()` | AI-friendly error remediation prompts |
|
|
630
|
+
| **`installation-diagnostics.js`** | Installation error diagnostics | `formatError()`, `getInstallationDiagnostics()` | Installation error formatting with remediation |
|
|
631
|
+
| **`claude-diagnostics.js`** | Claude CLI error diagnostics | `detectClaudeError()`, `formatClaudeError()` | Rate limit, auth, network error detection |
|
|
631
632
|
|
|
632
633
|
#### Using Utilities in Other Claude Instances
|
|
633
634
|
|
|
634
635
|
**Example: Check installation health**
|
|
636
|
+
|
|
635
637
|
```javascript
|
|
636
638
|
import { formatError } from './lib/utils/installation-diagnostics.js';
|
|
637
639
|
|
|
638
640
|
try {
|
|
639
|
-
|
|
641
|
+
// ... operation that may fail
|
|
640
642
|
} catch (error) {
|
|
641
|
-
|
|
642
|
-
|
|
643
|
+
console.error(formatError('Operation failed', ['Additional context line']));
|
|
644
|
+
process.exit(1);
|
|
643
645
|
}
|
|
644
646
|
```
|
|
645
647
|
|
|
646
648
|
**Example: Load configuration**
|
|
649
|
+
|
|
647
650
|
```javascript
|
|
648
651
|
import { getConfig } from './lib/config.js';
|
|
649
652
|
|
|
@@ -652,6 +655,7 @@ const maxFiles = config.analysis.maxFiles;
|
|
|
652
655
|
```
|
|
653
656
|
|
|
654
657
|
**Example: Execute git operations**
|
|
658
|
+
|
|
655
659
|
```javascript
|
|
656
660
|
import { getRepoRoot, getStagedFiles } from './lib/utils/git-operations.js';
|
|
657
661
|
|
|
@@ -660,13 +664,14 @@ const files = getStagedFiles({ extensions: ['.js', '.ts'] });
|
|
|
660
664
|
```
|
|
661
665
|
|
|
662
666
|
**Example: Build custom prompts**
|
|
667
|
+
|
|
663
668
|
```javascript
|
|
664
669
|
import { buildAnalysisPrompt } from './lib/utils/prompt-builder.js';
|
|
665
670
|
|
|
666
671
|
const prompt = await buildAnalysisPrompt({
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
672
|
+
templateName: 'CUSTOM_PROMPT.md',
|
|
673
|
+
files: filesData,
|
|
674
|
+
metadata: { REPO_NAME: 'my-repo' }
|
|
670
675
|
});
|
|
671
676
|
```
|
|
672
677
|
|
package/bin/claude-hooks
CHANGED
|
@@ -509,14 +509,12 @@ async function checkAndInstallDependencies(sudoPassword = null, skipAuth = false
|
|
|
509
509
|
|
|
510
510
|
// v2.0.0+: Unix tools (sed, awk, grep, etc.) no longer needed (pure Node.js implementation)
|
|
511
511
|
|
|
512
|
-
// Check and install Claude CLI
|
|
513
|
-
await checkAndInstallClaude();
|
|
514
|
-
|
|
515
|
-
// Check Claude authentication (if not skipped)
|
|
512
|
+
// Check and install Claude CLI (skip if --skip-auth)
|
|
516
513
|
if (!skipAuth) {
|
|
514
|
+
await checkAndInstallClaude();
|
|
517
515
|
await checkClaudeAuth();
|
|
518
516
|
} else {
|
|
519
|
-
warning('Skipping Claude
|
|
517
|
+
warning('Skipping Claude CLI verification and authentication (--skip-auth)');
|
|
520
518
|
}
|
|
521
519
|
|
|
522
520
|
// Clear password from memory
|
|
@@ -530,9 +528,19 @@ function isWindows() {
|
|
|
530
528
|
}
|
|
531
529
|
|
|
532
530
|
// Get Claude command based on platform
|
|
533
|
-
// Why: On Windows,
|
|
531
|
+
// Why: On Windows, try native Claude first, then WSL as fallback
|
|
534
532
|
function getClaudeCommand() {
|
|
535
|
-
|
|
533
|
+
if (isWindows()) {
|
|
534
|
+
// Try native Windows Claude first
|
|
535
|
+
try {
|
|
536
|
+
execSync('claude --version', { stdio: 'ignore', timeout: 3000 });
|
|
537
|
+
return 'claude';
|
|
538
|
+
} catch (e) {
|
|
539
|
+
// Fallback to WSL
|
|
540
|
+
return 'wsl claude';
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
return 'claude';
|
|
536
544
|
}
|
|
537
545
|
|
|
538
546
|
// Check if we need to install dependencies
|
|
@@ -1310,7 +1318,7 @@ async function updateConfig(propertyPath, value, options = {}) {
|
|
|
1310
1318
|
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
1311
1319
|
|
|
1312
1320
|
// Show success message
|
|
1313
|
-
const message = successMessage ? successMessage(value) : 'Configuration updated';
|
|
1321
|
+
const message = successMessage ? await successMessage(value) : 'Configuration updated';
|
|
1314
1322
|
success(message);
|
|
1315
1323
|
info(`Configuration saved to ${configPath}`);
|
|
1316
1324
|
} catch (err) {
|
|
@@ -67,22 +67,49 @@ const isWSLAvailable = () => {
|
|
|
67
67
|
|
|
68
68
|
/**
|
|
69
69
|
* Get Claude command configuration for current platform
|
|
70
|
-
* Why: On Windows,
|
|
70
|
+
* Why: On Windows, try native Claude first, then WSL as fallback
|
|
71
71
|
*
|
|
72
72
|
* @returns {Object} { command, args } - Command and base arguments
|
|
73
|
-
* @throws {ClaudeClientError} If
|
|
73
|
+
* @throws {ClaudeClientError} If Claude not available on any method
|
|
74
74
|
*/
|
|
75
75
|
const getClaudeCommand = () => {
|
|
76
76
|
if (isWindows()) {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
77
|
+
// Try native Windows Claude first (e.g., installed via npm/scoop/choco)
|
|
78
|
+
try {
|
|
79
|
+
execSync('claude --version', { stdio: 'ignore', timeout: 3000 });
|
|
80
|
+
logger.debug('claude-client - getClaudeCommand', 'Using native Windows Claude CLI');
|
|
81
|
+
return { command: 'claude', args: [] };
|
|
82
|
+
} catch (nativeError) {
|
|
83
|
+
logger.debug('claude-client - getClaudeCommand', 'Native Claude not found, trying WSL');
|
|
84
|
+
|
|
85
|
+
// Fallback to WSL
|
|
86
|
+
if (!isWSLAvailable()) {
|
|
87
|
+
throw new ClaudeClientError('Claude CLI not found. Install Claude CLI natively on Windows or via WSL', {
|
|
88
|
+
context: {
|
|
89
|
+
platform: 'Windows',
|
|
90
|
+
suggestions: [
|
|
91
|
+
'Native Windows: npm install -g @anthropic-ai/claude-cli',
|
|
92
|
+
'WSL: wsl --install, then install Claude in WSL'
|
|
93
|
+
]
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Check if Claude is available in WSL
|
|
99
|
+
try {
|
|
100
|
+
execSync('wsl claude --version', { stdio: 'ignore', timeout: 5000 });
|
|
101
|
+
logger.debug('claude-client - getClaudeCommand', 'Using WSL Claude CLI');
|
|
102
|
+
return { command: 'wsl', args: ['claude'] };
|
|
103
|
+
} catch (wslError) {
|
|
104
|
+
throw new ClaudeClientError('Claude CLI not found in Windows or WSL', {
|
|
105
|
+
context: {
|
|
106
|
+
platform: 'Windows',
|
|
107
|
+
nativeError: nativeError.message,
|
|
108
|
+
wslError: wslError.message
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
}
|
|
84
112
|
}
|
|
85
|
-
return { command: 'wsl', args: ['claude'] };
|
|
86
113
|
}
|
|
87
114
|
return { command: 'claude', args: [] };
|
|
88
115
|
};
|
|
@@ -114,8 +141,10 @@ const executeClaude = (prompt, { timeout = 120000 } = {}) => {
|
|
|
114
141
|
|
|
115
142
|
// Why: Use spawn instead of exec to handle large prompts and responses
|
|
116
143
|
// spawn streams data, exec buffers everything in memory
|
|
144
|
+
// shell: true needed on Windows to resolve .cmd/.bat executables
|
|
117
145
|
const claude = spawn(command, args, {
|
|
118
|
-
stdio: ['pipe', 'pipe', 'pipe'] // stdin, stdout, stderr
|
|
146
|
+
stdio: ['pipe', 'pipe', 'pipe'], // stdin, stdout, stderr
|
|
147
|
+
shell: true // Required for Windows to find .cmd/.bat files
|
|
119
148
|
});
|
|
120
149
|
|
|
121
150
|
let stdout = '';
|
package/package.json
CHANGED
|
@@ -1,41 +1,41 @@
|
|
|
1
|
-
{
|
|
2
|
-
"preset": "ai",
|
|
3
|
-
"analysis": {
|
|
4
|
-
"maxFileSize": 1000000,
|
|
5
|
-
"maxFiles": 30,
|
|
6
|
-
"timeout": 180000,
|
|
7
|
-
"contextLines": 3,
|
|
8
|
-
"ignoreExtensions": []
|
|
9
|
-
},
|
|
10
|
-
"commitMessage": {
|
|
11
|
-
"autoKeyword": "auto",
|
|
12
|
-
"timeout": 180000
|
|
13
|
-
},
|
|
14
|
-
"subagents": {
|
|
15
|
-
"enabled": false,
|
|
16
|
-
"model": "haiku",
|
|
17
|
-
"batchSize": 1
|
|
18
|
-
},
|
|
19
|
-
"templates": {
|
|
20
|
-
"baseDir": ".claude",
|
|
21
|
-
"analysis": "CLAUDE_ANALYSIS_PROMPT_SONAR.md",
|
|
22
|
-
"guidelines": "CLAUDE_PRE_COMMIT_SONAR.md",
|
|
23
|
-
"commitMessage": "COMMIT_MESSAGE.md",
|
|
24
|
-
"analyzeDiff": "ANALYZE_DIFF.md",
|
|
25
|
-
"resolution": "CLAUDE_RESOLUTION_PROMPT.md",
|
|
26
|
-
"subagentInstruction": "SUBAGENT_INSTRUCTION.md"
|
|
27
|
-
},
|
|
28
|
-
"output": {
|
|
29
|
-
"outputDir": ".claude/out",
|
|
30
|
-
"debugFile": ".claude/out/debug-claude-response.json",
|
|
31
|
-
"resolutionFile": ".claude/out/claude_resolution_prompt.md",
|
|
32
|
-
"prAnalysisFile": ".claude/out/pr-analysis.json"
|
|
33
|
-
},
|
|
34
|
-
"system": {
|
|
35
|
-
"debug": false,
|
|
36
|
-
"wslCheckTimeout": 3000
|
|
37
|
-
},
|
|
38
|
-
"git": {
|
|
39
|
-
"diffFilter": "ACM"
|
|
40
|
-
}
|
|
41
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"preset": "ai",
|
|
3
|
+
"analysis": {
|
|
4
|
+
"maxFileSize": 1000000,
|
|
5
|
+
"maxFiles": 30,
|
|
6
|
+
"timeout": 180000,
|
|
7
|
+
"contextLines": 3,
|
|
8
|
+
"ignoreExtensions": []
|
|
9
|
+
},
|
|
10
|
+
"commitMessage": {
|
|
11
|
+
"autoKeyword": "auto",
|
|
12
|
+
"timeout": 180000
|
|
13
|
+
},
|
|
14
|
+
"subagents": {
|
|
15
|
+
"enabled": false,
|
|
16
|
+
"model": "haiku",
|
|
17
|
+
"batchSize": 1
|
|
18
|
+
},
|
|
19
|
+
"templates": {
|
|
20
|
+
"baseDir": ".claude",
|
|
21
|
+
"analysis": "CLAUDE_ANALYSIS_PROMPT_SONAR.md",
|
|
22
|
+
"guidelines": "CLAUDE_PRE_COMMIT_SONAR.md",
|
|
23
|
+
"commitMessage": "COMMIT_MESSAGE.md",
|
|
24
|
+
"analyzeDiff": "ANALYZE_DIFF.md",
|
|
25
|
+
"resolution": "CLAUDE_RESOLUTION_PROMPT.md",
|
|
26
|
+
"subagentInstruction": "SUBAGENT_INSTRUCTION.md"
|
|
27
|
+
},
|
|
28
|
+
"output": {
|
|
29
|
+
"outputDir": ".claude/out",
|
|
30
|
+
"debugFile": ".claude/out/debug-claude-response.json",
|
|
31
|
+
"resolutionFile": ".claude/out/claude_resolution_prompt.md",
|
|
32
|
+
"prAnalysisFile": ".claude/out/pr-analysis.json"
|
|
33
|
+
},
|
|
34
|
+
"system": {
|
|
35
|
+
"debug": false,
|
|
36
|
+
"wslCheckTimeout": 3000
|
|
37
|
+
},
|
|
38
|
+
"git": {
|
|
39
|
+
"diffFilter": "ACM"
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
{
|
|
2
|
-
"analysis": {
|
|
3
|
-
"maxFileSize": 1000000,
|
|
4
|
-
"maxFiles": 10,
|
|
5
|
-
"timeout": 300000
|
|
6
|
-
},
|
|
7
|
-
"subagents": {
|
|
8
|
-
"enabled": true,
|
|
9
|
-
"model": "haiku",
|
|
10
|
-
"batchSize": 3
|
|
11
|
-
}
|
|
12
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"analysis": {
|
|
3
|
+
"maxFileSize": 1000000,
|
|
4
|
+
"maxFiles": 10,
|
|
5
|
+
"timeout": 300000
|
|
6
|
+
},
|
|
7
|
+
"subagents": {
|
|
8
|
+
"enabled": true,
|
|
9
|
+
"model": "haiku",
|
|
10
|
+
"batchSize": 3
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -1,42 +1,37 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
"name": "ai",
|
|
3
|
+
"displayName": "AI/CLI (Node.js + Claude)",
|
|
4
|
+
"description": "Node.js CLI tools with Claude API integration",
|
|
5
|
+
"version": "1.0.0",
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
7
|
+
"techStack": [
|
|
8
|
+
"Node.js",
|
|
9
|
+
"ES Modules",
|
|
10
|
+
"Claude API",
|
|
11
|
+
"CLI tools",
|
|
12
|
+
"Git hooks",
|
|
13
|
+
"Bash scripting",
|
|
14
|
+
"Markdown templates"
|
|
15
|
+
],
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
".js",
|
|
19
|
-
".json",
|
|
20
|
-
".md",
|
|
21
|
-
".sh"
|
|
22
|
-
],
|
|
17
|
+
"fileExtensions": [".js", ".json", ".md", ".sh"],
|
|
23
18
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
19
|
+
"focusAreas": [
|
|
20
|
+
"Claude API usage and best practices",
|
|
21
|
+
"Prompt engineering quality",
|
|
22
|
+
"CLI user experience",
|
|
23
|
+
"Error handling and logging",
|
|
24
|
+
"Git operations safety",
|
|
25
|
+
"Cross-platform compatibility",
|
|
26
|
+
"Token usage optimization",
|
|
27
|
+
"Security (API keys, secrets)"
|
|
28
|
+
],
|
|
34
29
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
30
|
+
"templates": {
|
|
31
|
+
"analysis": "ANALYSIS_PROMPT.md",
|
|
32
|
+
"guidelines": "PRE_COMMIT_GUIDELINES.md",
|
|
33
|
+
"commitMessage": "../shared/COMMIT_MESSAGE.md",
|
|
34
|
+
"analyzeDiff": "../shared/ANALYZE_DIFF.md",
|
|
35
|
+
"resolution": "../shared/RESOLUTION_PROMPT.md"
|
|
36
|
+
}
|
|
42
37
|
}
|
|
@@ -13,32 +13,35 @@ Perform a comprehensive code quality analysis focusing on these areas:
|
|
|
13
13
|
## Analysis Guidelines
|
|
14
14
|
|
|
15
15
|
1. **Security First**: Check for OWASP Top 10 vulnerabilities, especially:
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
- SQL injection risks
|
|
17
|
+
- Authentication/authorization flaws
|
|
18
|
+
- Sensitive data exposure
|
|
19
|
+
- XML external entities (XXE)
|
|
20
|
+
- Insecure deserialization
|
|
21
21
|
|
|
22
22
|
2. **Spring Boot Best Practices**:
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
- Proper use of `@Transactional`
|
|
24
|
+
- Correct exception handling
|
|
25
|
+
- Appropriate use of DTOs vs Entities
|
|
26
|
+
- Proper dependency injection // Si intelligence -> recomendar @RequiredArgsConstructor || Si Automation -> recomendar @Autowired
|
|
27
|
+
- Configuration management
|
|
28
28
|
|
|
29
29
|
3. **JPA/Hibernate**:
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
- N+1 query problems
|
|
31
|
+
- Lazy loading issues
|
|
32
|
+
- Proper use of relationships
|
|
33
|
+
- Query optimization
|
|
34
|
+
- Transaction boundaries
|
|
35
35
|
|
|
36
36
|
4. **Code Quality**:
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
- SOLID principles
|
|
38
|
+
- DRY violations
|
|
39
|
+
- Proper error handling
|
|
40
|
+
- Logging should be like so
|
|
41
|
+
- debug: regular flow, operations details
|
|
42
|
+
- info: important business events
|
|
43
|
+
- warn: anomalies and manageable errors
|
|
44
|
+
- error: exceptions and errors
|
|
42
45
|
|
|
43
46
|
## Output Format
|
|
44
47
|
|
|
@@ -48,14 +51,6 @@ Respond with a valid JSON following the SonarQube format:
|
|
|
48
51
|
{
|
|
49
52
|
"QUALITY_GATE": "PASSED|FAILED",
|
|
50
53
|
"approved": true|false,
|
|
51
|
-
"metrics": {
|
|
52
|
-
"reliability": "A|B|C|D|E",
|
|
53
|
-
"security": "A|B|C|D|E",
|
|
54
|
-
"maintainability": "A|B|C|D|E",
|
|
55
|
-
"coverage": 0-100,
|
|
56
|
-
"duplications": 0-100,
|
|
57
|
-
"complexity": "number"
|
|
58
|
-
},
|
|
59
54
|
"issues": {
|
|
60
55
|
"blocker": 0,
|
|
61
56
|
"critical": 0,
|
|
@@ -3,45 +3,63 @@
|
|
|
3
3
|
## Spring Boot Standards
|
|
4
4
|
|
|
5
5
|
### Controllers
|
|
6
|
-
|
|
6
|
+
|
|
7
|
+
- Use proper HTTP methods
|
|
8
|
+
- Endpoints should handle entities as substantives
|
|
9
|
+
- Make sure Response Codes include: [200, 201, 204, 400, 401, 403, 404, 409, 422, 500, 503] (if non-compliant classify as BLOCKER)
|
|
7
10
|
- Validate input with `@Valid`
|
|
8
11
|
- Handle exceptions with `@ExceptionHandler`
|
|
9
12
|
- Keep controllers thin - business logic in services
|
|
10
13
|
- Use DTOs for API contracts
|
|
11
14
|
|
|
12
15
|
### Services
|
|
16
|
+
|
|
13
17
|
- Use `@Transactional` appropriately
|
|
14
18
|
- Handle exceptions properly
|
|
15
19
|
- Keep methods focused and small
|
|
16
20
|
- Avoid business logic in controllers or repositories
|
|
17
21
|
|
|
18
22
|
### Repositories
|
|
23
|
+
|
|
19
24
|
- Extend appropriate Spring Data interfaces
|
|
20
25
|
- Use method naming conventions for queries
|
|
21
26
|
- Optimize queries with `@Query` when needed
|
|
22
27
|
- Avoid N+1 problems with `@EntityGraph`
|
|
23
28
|
|
|
24
29
|
### Entities
|
|
30
|
+
|
|
25
31
|
- Use Lombok annotations appropriately
|
|
26
32
|
- Define proper relationships (`@OneToMany`, `@ManyToOne`, etc.)
|
|
27
33
|
- Use `@Version` for optimistic locking
|
|
28
34
|
- Never expose entities in API - use DTOs
|
|
29
35
|
|
|
36
|
+
### Mappers
|
|
37
|
+
|
|
38
|
+
- Use Mapstruct for all mapping (If non-compliant, classify as MINOR)
|
|
39
|
+
- Mappers should not have logic (If non-compliant, classify as MAJOR)
|
|
40
|
+
|
|
41
|
+
### Logging
|
|
42
|
+
|
|
43
|
+
- Recommend @Slf4j annotation in Lombok (If non-compliant, classify as MINOR)
|
|
44
|
+
|
|
30
45
|
## Security Requirements
|
|
31
46
|
|
|
32
47
|
### Authentication & Authorization
|
|
48
|
+
|
|
33
49
|
- Never hardcode credentials
|
|
34
50
|
- Use Spring Security properly
|
|
35
51
|
- Validate JWT tokens correctly
|
|
36
52
|
- Check permissions before operations
|
|
37
53
|
|
|
38
54
|
### Data Validation
|
|
55
|
+
|
|
39
56
|
- Validate all user input
|
|
40
57
|
- Use parameterized queries (JPA does this by default)
|
|
41
58
|
- Sanitize data before logging
|
|
42
59
|
- Never trust client-side validation alone
|
|
43
60
|
|
|
44
61
|
### SQL Injection Prevention
|
|
62
|
+
|
|
45
63
|
- Always use JPA/JPQL or prepared statements
|
|
46
64
|
- Never concatenate SQL strings
|
|
47
65
|
- Be careful with native queries
|
|
@@ -50,35 +68,55 @@
|
|
|
50
68
|
## Performance
|
|
51
69
|
|
|
52
70
|
### Database
|
|
71
|
+
|
|
53
72
|
- Use pagination for large result sets
|
|
54
73
|
- Optimize queries with proper indexes
|
|
55
74
|
- Avoid loading unnecessary data
|
|
56
75
|
- Use projections when you don't need full entities
|
|
57
76
|
|
|
58
77
|
### Threading
|
|
78
|
+
|
|
59
79
|
- Be careful with `@Async` methods
|
|
60
80
|
- Use proper thread pool configuration
|
|
61
81
|
- Avoid blocking operations in async methods
|
|
62
82
|
- Handle exceptions in async methods
|
|
63
83
|
|
|
64
84
|
### Caching
|
|
85
|
+
|
|
65
86
|
- Use `@Cacheable` appropriately
|
|
66
87
|
- Clear caches when data changes
|
|
67
88
|
- Don't cache sensitive data without encryption
|
|
68
89
|
|
|
69
90
|
## Testing
|
|
70
91
|
|
|
71
|
-
|
|
92
|
+
### Unit Tests
|
|
93
|
+
|
|
94
|
+
- Unit tests should use exclusively JUnit 5, and specific annotations @SpringBootTest, @MockBean, @Test
|
|
72
95
|
- Use `@DataJpaTest` for repository tests
|
|
73
96
|
- Use `@WebMvcTest` for controller tests
|
|
74
97
|
- Mock external dependencies
|
|
75
98
|
- Aim for 80%+ coverage on new code
|
|
76
99
|
|
|
100
|
+
### Integration Tests
|
|
101
|
+
|
|
102
|
+
- Use `@SpringBootTest` with real application context
|
|
103
|
+
- Test complete request-response flows
|
|
104
|
+
- Verify database transactions and rollbacks
|
|
105
|
+
- Test API endpoint integration with all layers
|
|
106
|
+
- Use `@Transactional` with `@Rollback` for test data cleanup
|
|
107
|
+
|
|
108
|
+
### Security Tests
|
|
109
|
+
|
|
110
|
+
- Test authentication and authorization scenarios
|
|
111
|
+
- Verify access control for protected endpoints
|
|
112
|
+
- Test with invalid/expired tokens
|
|
113
|
+
- Validate input sanitization and XSS prevention
|
|
114
|
+
- Test SQL injection prevention with malicious input
|
|
115
|
+
|
|
77
116
|
## Common Issues to Avoid
|
|
78
117
|
|
|
79
118
|
❌ Returning entities from controllers
|
|
80
119
|
❌ Missing `@Transactional` on write operations
|
|
81
|
-
❌ N+1 query problems
|
|
82
120
|
❌ Hardcoded secrets or credentials
|
|
83
121
|
❌ Catching and ignoring exceptions
|
|
84
122
|
❌ Missing input validation
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
{
|
|
2
|
-
"analysis": {
|
|
3
|
-
"maxFileSize": 1000000,
|
|
4
|
-
"maxFiles": 10,
|
|
5
|
-
"timeout": 300000
|
|
6
|
-
},
|
|
7
|
-
"subagents": {
|
|
8
|
-
"enabled": true,
|
|
9
|
-
"model": "haiku",
|
|
10
|
-
"batchSize": 3
|
|
11
|
-
}
|
|
12
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"analysis": {
|
|
3
|
+
"maxFileSize": 1000000,
|
|
4
|
+
"maxFiles": 10,
|
|
5
|
+
"timeout": 300000
|
|
6
|
+
},
|
|
7
|
+
"subagents": {
|
|
8
|
+
"enabled": true,
|
|
9
|
+
"model": "haiku",
|
|
10
|
+
"batchSize": 3
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
{
|
|
2
|
-
"analysis": {
|
|
3
|
-
"maxFileSize": 1000000,
|
|
4
|
-
"maxFiles": 8,
|
|
5
|
-
"timeout": 300000
|
|
6
|
-
},
|
|
7
|
-
"subagents": {
|
|
8
|
-
"enabled": true,
|
|
9
|
-
"model": "haiku",
|
|
10
|
-
"batchSize": 2
|
|
11
|
-
}
|
|
12
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"analysis": {
|
|
3
|
+
"maxFileSize": 1000000,
|
|
4
|
+
"maxFiles": 8,
|
|
5
|
+
"timeout": 300000
|
|
6
|
+
},
|
|
7
|
+
"subagents": {
|
|
8
|
+
"enabled": true,
|
|
9
|
+
"model": "haiku",
|
|
10
|
+
"batchSize": 2
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
{
|
|
2
|
-
"analysis": {
|
|
3
|
-
"maxFileSize": 1000000,
|
|
4
|
-
"maxFiles": 10,
|
|
5
|
-
"timeout": 300000
|
|
6
|
-
},
|
|
7
|
-
"subagents": {
|
|
8
|
-
"enabled": true,
|
|
9
|
-
"model": "haiku",
|
|
10
|
-
"batchSize": 3
|
|
11
|
-
}
|
|
12
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"analysis": {
|
|
3
|
+
"maxFileSize": 1000000,
|
|
4
|
+
"maxFiles": 10,
|
|
5
|
+
"timeout": 300000
|
|
6
|
+
},
|
|
7
|
+
"subagents": {
|
|
8
|
+
"enabled": true,
|
|
9
|
+
"model": "haiku",
|
|
10
|
+
"batchSize": 3
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
{
|
|
2
|
-
"analysis": {
|
|
3
|
-
"maxFileSize": 1000000,
|
|
4
|
-
"maxFiles": 10,
|
|
5
|
-
"timeout": 300000
|
|
6
|
-
},
|
|
7
|
-
"subagents": {
|
|
8
|
-
"enabled": true,
|
|
9
|
-
"model": "haiku",
|
|
10
|
-
"batchSize": 3
|
|
11
|
-
}
|
|
12
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"analysis": {
|
|
3
|
+
"maxFileSize": 1000000,
|
|
4
|
+
"maxFiles": 10,
|
|
5
|
+
"timeout": 300000
|
|
6
|
+
},
|
|
7
|
+
"subagents": {
|
|
8
|
+
"enabled": true,
|
|
9
|
+
"model": "haiku",
|
|
10
|
+
"batchSize": 3
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
{
|
|
2
|
-
"analysis": {
|
|
3
|
-
"maxFileSize": 1000000,
|
|
4
|
-
"maxFiles": 15,
|
|
5
|
-
"timeout": 300000
|
|
6
|
-
},
|
|
7
|
-
"subagents": {
|
|
8
|
-
"enabled": true,
|
|
9
|
-
"model": "haiku",
|
|
10
|
-
"batchSize": 4
|
|
11
|
-
}
|
|
12
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"analysis": {
|
|
3
|
+
"maxFileSize": 1000000,
|
|
4
|
+
"maxFiles": 15,
|
|
5
|
+
"timeout": 300000
|
|
6
|
+
},
|
|
7
|
+
"subagents": {
|
|
8
|
+
"enabled": true,
|
|
9
|
+
"model": "haiku",
|
|
10
|
+
"batchSize": 4
|
|
11
|
+
}
|
|
12
|
+
}
|