claude-git-hooks 2.34.0 → 2.35.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 +15 -0
- package/CLAUDE.md +12 -10
- package/README.md +37 -0
- package/lib/commands/install.js +1 -1
- package/lib/commands/lint.js +1 -1
- package/lib/hooks/pre-commit.js +1 -1
- package/lib/utils/linter-runner.js +103 -14
- package/package.json +69 -69
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,21 @@ 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.35.0] - 2026-03-27
|
|
9
|
+
|
|
10
|
+
### ✨ Added
|
|
11
|
+
- Prettier formatting support — auto-formats JS/TS/CSS/HTML/JSON/YAML/MD files before linting (format first, then lint)
|
|
12
|
+
- Remote formatter configuration — preset-to-tools mapping fetched from centralized git-hooks-config repo, allowing team-wide control without releasing new versions
|
|
13
|
+
- New `parsePrettierOutput()` function for parsing Prettier --check output into structured issues
|
|
14
|
+
|
|
15
|
+
### 🔧 Changed
|
|
16
|
+
- Linting pipeline now runs formatters (Prettier) before linters (ESLint) for consistent code style
|
|
17
|
+
- Updated preset-to-tools mapping: frontend, fullstack, ai, and default presets now include Prettier
|
|
18
|
+
- `getLinterToolsForPreset()` now fetches remote config with local fallback instead of using hardcoded mapping only
|
|
19
|
+
- `runLinters()` and `checkLinterAvailability()` converted to async functions to support remote config fetching
|
|
20
|
+
- Unfixable linting issues are now forwarded to the Claude judge for semantic resolution instead of blocking directly
|
|
21
|
+
|
|
22
|
+
|
|
8
23
|
## [2.34.0] - 2026-03-27
|
|
9
24
|
|
|
10
25
|
### ✨ Added
|
package/CLAUDE.md
CHANGED
|
@@ -6,14 +6,14 @@
|
|
|
6
6
|
|
|
7
7
|
**Main use cases:**
|
|
8
8
|
|
|
9
|
-
1. **Pre-commit linting**: Runs linters (ESLint, Spotless, sqlfluff) on staged files before Claude analysis — fast, deterministic, auto-fix enabled by default
|
|
9
|
+
1. **Pre-commit linting**: Runs formatters and linters (Prettier, ESLint, Spotless, sqlfluff) on staged files before Claude analysis — fast, deterministic, auto-fix enabled by default
|
|
10
10
|
2. **Pre-commit analysis**: Detects security issues, bugs, and code smells before each commit (blocks on CRITICAL/BLOCKER only)
|
|
11
11
|
3. **Interactive analysis**: `claude-hooks analyze` - review all issues (INFO to BLOCKER) interactively before committing
|
|
12
12
|
4. **Automatic messages**: Write `git commit -m "auto"` and Claude generates the message in Conventional Commits format with task-id extracted from branch
|
|
13
13
|
5. **PR analysis**: `claude-hooks analyze-diff [branch]` generates title, description, and test plan for PRs
|
|
14
14
|
6. **PR review**: `claude-hooks analyze-pr <url>` analyzes a GitHub PR with preset guidelines, Linear ticket enrichment, and posts review comments
|
|
15
15
|
7. **PR creation**: `claude-hooks create-pr [branch]` creates the PR on GitHub with automatic metadata (reviewers from CODEOWNERS, labels by preset, merge strategy auto-detected from branch naming)
|
|
16
|
-
8. **Linting**: `claude-hooks lint [paths...]` runs linters on staged files, directories, or specific files — supports ESLint, Spotless, sqlfluff per preset
|
|
16
|
+
8. **Linting**: `claude-hooks lint [paths...]` runs formatters and linters on staged files, directories, or specific files — supports Prettier, ESLint, Spotless, sqlfluff per preset (remote config priority with local fallback)
|
|
17
17
|
9. **Coupling detection**: `claude-hooks check-coupling` scans open PRs targeting a base branch, computes file overlap, and reports which features are coupled (share modified files) — helps TL make informed decisions before cutting a release
|
|
18
18
|
10. **Shadow management**: `claude-hooks shadow <analyze|reset|sync>` manages the shadow branch lifecycle — analyze divergence vs main and active RC, reset shadow to a clean copy of main, or sync shadow with a source branch (RC, develop, feature)
|
|
19
19
|
11. **Release creation**: `claude-hooks create-release <major|minor|patch>` creates a release-candidate branch from develop, bumps version files, commits, pushes, and deploys to shadow — replaces the 8 manual steps executed every Tuesday by the Tech Lead
|
|
@@ -86,7 +86,7 @@ claude-git-hooks/
|
|
|
86
86
|
│ │ └── prepare-commit-msg.js # Message generation - auto commit messages
|
|
87
87
|
│ └── utils/ # Reusable modules - shared logic
|
|
88
88
|
│ ├── tool-runner.js # Generic tool executor - resolve, spawn, parse, auto-fix (v2.34.0)
|
|
89
|
-
│ ├── linter-runner.js # Linter orchestration - preset mapping, ESLint/Spotless/sqlfluff (v2.34.0)
|
|
89
|
+
│ ├── linter-runner.js # Linter orchestration - preset mapping, Prettier/ESLint/Spotless/sqlfluff, remote config (v2.34.0)
|
|
90
90
|
│ ├── analysis-engine.js # Shared analysis logic - file data, 3-tier routing, results (v2.13.0+)
|
|
91
91
|
│ ├── diff-analysis-orchestrator.js # Intelligent batch orchestration via Opus (v2.20.0)
|
|
92
92
|
│ ├── claude-client.js # Claude CLI wrapper - spawn, retry, model override
|
|
@@ -183,6 +183,7 @@ preset config (.claude/presets/{name}/config.json) ← HIGHEST PRIORITY
|
|
|
183
183
|
**Team-wide remote config** ([`mscope-S-L/git-hooks-config`](https://github.com/mscope-S-L/git-hooks-config)):
|
|
184
184
|
|
|
185
185
|
- `labels.json` — PR label rules (fetched by `remote-config.js`, consumed by `label-resolver.js`)
|
|
186
|
+
- `formatters.json` — preset-to-tools mapping for linting/formatting (fetched by `remote-config.js`, consumed by `linter-runner.js`)
|
|
186
187
|
- `permissions.json` — role-based authorization (fetched directly by `authorization.js`, fail-closed)
|
|
187
188
|
- Changes take effect immediately across all governed repos — no tool update needed
|
|
188
189
|
|
|
@@ -319,7 +320,7 @@ consolidateResults()
|
|
|
319
320
|
| `lib/cli-metadata.js` | Command registry | `commands`, `buildCommandMap()`, `generateCompletionData()`, `PRESET_NAMES`, `HOOK_NAMES`, `BUMP_TYPES` |
|
|
320
321
|
| `lib/config.js` | Config system | `getConfig()` |
|
|
321
322
|
| `tool-runner.js` | Generic tool executor | `isToolAvailable()`, `filterFilesByTool()`, `runTool()`, `runToolFix()`, `runToolWithAutoFix()`, `displayToolResult()` (v2.34.0) |
|
|
322
|
-
| `linter-runner.js` | Linter orchestration | `runLinters()`, `displayLintResults()`, `checkLinterAvailability()`, `getLinterToolsForPreset()`, `LINTER_TOOLS`, `PRESET_LINTERS`, `parseEslintOutput()`, `parseSpotlessOutput()`, `parseSqlfluffOutput()`, `filesToSpotlessRegex()` (v2.34.0)
|
|
323
|
+
| `linter-runner.js` | Linter orchestration | `runLinters()`, `displayLintResults()`, `checkLinterAvailability()`, `getLinterToolsForPreset()`, `LINTER_TOOLS`, `PRESET_LINTERS`, `parsePrettierOutput()`, `parseEslintOutput()`, `parseSpotlessOutput()`, `parseSqlfluffOutput()`, `filesToSpotlessRegex()` (v2.34.0) |
|
|
323
324
|
| `analysis-engine.js` | Shared analysis logic | `buildFileData()`, `buildFilesData()`, `runAnalysis()`, `consolidateResults()`, `hasBlockingIssues()`, `hasAnyIssues()`, `displayResults()`, `displayIssueSummary()` (v2.13.0+) |
|
|
324
325
|
| `diff-analysis-orchestrator.js` | Intelligent batch orchestration | `orchestrateBatches()`, `buildFileOverview()`, `detectDependencies()` (v2.20.0) |
|
|
325
326
|
| `claude-client.js` | Claude CLI wrapper | `analyzeCode()`, `executeClaudeWithRetry()`, `extractJSON()` — spawn, retry, model override |
|
|
@@ -359,8 +360,8 @@ consolidateResults()
|
|
|
359
360
|
7. **Adapter Pattern**: `git-operations.js` abstracts git commands into JS functions
|
|
360
361
|
8. **Singleton Pattern**: `config.js` loads configuration once per execution
|
|
361
362
|
9. **Guard Pattern**: `authorization.js` — fail-closed gate in `bin/claude-hooks` before command dispatch; static `PROTECTED_COMMANDS` set avoids API calls for unprotected commands; permissions sourced from `mscope-S-L/git-hooks-config/permissions.json`
|
|
362
|
-
10. **Remote Config Pattern**: `remote-config.js` — fetches JSON from `mscope-S-L/git-hooks-config`, caches per-process (including nulls), graceful degradation (warn + return null); `label-resolver.js` — callers
|
|
363
|
-
11. **Pipeline Pattern**: `tool-runner.js` + `linter-runner.js` — generic tool execution infrastructure;
|
|
363
|
+
10. **Remote Config Pattern**: `remote-config.js` — fetches JSON from `mscope-S-L/git-hooks-config`, caches per-process (including nulls), graceful degradation (warn + return null); `label-resolver.js` and `linter-runner.js` — callers fetch remote config and decide fallback (`labels.json` for PR labels, `formatters.json` for preset-to-tools mapping)
|
|
364
|
+
11. **Pipeline Pattern**: `tool-runner.js` + `linter-runner.js` — generic tool execution infrastructure; formatters (Prettier) and linters (ESLint, Spotless, sqlfluff) share the same resolve → spawn → parse → fix → re-stage pipeline. Tool definitions are data objects, not classes. Preset-to-tools mapping fetched from `mscope-S-L/git-hooks-config/formatters.json` (remote config priority, local fallback).
|
|
364
365
|
|
|
365
366
|
### Key Data Flows
|
|
366
367
|
|
|
@@ -372,13 +373,14 @@ git commit
|
|
|
372
373
|
→ filters by preset extensions + size
|
|
373
374
|
↓
|
|
374
375
|
→ LINTING STEP (fast, deterministic)
|
|
375
|
-
→ getLinterToolsForPreset(presetName)
|
|
376
|
-
|
|
376
|
+
→ getLinterToolsForPreset(presetName):
|
|
377
|
+
1. fetchRemoteConfig('formatters.json') → remote presetTools mapping
|
|
378
|
+
2. fallback to local PRESET_LINTERS if remote unavailable
|
|
379
|
+
→ for each tool (formatters first, then linters):
|
|
377
380
|
isToolAvailable() → not found? warn + install hint → skip
|
|
378
381
|
filterFilesByTool() → matching files
|
|
379
382
|
runToolWithAutoFix() → check → auto-fix → re-stage → re-check
|
|
380
|
-
→
|
|
381
|
-
→ if failOnWarning && warnings → exit 1 (COMMIT BLOCKED)
|
|
383
|
+
→ unfixable issues forwarded to judge
|
|
382
384
|
↓
|
|
383
385
|
→ continues to Claude analysis
|
|
384
386
|
```
|
package/README.md
CHANGED
|
@@ -82,6 +82,43 @@ export GITHUB_TOKEN="ghp_..."
|
|
|
82
82
|
|
|
83
83
|
Create token at https://github.com/settings/tokens with scopes: `repo`, `read:org`
|
|
84
84
|
|
|
85
|
+
### Linting & Formatting
|
|
86
|
+
|
|
87
|
+
Runs formatters and linters on staged files automatically during pre-commit, or on demand:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
# Lint staged files (default)
|
|
91
|
+
claude-hooks lint
|
|
92
|
+
|
|
93
|
+
# Lint all files in a directory
|
|
94
|
+
claude-hooks lint src/
|
|
95
|
+
|
|
96
|
+
# Lint specific files
|
|
97
|
+
claude-hooks lint file1.js file2.java
|
|
98
|
+
|
|
99
|
+
# Mix of directories and files
|
|
100
|
+
claude-hooks lint src/ lib/utils/ file.js
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**Tools per preset** (configured via [remote config](https://github.com/mscope-S-L/git-hooks-config)):
|
|
104
|
+
|
|
105
|
+
| Preset | Tools |
|
|
106
|
+
| ----------- | ----------------------------- |
|
|
107
|
+
| `frontend` | Prettier, ESLint |
|
|
108
|
+
| `backend` | Spotless |
|
|
109
|
+
| `fullstack` | Prettier, ESLint, Spotless |
|
|
110
|
+
| `database` | sqlfluff |
|
|
111
|
+
| `ai` | Prettier, ESLint |
|
|
112
|
+
| `default` | Prettier, ESLint |
|
|
113
|
+
|
|
114
|
+
**Behavior:**
|
|
115
|
+
|
|
116
|
+
- Formatters run first (Prettier), then linters (ESLint) — format before lint
|
|
117
|
+
- Auto-fix enabled by default — fixes and re-stages files automatically
|
|
118
|
+
- Missing tools are skipped with install instructions (never blocks)
|
|
119
|
+
- Unfixable issues are forwarded to the Claude judge for semantic resolution
|
|
120
|
+
- Tool-to-preset mapping is fetched from remote config (team-controlled, no release needed)
|
|
121
|
+
|
|
85
122
|
### Analyze Code (Interactive Review)
|
|
86
123
|
|
|
87
124
|
Run interactive code analysis before committing:
|
package/lib/commands/install.js
CHANGED
|
@@ -673,7 +673,7 @@ export async function runInstall(args) {
|
|
|
673
673
|
const presetName = config.preset || 'default';
|
|
674
674
|
if (config.linting?.enabled !== false) {
|
|
675
675
|
const { checkLinterAvailability } = await import('../utils/linter-runner.js');
|
|
676
|
-
checkLinterAvailability(presetName);
|
|
676
|
+
await checkLinterAvailability(presetName);
|
|
677
677
|
}
|
|
678
678
|
} catch {
|
|
679
679
|
// Non-fatal — linter check failure should not block installation
|
package/lib/commands/lint.js
CHANGED
|
@@ -170,7 +170,7 @@ export async function runLint(args = []) {
|
|
|
170
170
|
|
|
171
171
|
info(`🎯 Linting ${filesToLint.length} file(s) with '${metadata.displayName}' preset`);
|
|
172
172
|
|
|
173
|
-
const lintResult = runLinters(filesToLint, config, presetName);
|
|
173
|
+
const lintResult = await runLinters(filesToLint, config, presetName);
|
|
174
174
|
displayLintResults(lintResult);
|
|
175
175
|
|
|
176
176
|
// Exit with error code if linting failed
|
package/lib/hooks/pre-commit.js
CHANGED
|
@@ -152,7 +152,7 @@ const main = async () => {
|
|
|
152
152
|
logger.info('🔍 Running linters...');
|
|
153
153
|
const lintStartTime = Date.now();
|
|
154
154
|
const filePaths = validFiles.map((f) => (typeof f === 'string' ? f : f.path));
|
|
155
|
-
const lintResult = runLinters(filePaths, config, presetName);
|
|
155
|
+
const lintResult = await runLinters(filePaths, config, presetName);
|
|
156
156
|
displayLintResults(lintResult);
|
|
157
157
|
|
|
158
158
|
// Record lint metric
|
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
displayToolResult
|
|
24
24
|
} from './tool-runner.js';
|
|
25
25
|
import { getRepoRoot } from './git-operations.js';
|
|
26
|
+
import { fetchRemoteConfig } from './remote-config.js';
|
|
26
27
|
import logger from './logger.js';
|
|
27
28
|
|
|
28
29
|
/**
|
|
@@ -157,6 +158,46 @@ export function parseSqlfluffOutput(stdout) {
|
|
|
157
158
|
return { errors, warnings };
|
|
158
159
|
}
|
|
159
160
|
|
|
161
|
+
/**
|
|
162
|
+
* Parse Prettier --check output into structured issues
|
|
163
|
+
* Prettier outputs [warn] lines for files that need formatting
|
|
164
|
+
*
|
|
165
|
+
* @param {string} stdout - Prettier --check stdout
|
|
166
|
+
* @returns {{ errors: Array, warnings: Array }}
|
|
167
|
+
*/
|
|
168
|
+
export function parsePrettierOutput(stdout) {
|
|
169
|
+
const errors = [];
|
|
170
|
+
const warnings = [];
|
|
171
|
+
|
|
172
|
+
const lines = stdout.split('\n');
|
|
173
|
+
|
|
174
|
+
for (const line of lines) {
|
|
175
|
+
const trimmed = line.trim();
|
|
176
|
+
|
|
177
|
+
// Match [warn] <filepath> lines — skip summary lines
|
|
178
|
+
const match = trimmed.match(/^\[warn\]\s+(.+)$/);
|
|
179
|
+
if (!match) continue;
|
|
180
|
+
|
|
181
|
+
const content = match[1];
|
|
182
|
+
|
|
183
|
+
// Skip Prettier's summary lines (not file paths)
|
|
184
|
+
if (
|
|
185
|
+
content.includes('Code style issues') ||
|
|
186
|
+
content.includes('Forgot to run Prettier')
|
|
187
|
+
) {
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
errors.push({
|
|
192
|
+
file: content,
|
|
193
|
+
severity: 'error',
|
|
194
|
+
message: 'File is not properly formatted'
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return { errors, warnings };
|
|
199
|
+
}
|
|
200
|
+
|
|
160
201
|
/**
|
|
161
202
|
* Convert file paths to Spotless-compatible regex pattern
|
|
162
203
|
* Spotless -DspotlessFiles accepts a regex matching absolute file paths
|
|
@@ -176,6 +217,25 @@ export function filesToSpotlessRegex(files) {
|
|
|
176
217
|
* @type {Object<string, import('./tool-runner.js').ToolDefinition>}
|
|
177
218
|
*/
|
|
178
219
|
export const LINTER_TOOLS = {
|
|
220
|
+
prettier: {
|
|
221
|
+
name: 'prettier',
|
|
222
|
+
command: 'npx',
|
|
223
|
+
args: (files) => ['prettier', '--check', ...files],
|
|
224
|
+
fixArgs: (files) => ['prettier', '--write', ...files],
|
|
225
|
+
detectCommand: 'prettier',
|
|
226
|
+
detectInProjectFile: {
|
|
227
|
+
filename: 'package.json',
|
|
228
|
+
check: (content) => {
|
|
229
|
+
const pkg = JSON.parse(content);
|
|
230
|
+
const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
231
|
+
return 'prettier' in allDeps;
|
|
232
|
+
}
|
|
233
|
+
},
|
|
234
|
+
installHint: 'npm install --save-dev prettier',
|
|
235
|
+
extensions: ['.js', '.jsx', '.ts', '.tsx', '.css', '.scss', '.html', '.json', '.md', '.yaml', '.yml'],
|
|
236
|
+
parseOutput: parsePrettierOutput,
|
|
237
|
+
timeout: 30000
|
|
238
|
+
},
|
|
179
239
|
eslint: {
|
|
180
240
|
name: 'eslint',
|
|
181
241
|
command: 'npx',
|
|
@@ -228,27 +288,56 @@ export const LINTER_TOOLS = {
|
|
|
228
288
|
};
|
|
229
289
|
|
|
230
290
|
/**
|
|
231
|
-
*
|
|
232
|
-
*
|
|
291
|
+
* Local fallback preset-to-tool mapping
|
|
292
|
+
* Used when remote formatters.json is unavailable
|
|
233
293
|
* @type {Object<string, string[]>}
|
|
234
294
|
*/
|
|
235
295
|
export const PRESET_LINTERS = {
|
|
236
|
-
frontend: ['eslint'],
|
|
296
|
+
frontend: ['prettier', 'eslint'],
|
|
237
297
|
backend: ['spotless'],
|
|
238
|
-
fullstack: ['eslint', 'spotless'],
|
|
298
|
+
fullstack: ['prettier', 'eslint', 'spotless'],
|
|
239
299
|
database: ['sqlfluff'],
|
|
240
|
-
ai: ['eslint'],
|
|
241
|
-
default: ['eslint']
|
|
300
|
+
ai: ['prettier', 'eslint'],
|
|
301
|
+
default: ['prettier', 'eslint']
|
|
242
302
|
};
|
|
243
303
|
|
|
244
304
|
/**
|
|
245
|
-
* Get linter tool definitions for a preset
|
|
305
|
+
* Get linter/formatter tool definitions for a preset.
|
|
306
|
+
* Fetches preset-to-tools mapping from remote config (formatters.json),
|
|
307
|
+
* falls back to local PRESET_LINTERS when remote is unavailable.
|
|
246
308
|
*
|
|
247
309
|
* @param {string} presetName - Preset name
|
|
248
|
-
* @returns {import('./tool-runner.js').ToolDefinition[]} Tool definitions
|
|
310
|
+
* @returns {Promise<import('./tool-runner.js').ToolDefinition[]>} Tool definitions
|
|
249
311
|
*/
|
|
250
|
-
export function getLinterToolsForPreset(presetName) {
|
|
251
|
-
|
|
312
|
+
export async function getLinterToolsForPreset(presetName) {
|
|
313
|
+
// Try remote config first
|
|
314
|
+
const remoteConfig = await fetchRemoteConfig('formatters.json');
|
|
315
|
+
|
|
316
|
+
let toolNames;
|
|
317
|
+
|
|
318
|
+
if (remoteConfig?.presetTools?.[presetName]) {
|
|
319
|
+
toolNames = remoteConfig.presetTools[presetName];
|
|
320
|
+
logger.debug('linter-runner - getLinterToolsForPreset', 'Using remote preset tools', {
|
|
321
|
+
preset: presetName,
|
|
322
|
+
tools: toolNames
|
|
323
|
+
});
|
|
324
|
+
} else if (remoteConfig?.presetTools?.default) {
|
|
325
|
+
toolNames = remoteConfig.presetTools.default;
|
|
326
|
+
logger.debug('linter-runner - getLinterToolsForPreset',
|
|
327
|
+
'Preset not in remote config, using remote default', {
|
|
328
|
+
preset: presetName,
|
|
329
|
+
tools: toolNames
|
|
330
|
+
});
|
|
331
|
+
} else {
|
|
332
|
+
// Fall back to local
|
|
333
|
+
toolNames = PRESET_LINTERS[presetName] || PRESET_LINTERS.default;
|
|
334
|
+
logger.debug('linter-runner - getLinterToolsForPreset', 'Using local fallback', {
|
|
335
|
+
preset: presetName,
|
|
336
|
+
tools: toolNames,
|
|
337
|
+
remoteAvailable: remoteConfig !== null
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
|
|
252
341
|
return toolNames.map((name) => LINTER_TOOLS[name]).filter(Boolean);
|
|
253
342
|
}
|
|
254
343
|
|
|
@@ -260,12 +349,12 @@ export function getLinterToolsForPreset(presetName) {
|
|
|
260
349
|
* @param {string} [presetName] - Preset name (default: 'default')
|
|
261
350
|
* @returns {{ results: ToolRunResult[], totalErrors: number, totalWarnings: number, totalFixed: number }}
|
|
262
351
|
*/
|
|
263
|
-
export function runLinters(files, config, presetName = 'default') {
|
|
352
|
+
export async function runLinters(files, config, presetName = 'default') {
|
|
264
353
|
const lintConfig = config.linting || {};
|
|
265
354
|
const autoFix = lintConfig.autoFix !== false;
|
|
266
355
|
const timeout = lintConfig.timeout || 30000;
|
|
267
356
|
|
|
268
|
-
const tools = getLinterToolsForPreset(presetName);
|
|
357
|
+
const tools = await getLinterToolsForPreset(presetName);
|
|
269
358
|
const results = [];
|
|
270
359
|
|
|
271
360
|
logger.debug('linter-runner - runLinters', 'Starting linters', {
|
|
@@ -415,8 +504,8 @@ export function lintIssuesToAnalysisDetails(lintResult) {
|
|
|
415
504
|
*
|
|
416
505
|
* @param {string} presetName - Preset name
|
|
417
506
|
*/
|
|
418
|
-
export function checkLinterAvailability(presetName) {
|
|
419
|
-
const tools = getLinterToolsForPreset(presetName);
|
|
507
|
+
export async function checkLinterAvailability(presetName) {
|
|
508
|
+
const tools = await getLinterToolsForPreset(presetName);
|
|
420
509
|
|
|
421
510
|
if (tools.length === 0) {
|
|
422
511
|
return;
|
package/package.json
CHANGED
|
@@ -1,69 +1,69 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "claude-git-hooks",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"description": "Git hooks with Claude CLI for code analysis and automatic commit messages",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"bin": {
|
|
7
|
-
"claude-hooks": "./bin/claude-hooks"
|
|
8
|
-
},
|
|
9
|
-
"scripts": {
|
|
10
|
-
"test": "npm run test:all",
|
|
11
|
-
"test:all": "npm run lint && npm run test:smoke && npm run test:unit && npm run test:integration",
|
|
12
|
-
"test:smoke": "node --experimental-vm-modules node_modules/jest/bin/jest.js test/smoke --maxWorkers=1",
|
|
13
|
-
"test:unit": "node --experimental-vm-modules node_modules/jest/bin/jest.js test/unit --forceExit",
|
|
14
|
-
"test:integration": "node --experimental-vm-modules node_modules/jest/bin/jest.js test/integration --maxWorkers=1 --testTimeout=30000 --forceExit",
|
|
15
|
-
"test:integration:ci": "node --experimental-vm-modules node_modules/jest/bin/jest.js test/integration/ci-safe.test.js --maxWorkers=1 --testTimeout=30000 --forceExit",
|
|
16
|
-
"test:changed": "node --experimental-vm-modules node_modules/jest/bin/jest.js test/unit --changedSince=main --forceExit",
|
|
17
|
-
"test:watch": "node --experimental-vm-modules node_modules/jest/bin/jest.js --watch",
|
|
18
|
-
"test:coverage": "node --experimental-vm-modules node_modules/jest/bin/jest.js --coverage",
|
|
19
|
-
"lint": "eslint lib/ bin/claude-hooks",
|
|
20
|
-
"lint:fix": "eslint lib/ bin/claude-hooks --fix",
|
|
21
|
-
"format": "prettier --write \"lib/**/*.js\" \"bin/**\" \"test/**/*.js\"",
|
|
22
|
-
"precommit": "npm run lint && npm run test:smoke",
|
|
23
|
-
"prepublishOnly": "npm run test:all"
|
|
24
|
-
},
|
|
25
|
-
"keywords": [
|
|
26
|
-
"git",
|
|
27
|
-
"hooks",
|
|
28
|
-
"claude",
|
|
29
|
-
"ai",
|
|
30
|
-
"code-review",
|
|
31
|
-
"commit-messages",
|
|
32
|
-
"pre-commit",
|
|
33
|
-
"automation"
|
|
34
|
-
],
|
|
35
|
-
"author": "Pablo Rovito",
|
|
36
|
-
"license": "MIT",
|
|
37
|
-
"repository": {
|
|
38
|
-
"type": "git",
|
|
39
|
-
"url": "https://github.com/mscope-S-L/git-hooks.git"
|
|
40
|
-
},
|
|
41
|
-
"engines": {
|
|
42
|
-
"node": ">=16.9.0"
|
|
43
|
-
},
|
|
44
|
-
"engineStrict": false,
|
|
45
|
-
"os": [
|
|
46
|
-
"darwin",
|
|
47
|
-
"linux",
|
|
48
|
-
"win32"
|
|
49
|
-
],
|
|
50
|
-
"preferGlobal": true,
|
|
51
|
-
"files": [
|
|
52
|
-
"bin/",
|
|
53
|
-
"lib/",
|
|
54
|
-
"templates/",
|
|
55
|
-
"README.md",
|
|
56
|
-
"CHANGELOG.md",
|
|
57
|
-
"CLAUDE.md",
|
|
58
|
-
"LICENSE"
|
|
59
|
-
],
|
|
60
|
-
"dependencies": {
|
|
61
|
-
"@octokit/rest": "^21.0.0"
|
|
62
|
-
},
|
|
63
|
-
"devDependencies": {
|
|
64
|
-
"@types/jest": "^29.5.0",
|
|
65
|
-
"eslint": "^8.57.1",
|
|
66
|
-
"jest": "^29.7.0",
|
|
67
|
-
"prettier": "^3.2.0"
|
|
68
|
-
}
|
|
69
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "claude-git-hooks",
|
|
3
|
+
"version": "2.35.0",
|
|
4
|
+
"description": "Git hooks with Claude CLI for code analysis and automatic commit messages",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"claude-hooks": "./bin/claude-hooks"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"test": "npm run test:all",
|
|
11
|
+
"test:all": "npm run lint && npm run test:smoke && npm run test:unit && npm run test:integration",
|
|
12
|
+
"test:smoke": "node --experimental-vm-modules node_modules/jest/bin/jest.js test/smoke --maxWorkers=1",
|
|
13
|
+
"test:unit": "node --experimental-vm-modules node_modules/jest/bin/jest.js test/unit --forceExit",
|
|
14
|
+
"test:integration": "node --experimental-vm-modules node_modules/jest/bin/jest.js test/integration --maxWorkers=1 --testTimeout=30000 --forceExit",
|
|
15
|
+
"test:integration:ci": "node --experimental-vm-modules node_modules/jest/bin/jest.js test/integration/ci-safe.test.js --maxWorkers=1 --testTimeout=30000 --forceExit",
|
|
16
|
+
"test:changed": "node --experimental-vm-modules node_modules/jest/bin/jest.js test/unit --changedSince=main --forceExit",
|
|
17
|
+
"test:watch": "node --experimental-vm-modules node_modules/jest/bin/jest.js --watch",
|
|
18
|
+
"test:coverage": "node --experimental-vm-modules node_modules/jest/bin/jest.js --coverage",
|
|
19
|
+
"lint": "eslint lib/ bin/claude-hooks",
|
|
20
|
+
"lint:fix": "eslint lib/ bin/claude-hooks --fix",
|
|
21
|
+
"format": "prettier --write \"lib/**/*.js\" \"bin/**\" \"test/**/*.js\"",
|
|
22
|
+
"precommit": "npm run lint && npm run test:smoke",
|
|
23
|
+
"prepublishOnly": "npm run test:all"
|
|
24
|
+
},
|
|
25
|
+
"keywords": [
|
|
26
|
+
"git",
|
|
27
|
+
"hooks",
|
|
28
|
+
"claude",
|
|
29
|
+
"ai",
|
|
30
|
+
"code-review",
|
|
31
|
+
"commit-messages",
|
|
32
|
+
"pre-commit",
|
|
33
|
+
"automation"
|
|
34
|
+
],
|
|
35
|
+
"author": "Pablo Rovito",
|
|
36
|
+
"license": "MIT",
|
|
37
|
+
"repository": {
|
|
38
|
+
"type": "git",
|
|
39
|
+
"url": "https://github.com/mscope-S-L/git-hooks.git"
|
|
40
|
+
},
|
|
41
|
+
"engines": {
|
|
42
|
+
"node": ">=16.9.0"
|
|
43
|
+
},
|
|
44
|
+
"engineStrict": false,
|
|
45
|
+
"os": [
|
|
46
|
+
"darwin",
|
|
47
|
+
"linux",
|
|
48
|
+
"win32"
|
|
49
|
+
],
|
|
50
|
+
"preferGlobal": true,
|
|
51
|
+
"files": [
|
|
52
|
+
"bin/",
|
|
53
|
+
"lib/",
|
|
54
|
+
"templates/",
|
|
55
|
+
"README.md",
|
|
56
|
+
"CHANGELOG.md",
|
|
57
|
+
"CLAUDE.md",
|
|
58
|
+
"LICENSE"
|
|
59
|
+
],
|
|
60
|
+
"dependencies": {
|
|
61
|
+
"@octokit/rest": "^21.0.0"
|
|
62
|
+
},
|
|
63
|
+
"devDependencies": {
|
|
64
|
+
"@types/jest": "^29.5.0",
|
|
65
|
+
"eslint": "^8.57.1",
|
|
66
|
+
"jest": "^29.7.0",
|
|
67
|
+
"prettier": "^3.2.0"
|
|
68
|
+
}
|
|
69
|
+
}
|