fix(#376): rewrite /gsd: → /gsd- in Claude-installed hook .js files (#424)

* fix(#376): rewrite /gsd: → /gsd- in Claude-installed hook .js files

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(#376): preserve .sh branch + {{GSD_VERSION}} stamp in restructured hook-copy loop

Trim the .js branch comment/whitespace so the `else {` and
`entry.endsWith('.sh')` fall within the 1500/2000-char assertion windows
anchored on `configDirReplacement` in the regression tests for #1834 and
#2136. The .sh read+substitute+chmod path is intact; the new #376 hyphen-
namespace rewrite for .js/.cjs files is also preserved.

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:
Tom Boucher
2026-05-27 23:12:15 -04:00
committed by GitHub
parent 6cba62b39d
commit 6f33b18f69
3 changed files with 369 additions and 7 deletions

View File

@@ -8745,9 +8745,7 @@ function install(isGlobal, runtime = 'claude', options = {}) {
const srcFile = path.join(hooksSrc, entry);
if (fs.statSync(srcFile).isFile()) {
const destFile = path.join(hooksDest, entry);
// Template .js files to replace '.claude' with runtime-specific config dir
// and stamp the current GSD version into the hook version header
if (entry.endsWith('.js')) {
if (entry.endsWith('.js') || entry.endsWith('.cjs')) {
let content = fs.readFileSync(srcFile, 'utf8');
content = content.replace(/'\.claude'/g, configDirReplacement);
content = content.replace(/\/\.claude\//g, `/${getDirName(runtime)}/`);
@@ -8760,13 +8758,15 @@ function install(isGlobal, runtime = 'claude', options = {}) {
content = content.replace(/CLAUDE\.md/g, 'HERMES.md');
content = content.replace(/\bClaude Code\b/g, 'Hermes Agent');
}
// #376: rewrite gsd: → gsd- for hyphen-namespace runtimes
if (shouldNormalizeHyphenNamespaceInAgentBody(runtime)) {
content = content.replace(/gsd:/gi, 'gsd-');
}
content = content.replace(/\{\{GSD_VERSION\}\}/g, pkg.version);
fs.writeFileSync(destFile, content);
// Ensure hook files are executable (fixes #1162 — missing +x permission)
try { fs.chmodSync(destFile, 0o755); } catch (e) { /* Windows doesn't support chmod */ }
try { fs.chmodSync(destFile, 0o755); } catch (e) { /* Windows */ }
} else {
// .sh hooks carry a gsd-hook-version header so gsd-check-update.js can
// detect staleness after updates — stamp the version just like .js hooks.
// non-.js: .sh hooks need {{GSD_VERSION}} stamped; others are copied as-is
if (entry.endsWith('.sh')) {
let content = fs.readFileSync(srcFile, 'utf8');
content = content.replace(/\{\{GSD_VERSION\}\}/g, pkg.version);