claude-git-hooks 2.6.0 → 2.6.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 +21 -0
- package/lib/utils/claude-client.js +19 -2
- package/lib/utils/which-command.js +23 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,27 @@ 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.6.1] - 2025-12-04
|
|
9
|
+
|
|
10
|
+
### 🐛 Fixed
|
|
11
|
+
|
|
12
|
+
- **Windows spawn ENOENT errors** - Fixed critical issue where Claude CLI failed to execute on Windows with npm-installed tools
|
|
13
|
+
- **What was broken**: `spawn()` cannot execute `.cmd`/`.bat` files directly on Windows, causing `ENOENT` errors
|
|
14
|
+
- **Root cause**: npm on Windows creates both `claude` (non-executable) and `claude.cmd` (executable), and system was selecting the wrong one
|
|
15
|
+
- **Fix 1**: `which-command.js` now prefers `.cmd`/`.bat` extensions over extensionless entries when multiple matches found
|
|
16
|
+
- **Fix 2**: `claude-client.js` wraps `.cmd`/`.bat` commands with `cmd.exe /c` before spawning
|
|
17
|
+
- **Files changed**:
|
|
18
|
+
- `lib/utils/which-command.js:135-163` - Prefer `.cmd`/`.bat` in Windows path resolution
|
|
19
|
+
- `lib/utils/claude-client.js:165-179` - Wrap batch files with cmd.exe
|
|
20
|
+
- **Impact**: Fixes `analyze-diff` and commit hooks for Windows users with npm-installed Claude CLI
|
|
21
|
+
- **Compatibility**: No impact on Linux/macOS or Windows WSL setups, only affects Windows native npm installations
|
|
22
|
+
|
|
23
|
+
### 🎯 User Experience
|
|
24
|
+
|
|
25
|
+
- **Before**: Windows users with npm-installed Claude CLI got `ENOENT` errors on every command
|
|
26
|
+
- **After**: Commands work seamlessly, same as other platforms
|
|
27
|
+
- **Debug**: Added detailed logging for Windows .cmd file detection and wrapping
|
|
28
|
+
|
|
8
29
|
## [2.6.0] - 2025-12-02
|
|
9
30
|
|
|
10
31
|
### ✨ Added - Node.js 24 Compatibility
|
|
@@ -162,7 +162,23 @@ const executeClaude = (prompt, { timeout = 120000, allowedTools = [] } = {}) =>
|
|
|
162
162
|
finalArgs.push('--allowedTools', allowedTools.join(','));
|
|
163
163
|
}
|
|
164
164
|
|
|
165
|
-
|
|
165
|
+
// CRITICAL FIX: Windows .cmd/.bat file handling
|
|
166
|
+
// Why: spawn() cannot execute .cmd/.bat files directly on Windows (ENOENT error)
|
|
167
|
+
// Solution: Wrap with cmd.exe /c when command ends with .cmd or .bat
|
|
168
|
+
// Impact: Only affects Windows npm-installed CLI tools, no impact on other platforms
|
|
169
|
+
let spawnCommand = command;
|
|
170
|
+
let spawnArgs = finalArgs;
|
|
171
|
+
|
|
172
|
+
if (isWindows() && (command.endsWith('.cmd') || command.endsWith('.bat'))) {
|
|
173
|
+
logger.debug('claude-client - executeClaude', 'Wrapping .cmd/.bat with cmd.exe', {
|
|
174
|
+
originalCommand: command,
|
|
175
|
+
originalArgs: finalArgs
|
|
176
|
+
});
|
|
177
|
+
spawnCommand = 'cmd.exe';
|
|
178
|
+
spawnArgs = ['/c', command, ...finalArgs];
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const fullCommand = spawnArgs.length > 0 ? `${spawnCommand} ${spawnArgs.join(' ')}` : spawnCommand;
|
|
166
182
|
|
|
167
183
|
logger.debug(
|
|
168
184
|
'claude-client - executeClaude',
|
|
@@ -176,7 +192,8 @@ const executeClaude = (prompt, { timeout = 120000, allowedTools = [] } = {}) =>
|
|
|
176
192
|
// spawn streams data, exec buffers everything in memory
|
|
177
193
|
// Node 24 Fix: Removed shell: true to avoid DEP0190 deprecation warning
|
|
178
194
|
// We now use absolute paths from which(), so shell is not needed
|
|
179
|
-
|
|
195
|
+
// Windows .cmd/.bat fix: Wrapped with cmd.exe /c (see above)
|
|
196
|
+
const claude = spawn(spawnCommand, spawnArgs, {
|
|
180
197
|
stdio: ['pipe', 'pipe', 'pipe'] // stdin, stdout, stderr
|
|
181
198
|
});
|
|
182
199
|
|
|
@@ -132,12 +132,32 @@ const whichViaCommand = (command) => {
|
|
|
132
132
|
timeout: 3000 // Don't wait forever
|
|
133
133
|
});
|
|
134
134
|
|
|
135
|
-
// Windows 'where' returns multiple matches
|
|
136
|
-
const
|
|
135
|
+
// Windows 'where' returns multiple matches
|
|
136
|
+
const matches = result.split('\n').map(line => line.trim()).filter(line => line.length > 0);
|
|
137
|
+
|
|
138
|
+
// CRITICAL FIX: On Windows, prefer .cmd/.bat over extensionless entries
|
|
139
|
+
// Why: npm creates both 'claude' and 'claude.cmd', but only .cmd is executable via spawn()
|
|
140
|
+
// Example: where claude returns:
|
|
141
|
+
// 1. C:\Users\...\npm\claude (NOT executable)
|
|
142
|
+
// 2. C:\Users\...\npm\claude.cmd (executable)
|
|
143
|
+
if (isWin && matches.length > 1) {
|
|
144
|
+
const cmdMatch = matches.find(m => m.endsWith('.cmd') || m.endsWith('.bat'));
|
|
145
|
+
if (cmdMatch) {
|
|
146
|
+
logger.debug('which-command - whichViaCommand', 'Preferring .cmd/.bat over extensionless', {
|
|
147
|
+
command,
|
|
148
|
+
preferred: cmdMatch,
|
|
149
|
+
allMatches: matches
|
|
150
|
+
});
|
|
151
|
+
return cmdMatch;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const firstMatch = matches[0];
|
|
137
156
|
|
|
138
157
|
logger.debug('which-command - whichViaCommand', 'Found via command', {
|
|
139
158
|
command,
|
|
140
|
-
path: firstMatch
|
|
159
|
+
path: firstMatch,
|
|
160
|
+
totalMatches: matches.length
|
|
141
161
|
});
|
|
142
162
|
|
|
143
163
|
return firstMatch;
|