fix(#2557): Gemini/Antigravity local hook commands use relative paths, not \$CLAUDE_PROJECT_DIR (#2589)

\$CLAUDE_PROJECT_DIR is Claude Code-specific. Gemini CLI doesn't set it, and on
Windows its path-join logic doubled the value producing unresolvable paths like
D:\Projects\GSD\'D:\Projects\GSD'. Gemini runs project hooks with project root
as cwd, so bare relative paths (e.g. node .gemini/hooks/gsd-check-update.js)
are cross-platform and correct. Claude Code and others still use the env var.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Tom Boucher
2026-04-22 12:04:06 -04:00
committed by GitHub
parent 7032f44633
commit fba040c72c
3 changed files with 86 additions and 6 deletions

View File

@@ -6075,9 +6075,13 @@ function install(isGlobal, runtime = 'claude') {
return;
}
const settings = validateHookFields(cleanupOrphanedHooks(rawSettings));
// Local installs anchor paths to $CLAUDE_PROJECT_DIR so hooks resolve
// correctly regardless of the shell's current working directory (#1906).
const localPrefix = '"$CLAUDE_PROJECT_DIR"/' + dirName;
// Local installs anchor hook paths so they resolve regardless of cwd (#1906).
// Claude Code sets $CLAUDE_PROJECT_DIR; Gemini/Antigravity do not — and on
// Windows their own substitution logic doubles the path (#2557). Those runtimes
// run project hooks with the project dir as cwd, so bare relative paths work.
const localPrefix = (runtime === 'gemini' || runtime === 'antigravity')
? dirName
: '"$CLAUDE_PROJECT_DIR"/' + dirName;
const hookOpts = { portableHooks: hasPortableHooks };
const statuslineCommand = isGlobal
? buildHookCommand(targetDir, 'gsd-statusline.js', hookOpts)