Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 21 additions & 16 deletions bin/install.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand Down
8 changes: 4 additions & 4 deletions docs/context-monitor.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -71,15 +71,15 @@ 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": [
{
"hooks": [
{
"type": "command",
"command": "node ~/.claude/hooks/gsd-context-monitor.js"
"command": "node ~/.claude/hooks/gsd-context-monitor.cjs"
}
]
}
Expand Down
2 changes: 1 addition & 1 deletion get-shit-done/workflows/update.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
</step>

<step name="display_result">
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
6 changes: 3 additions & 3 deletions scripts/build-hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down