diff --git a/bin/install.js b/bin/install.js index 8a135958d9..23737d5a12 100755 --- a/bin/install.js +++ b/bin/install.js @@ -898,6 +898,9 @@ function cleanupOrphanedFiles(configDir) { const orphanedFiles = [ 'hooks/gsd-notify.sh', // Removed in v1.6.x 'hooks/statusline.js', // Renamed to gsd-statusline.js in v1.9.0 + 'hooks/gsd-check-update.js', // Renamed to .cjs for ES module compat + 'hooks/gsd-statusline.js', // Renamed to .cjs for ES module compat + 'hooks/gsd-context-monitor.js', // Renamed to .cjs for ES module compat ]; for (const relPath of orphanedFiles) { @@ -919,6 +922,9 @@ function cleanupOrphanedHooks(settings) { 'gsd-intel-index.js', // Removed in v1.9.2 'gsd-intel-session.js', // Removed in v1.9.2 'gsd-intel-prune.js', // Removed in v1.9.2 + 'gsd-check-update.js', // Renamed to .cjs for ES module compat + 'gsd-statusline.js', // Renamed to .cjs for ES module compat + 'gsd-context-monitor.js', // Renamed to .cjs for ES module compat ]; let cleanedHooks = false; @@ -951,16 +957,15 @@ function cleanupOrphanedHooks(settings) { console.log(` ${green}✓${reset} Removed orphaned hook registrations`); } - // Fix #330: Update statusLine if it points to old GSD statusline.js path - // Only match the specific old GSD path pattern (hooks/statusline.js), - // not third-party statusline scripts that happen to contain 'statusline.js' + // Fix #330: Update statusLine if it points to old GSD statusline path + // Only match the specific old GSD path pattern, not third-party statusline scripts if (settings.statusLine && settings.statusLine.command && - /hooks[\/\\]statusline\.js/.test(settings.statusLine.command)) { + /hooks[\/\\](statusline|gsd-statusline)\.js/.test(settings.statusLine.command)) { settings.statusLine.command = settings.statusLine.command.replace( - /hooks([\/\\])statusline\.js/, - 'hooks$1gsd-statusline.js' + /hooks([\/\\])(?:gsd-)?statusline\.js/, + 'hooks$1gsd-statusline.cjs' ); - console.log(` ${green}✓${reset} Updated statusline path (hooks/statusline.js → hooks/gsd-statusline.js)`); + console.log(` ${green}✓${reset} Updated statusline path → hooks/gsd-statusline.cjs`); } return settings; @@ -1071,7 +1076,7 @@ function uninstall(isGlobal, runtime = 'claude') { // 4. Remove GSD hooks const hooksDir = path.join(targetDir, 'hooks'); if (fs.existsSync(hooksDir)) { - const gsdHooks = ['gsd-statusline.js', 'gsd-check-update.js', 'gsd-check-update.sh', 'gsd-context-monitor.js']; + const gsdHooks = ['gsd-statusline.cjs', 'gsd-check-update.cjs', 'gsd-context-monitor.cjs', 'gsd-statusline.js', 'gsd-check-update.js', 'gsd-check-update.sh', 'gsd-context-monitor.js']; let hookCount = 0; for (const hook of gsdHooks) { const hookPath = path.join(hooksDir, hook); @@ -1728,8 +1733,8 @@ function install(isGlobal, runtime = 'claude') { 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 - if (entry.endsWith('.js')) { + // Template .js/.cjs files to replace '.claude' with runtime-specific config dir + if (entry.endsWith('.js') || entry.endsWith('.cjs')) { let content = fs.readFileSync(srcFile, 'utf8'); content = content.replace(/'\.claude'/g, configDirReplacement); fs.writeFileSync(destFile, content); @@ -1767,14 +1772,14 @@ function install(isGlobal, runtime = 'claude') { const settingsPath = path.join(targetDir, 'settings.json'); const settings = cleanupOrphanedHooks(readSettings(settingsPath)); const statuslineCommand = isGlobal - ? buildHookCommand(targetDir, 'gsd-statusline.js') - : 'node ' + dirName + '/hooks/gsd-statusline.js'; + ? buildHookCommand(targetDir, 'gsd-statusline.cjs') + : 'node ' + dirName + '/hooks/gsd-statusline.cjs'; const updateCheckCommand = isGlobal - ? buildHookCommand(targetDir, 'gsd-check-update.js') - : 'node ' + dirName + '/hooks/gsd-check-update.js'; + ? buildHookCommand(targetDir, 'gsd-check-update.cjs') + : 'node ' + dirName + '/hooks/gsd-check-update.cjs'; const contextMonitorCommand = isGlobal - ? buildHookCommand(targetDir, 'gsd-context-monitor.js') - : 'node ' + dirName + '/hooks/gsd-context-monitor.js'; + ? buildHookCommand(targetDir, 'gsd-context-monitor.cjs') + : 'node ' + dirName + '/hooks/gsd-context-monitor.cjs'; // Enable experimental agents for Gemini CLI (required for custom sub-agents) if (isGemini) { diff --git a/docs/context-monitor.md b/docs/context-monitor.md index b312bd8340..649d2ca645 100644 --- a/docs/context-monitor.md +++ b/docs/context-monitor.md @@ -31,13 +31,13 @@ To avoid spamming the agent with repeated warnings: ## Architecture ``` -Statusline Hook (gsd-statusline.js) +Statusline Hook (gsd-statusline.cjs) | writes v /tmp/claude-ctx-{session_id}.json ^ reads | -Context Monitor (gsd-context-monitor.js, PostToolUse) +Context Monitor (gsd-context-monitor.cjs, PostToolUse) | injects v additionalContext -> Agent sees warning @@ -71,7 +71,7 @@ Manual registration in `~/.claude/settings.json`: { "statusLine": { "type": "command", - "command": "node ~/.claude/hooks/gsd-statusline.js" + "command": "node ~/.claude/hooks/gsd-statusline.cjs" }, "hooks": { "PostToolUse": [ @@ -79,7 +79,7 @@ Manual registration in `~/.claude/settings.json`: "hooks": [ { "type": "command", - "command": "node ~/.claude/hooks/gsd-context-monitor.js" + "command": "node ~/.claude/hooks/gsd-context-monitor.cjs" } ] } diff --git a/get-shit-done/workflows/update.md b/get-shit-done/workflows/update.md index 3a184500ce..22378316da 100644 --- a/get-shit-done/workflows/update.md +++ b/get-shit-done/workflows/update.md @@ -169,7 +169,7 @@ rm -f ./.claude/cache/gsd-update-check.json rm -f ~/.claude/cache/gsd-update-check.json ``` -The SessionStart hook (`gsd-check-update.js`) always writes to `~/.claude/cache/` via `os.homedir()` regardless of install type, so both paths must be cleared to prevent stale update indicators. +The SessionStart hook (`gsd-check-update.cjs`) always writes to `~/.claude/cache/` via `os.homedir()` regardless of install type, so both paths must be cleared to prevent stale update indicators. diff --git a/hooks/gsd-check-update.js b/hooks/gsd-check-update.cjs similarity index 100% rename from hooks/gsd-check-update.js rename to hooks/gsd-check-update.cjs diff --git a/hooks/gsd-context-monitor.js b/hooks/gsd-context-monitor.cjs similarity index 100% rename from hooks/gsd-context-monitor.js rename to hooks/gsd-context-monitor.cjs diff --git a/hooks/gsd-statusline.js b/hooks/gsd-statusline.cjs similarity index 100% rename from hooks/gsd-statusline.js rename to hooks/gsd-statusline.cjs diff --git a/scripts/build-hooks.js b/scripts/build-hooks.js index ffb60b0ff2..0ede4ba3cf 100644 --- a/scripts/build-hooks.js +++ b/scripts/build-hooks.js @@ -11,9 +11,9 @@ const DIST_DIR = path.join(HOOKS_DIR, 'dist'); // Hooks to copy (pure Node.js, no bundling needed) const HOOKS_TO_COPY = [ - 'gsd-check-update.js', - 'gsd-context-monitor.js', - 'gsd-statusline.js' + 'gsd-check-update.cjs', + 'gsd-context-monitor.cjs', + 'gsd-statusline.cjs' ]; function build() {