Skip to content

Conversation

@danshapiro
Copy link

@danshapiro danshapiro commented Dec 1, 2025

Summary

  • Adds cross-platform Node.js implementation of session-start hook
  • Fixes Windows path handling issue where backslashes were being stripped
  • Node.js is guaranteed available since Claude Code runs on Node.js

Problem

On Windows, the bash-based session-start.sh hook fails with:

/bin/bash:C:Usersdan.claudepluginscachesuperpowers/hooks/session-start.sh: No such file or directory

Root cause: ${CLAUDE_PLUGIN_ROOT} expands to Windows paths with backslashes (e.g., C:\Users\dan\...). When passed through shell command parsing, backslashes are interpreted as escape characters and stripped, resulting in malformed paths like C:Usersdan....

Solution

Added session-start.js - a Node.js implementation that:

  • Uses path.join() for proper cross-platform path handling
  • Has identical functionality to the bash version
  • Properly reads SKILL.md and checks for legacy skills directory
  • Outputs the same JSON structure for hook injection

Test plan

  • Tested on Windows with Git Bash environment
  • Hook executes without errors
  • Skill context properly injected at session start
  • Verified skills are accessible after startup

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Session initialization now displays relevant skill documentation and contextual guidance upon startup.
  • Chores

    • Updated internal hook execution mechanism for improved performance.
    • Added legacy configuration detection and notification.

✏️ Tip: You can customize this high-level summary in your review settings.

The bash-based session-start hook fails on Windows because:
1. ${CLAUDE_PLUGIN_ROOT} expands to Windows paths with backslashes
2. When passed through shell command parsing, backslashes are
   interpreted as escape characters and stripped
3. Result: malformed path like C:Usersdan... instead of C:\Users\dan\...

This adds a cross-platform Node.js implementation of the session-start
hook. Since Claude Code runs on Node.js, node is guaranteed to be
available on all platforms where the plugin runs.

The Node.js script:
- Uses path.join() for proper cross-platform path handling
- Has identical functionality to the bash version
- Properly reads SKILL.md and checks for legacy skills directory
- Outputs the same JSON structure for hook injection

Tested on Windows with Git Bash environment - hook now executes
without errors and properly injects skill context.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@coderabbitai
Copy link

coderabbitai bot commented Dec 1, 2025

Walkthrough

The PR replaces the SessionStart hook from executing a shell script (session-start.sh) to a Node.js script (session-start.js). The new script checks for legacy skills directories, loads skill documentation, constructs JSON metadata, and outputs the result with hook context and optional warnings.

Changes

Cohort / File(s) Summary
Hook configuration
hooks/hooks.json
Updated SessionStart hook command to execute Node.js script instead of shell script
Hook implementation
hooks/session-start.js
New Node.js script that checks for legacy skills directory, reads skill documentation, constructs JSON output with hook metadata and skill content

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10–15 minutes

  • Hook configuration update is straightforward (single path change)
  • New script contains basic logic: filesystem checks, synchronous file reading, error embedding, and JSON serialization
  • No complex async operations, control flow, or edge case handling

Possibly related PRs

Poem

🐰 A hook once wore a shell so bright,
Now dressed in Node.js, what a sight!
With skills to load and warnings to share,
JSON flows forth through the plugin-root air! ✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding a Node.js implementation to fix Windows compatibility for the SessionStart hook.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1b878e4 and 4b737c7.

📒 Files selected for processing (2)
  • hooks/hooks.json (1 hunks)
  • hooks/session-start.js (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
hooks/session-start.js (1)
.opencode/plugin/superpowers.js (1)
  • __dirname (15-15)
🔇 Additional comments (3)
hooks/hooks.json (1)

8-10: Command switch to Node looks correct and fixes Windows path escaping.

Using node "${CLAUDE_PLUGIN_ROOT}/hooks/session-start.js" with quotes should avoid the earlier backslash‑escaping problems on Windows while keeping behavior identical on other platforms. No further changes needed here.

hooks/session-start.js (2)

1-12: Verify Node module type (ESM vs CommonJS) for this script.

This file is written as CommonJS (require, __dirname). If your plugin/package is configured with "type": "module" (which is common when other files use import/import.meta.url), Node will treat .js files as ES modules and require / __dirname will be unavailable, causing the hook command to fail at runtime.

Two ways to avoid that, depending on how the rest of the repo is set up:

  • Keep this as CommonJS:

    • Rename the file to session-start.cjs and point hooks.json at that path, or
    • Place it in a directory governed by a package.json with "type": "commonjs".
  • Or convert it to ESM to match a "type": "module" package, e.g.:

-#!/usr/bin/env node
-// SessionStart hook for superpowers plugin
-// Cross-platform Node.js implementation (works on Windows, macOS, Linux)
-
-const fs = require('fs');
-const path = require('path');
-const os = require('os');
-
-// Determine plugin root directory
-const SCRIPT_DIR = __dirname;
-const PLUGIN_ROOT = path.dirname(SCRIPT_DIR);
+#!/usr/bin/env node
+// SessionStart hook for superpowers plugin
+// Cross-platform Node.js implementation (works on Windows, macOS, Linux)
+
+import fs from 'node:fs';
+import path from 'node:path';
+import os from 'node:os';
+import { fileURLToPath } from 'node:url';
+
+// Determine plugin root directory
+const SCRIPT_DIR = path.dirname(fileURLToPath(import.meta.url));
+const PLUGIN_ROOT = path.dirname(SCRIPT_DIR);

Please double‑check how Node is resolving modules for this plugin and adjust accordingly so the hook runs reliably in all environments.


13-45: Hook behavior and JSON output shape look consistent and robust.

  • Legacy skills warning: fs.existsSync against ~/.config/superpowers/skills and injecting a clearly demarcated <important-reminder> block into additionalContext is straightforward and low‑risk.
  • Skill content: building skillPath from PLUGIN_ROOT with path.join and falling back to an inline error string on read failure gives predictable behavior even when SKILL.md is missing.
  • Output: hookSpecificOutput.hookEventName = 'SessionStart' and the additionalContext template (with the inlined skill content and optional warning) matches the described contract, and JSON.stringify(output, null, 2) is appropriate for a hook that writes to stdout.

I don’t see any functional issues with this logic; once the module‑type concern above is addressed/confirmed, this implementation should behave as intended across platforms.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@obra
Copy link
Owner

obra commented Dec 2, 2025

Thanks for working on this! We've just released v3.6.0 which includes Windows hook support via a polyglot wrapper approach.

Could you try updating the plugin and let us know if it resolves your Windows issues?

/plugin update superpowers@superpowers-marketplace

The new approach uses a .cmd wrapper that works on both Windows CMD and Unix bash, calling Git for Windows' bash.exe to run the actual hook scripts.

If this works for you, we can close this PR. If you're still seeing issues, please let us know!

@obra obra closed this Dec 2, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants