From 9b7ce9d8e1e5803063e621190465298750c4c5bf Mon Sep 17 00:00:00 2001 From: Sebastian Geraldes <199673787+sebastiangeraldes@users.noreply.github.com> Date: Sun, 25 Jan 2026 00:57:36 -0300 Subject: [PATCH] fix(windows): Replace bash hook with Node.js for cross-platform support Fixes #354 The SessionStart hook was failing on Windows due to two issues: 1. Path mangling: When CLAUDE_PLUGIN_ROOT (containing Windows backslash paths) is passed through bash command execution, backslashes are interpreted as escape characters and stripped, resulting in invalid paths like "C:UsersSebastian.claude..." instead of "C:\Users\Sebastian\.claude..." 2. Shebang stdout suppression: Git Bash on Windows suppresses stdout when running scripts with shebang lines via `bash script.sh`, causing the hook to produce no output even when it executes successfully. Solution: Replace the bash script with a Node.js equivalent that: - Uses __dirname for reliable cross-platform path resolution - Works identically on Windows, macOS, and Linux - Produces proper JSON output for the Claude Code hook system The original session-start.sh is retained for reference and potential Unix-only use cases. Co-Authored-By: Claude Opus 4.5 --- hooks/hooks.json | 2 +- hooks/session-start.js | 50 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 hooks/session-start.js diff --git a/hooks/hooks.json b/hooks/hooks.json index 17e0ac87b..a088ef604 100644 --- a/hooks/hooks.json +++ b/hooks/hooks.json @@ -6,7 +6,7 @@ "hooks": [ { "type": "command", - "command": "${CLAUDE_PLUGIN_ROOT}/hooks/session-start.sh" + "command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/session-start.js\"" } ] } diff --git a/hooks/session-start.js b/hooks/session-start.js new file mode 100644 index 000000000..efce84a7c --- /dev/null +++ b/hooks/session-start.js @@ -0,0 +1,50 @@ +#!/usr/bin/env node +/** + * SessionStart hook for superpowers plugin + * + * Cross-platform wrapper (Windows, macOS, Linux) that handles: + * - Windows path backslash issues when CLAUDE_PLUGIN_ROOT is passed to bash + * - Git Bash shebang stdout suppression issue on Windows + * + * See: https://github.com/obra/superpowers/issues/354 + */ + +const fs = require('fs'); +const path = require('path'); + +// Determine plugin root from this script's location +const SCRIPT_DIR = __dirname; +const PLUGIN_ROOT = path.dirname(SCRIPT_DIR); + +// Check if legacy skills directory exists +let warningMessage = ''; +const legacySkillsDir = path.join(process.env.HOME || process.env.USERPROFILE || '', '.config', 'superpowers', 'skills'); +if (fs.existsSync(legacySkillsDir)) { + warningMessage = '\n\nIN YOUR FIRST REPLY AFTER SEEING THIS MESSAGE YOU MUST TELL THE USER:⚠️ **WARNING:** Superpowers now uses Claude Code\'s skills system. Custom skills in ~/.config/superpowers/skills will not be read. Move custom skills to ~/.claude/skills instead. To make this message go away, remove ~/.config/superpowers/skills'; +} + +// Read using-superpowers skill content +const skillPath = path.join(PLUGIN_ROOT, 'skills', 'using-superpowers', 'SKILL.md'); +let usingSuperpowersContent = ''; +try { + usingSuperpowersContent = fs.readFileSync(skillPath, 'utf8'); +} catch (err) { + usingSuperpowersContent = 'Error reading using-superpowers skill: ' + err.message; +} + +// Output JSON for Claude Code hook system +const output = { + hookSpecificOutput: { + hookEventName: 'SessionStart', + additionalContext: ` +You have superpowers. + +**Below is the full content of your 'superpowers:using-superpowers' skill - your introduction to using skills. For all other skills, use the 'Skill' tool:** + +${usingSuperpowersContent} +${warningMessage} +` + } +}; + +console.log(JSON.stringify(output, null, 2));