fix(install): extend buildHookCommand to .sh hooks — absolute quoted paths (#2049)
* fix(autonomous): add Agent to allowed-tools in gsd-autonomous skill Closes #2043 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(install): extend buildHookCommand to .sh hooks — absolute quoted paths - Extend buildHookCommand() to branch on .sh suffix, using 'bash' runner instead of 'node', so all hook paths go through the same quoted-path construction: bash "/absolute/path/hooks/gsd-*.sh" - Replace three manual 'bash ' + targetDir + '...' concatenations for gsd-validate-commit.sh, gsd-session-state.sh, gsd-phase-boundary.sh with buildHookCommand(targetDir, hookName) for the global-install branch - Global .sh hook paths are now double-quoted, fixing invocation failure when the config dir path contains spaces (Windows usernames, #2045) - Adds regression tests in tests/sh-hook-paths.test.cjs Closes #2045 Closes #2046 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -443,7 +443,13 @@ function expandTilde(filePath) {
|
||||
function buildHookCommand(configDir, hookName) {
|
||||
// Use forward slashes for Node.js compatibility on all platforms
|
||||
const hooksPath = configDir.replace(/\\/g, '/') + '/hooks/' + hookName;
|
||||
return `node "${hooksPath}"`;
|
||||
// .sh hooks use bash; .js hooks use node. Both wrap the path in double quotes
|
||||
// so that paths with spaces (e.g. Windows "C:/Users/First Last/") work correctly
|
||||
// (fixes #2045). Routing .sh hooks through this function also ensures they always
|
||||
// receive an absolute path rather than the bare relative string that the old manual
|
||||
// concatenation produced (fixes #2046).
|
||||
const runner = hookName.endsWith('.sh') ? 'bash' : 'node';
|
||||
return `${runner} "${hooksPath}"`;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -6038,7 +6044,7 @@ function install(isGlobal, runtime = 'claude') {
|
||||
|
||||
// Configure commit validation hook (Conventional Commits enforcement, opt-in)
|
||||
const validateCommitCommand = isGlobal
|
||||
? 'bash ' + targetDir.replace(/\\/g, '/') + '/hooks/gsd-validate-commit.sh'
|
||||
? buildHookCommand(targetDir, 'gsd-validate-commit.sh')
|
||||
: 'bash ' + localPrefix + '/hooks/gsd-validate-commit.sh';
|
||||
const hasValidateCommitHook = settings.hooks[preToolEvent].some(entry =>
|
||||
entry.hooks && entry.hooks.some(h => h.command && h.command.includes('gsd-validate-commit'))
|
||||
@@ -6065,7 +6071,7 @@ function install(isGlobal, runtime = 'claude') {
|
||||
|
||||
// Configure session state orientation hook (opt-in)
|
||||
const sessionStateCommand = isGlobal
|
||||
? 'bash ' + targetDir.replace(/\\/g, '/') + '/hooks/gsd-session-state.sh'
|
||||
? buildHookCommand(targetDir, 'gsd-session-state.sh')
|
||||
: 'bash ' + localPrefix + '/hooks/gsd-session-state.sh';
|
||||
const hasSessionStateHook = settings.hooks.SessionStart.some(entry =>
|
||||
entry.hooks && entry.hooks.some(h => h.command && h.command.includes('gsd-session-state'))
|
||||
@@ -6087,7 +6093,7 @@ function install(isGlobal, runtime = 'claude') {
|
||||
|
||||
// Configure phase boundary detection hook (opt-in)
|
||||
const phaseBoundaryCommand = isGlobal
|
||||
? 'bash ' + targetDir.replace(/\\/g, '/') + '/hooks/gsd-phase-boundary.sh'
|
||||
? buildHookCommand(targetDir, 'gsd-phase-boundary.sh')
|
||||
: 'bash ' + localPrefix + '/hooks/gsd-phase-boundary.sh';
|
||||
const hasPhaseBoundaryHook = settings.hooks[postToolEvent].some(entry =>
|
||||
entry.hooks && entry.hooks.some(h => h.command && h.command.includes('gsd-phase-boundary'))
|
||||
|
||||
Reference in New Issue
Block a user