Skip to content
Merged
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
9 changes: 9 additions & 0 deletions .claude/hooks/notify.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Add-Type -AssemblyName System.Windows.Forms
$n = New-Object System.Windows.Forms.NotifyIcon
$n.Icon = [System.Drawing.SystemIcons]::Information
$n.Visible = $true
$n.BalloonTipTitle = "Claude Code"
$n.BalloonTipText = "Awaiting your input"
$n.ShowBalloonTip(5000)
Start-Sleep -Milliseconds 5100
$n.Dispose()
19 changes: 19 additions & 0 deletions .claude/hooks/notify.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/usr/bin/env python3
import os
import platform
import subprocess

system = platform.system()
script_dir = os.path.dirname(os.path.abspath(__file__))

if system == "Darwin":
subprocess.run([
"osascript", "-e",
'display notification "Awaiting your input" with title "Claude Code"'
])
elif system == "Windows":
ps1_path = os.path.join(script_dir, "notify.ps1")
subprocess.run([
"powershell", "-NoProfile", "-ExecutionPolicy", "Bypass",
"-File", ps1_path
])
4 changes: 2 additions & 2 deletions .claude/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"hooks": [
{
"type": "command",
"command": "osascript -e 'display notification \"Awaiting your input\" with title \"Claude Code\"'"
"command": "python3 .claude/hooks/notify.py 2>/dev/null || python .claude/hooks/notify.py"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🌐 Web query:

Claude Code Cursor IDE hook execution Windows shell compatibility

💡 Result:

On Windows, Claude Code hooks execute exactly the command string you configure (they’re “user-defined shell commands”). The official hooks guide even provides Windows examples that explicitly invoke powershell.exe -Command ..., which is the most reliable pattern on Windows shells. (docs.claude.com)

Why .sh hooks often fail in Cursor/Windows

If your hook is configured like this:

{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/session-start.sh" }

…Claude Code may open the .sh file in VS Code/Cursor instead of executing it on Windows (a reported Windows bug/behavior). (github.com)

Practical Windows-compatible fixes

  1. Call PowerShell directly (recommended for native Windows):
{ "type": "command", "command": "powershell.exe -NoProfile -ExecutionPolicy Bypass -File \"C:\\path\\to\\hook.ps1\"" }

(Or inline -Command "..." as shown in the docs.) (docs.claude.com)

  1. If you want to keep .sh, invoke Bash explicitly (Git Bash or WSL), don’t execute the .sh path bare:
  • Claude Code on native Windows commonly relies on Git for Windows’ bash.exe, and you may need to set:
    • CLAUDE_CODE_GIT_BASH_PATH="C:\Program Files\Git\bin\bash.exe" (docs.claude.com)
  • Then configure the hook like (example):
{
  "type": "command",
  "command": "\"C:\\Program Files\\Git\\bin\\bash.exe\" -lc \"${CLAUDE_PLUGIN_ROOT}/hooks/session-start.sh\""
}

Cursor IDE note

If something works in standalone CMD/PowerShell but not in Cursor’s integrated terminal, it’s often because the integrated terminal doesn’t inherit the same environment (so variables like CLAUDE_CODE_GIT_BASH_PATH may not be visible there). (reddit.com)

Citations:


🌐 Web query:

Cursor IDE .claude/hooks configuration Windows cmd.exe PowerShell

💡 Result:

Where to configure hooks (Cursor / Claude Code)

Claude Code hooks are read from these JSON files (user- or project-scoped): ~/.claude/settings.json, .claude/settings.json, or .claude/settings.local.json. (docs.anthropic.com)
They run shell commands, receiving event context as JSON on stdin. (docs.anthropic.com)
After editing hooks, Claude Code takes a startup snapshot; changes typically require review via the /hooks menu to apply. (docs.anthropic.com)

On Windows, ~ maps to your home directory (typically C:\Users\<you>), so user settings are usually:

  • C:\Users\<you>\.claude\settings.json

PowerShell hook (recommended on Windows)

1) Put a script somewhere, e.g.

  • Project: <repo>\.claude\hooks\my-hook.ps1

Example my-hook.ps1 (reads stdin JSON):

# .claude/hooks/my-hook.ps1
$inputJson = [Console]::In.ReadToEnd() | ConvertFrom-Json
# Example: log tool + command
$tool = $inputJson.tool_name
$cmd  = $inputJson.tool_input.command
"[$(Get-Date -Format o)] $tool :: $cmd" | Out-File -Append -FilePath "$env:CLAUDE_PROJECT_DIR\.claude\hook.log" -Encoding utf8

exit 0

2) Reference it from .claude/settings.json

Use $CLAUDE_PROJECT_DIR so it works regardless of current working directory. (docs.anthropic.com)

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "powershell.exe -NoProfile -ExecutionPolicy Bypass -File \"\\\"$CLAUDE_PROJECT_DIR\\\"\\.claude\\hooks\\my-hook.ps1\""
          }
        ]
      }
    ]
  }
}

(That quoting pattern is important if your project path contains spaces, per the docs’ guidance to quote $CLAUDE_PROJECT_DIR.) (docs.anthropic.com)


cmd.exe hook (if you really want cmd)

You can call cmd.exe /d /s /c ..., but handling stdin JSON in pure batch is awkward, so the common pattern is: cmd.exe → call powershell.exe anyway.

Example:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "cmd.exe /d /s /c \"powershell.exe -NoProfile -ExecutionPolicy Bypass -File \\\"%CLAUDE_PROJECT_DIR%\\.claude\\hooks\\my-hook.ps1\\\"\""
          }
        ]
      }
    ]
  }
}

If you tell me which hook event you’re targeting (PreToolUse, PostToolUse, PermissionRequest, etc.) and what you want to do (block commands, log, run formatters/tests), I can provide a ready-to-paste config + script for that specific case.

Citations:


🏁 Script executed:

# Check if this is a Cursor/Claude Code project and look for any shell configuration
find . -name ".cursor*" -o -name ".claude*" -type d 2>/dev/null | head -20
git ls-files | grep -E "(settings|config|hooks)" | head -20

Repository: solid-connection/solid-connect-server

Length of output: 1476


🏁 Script executed:

# Look for documentation about hook execution
find . -name "*.md" -o -name "*.txt" | xargs grep -l "hook\|shell\|execute" 2>/dev/null | head -10

Repository: solid-connection/solid-connect-server

Length of output: 63


🏁 Script executed:

cat -n ./.claude/settings.json

Repository: solid-connection/solid-connect-server

Length of output: 904


🏁 Script executed:

cat -n ./.claude/hooks/notify.ps1

Repository: solid-connection/solid-connect-server

Length of output: 451


Windows에서 작동하지 않는 유닉스 셸 문법 수정 필요

현재 .claude/settings.json의 훅 명령어가 Windows 호환성 목표와 맞지 않습니다. 공식 Claude Code 문서에 따르면, Windows에서는 2>/dev/null, || 같은 유닉스 셸 문법이 작동하지 않습니다. 프로젝트에 이미 PowerShell 버전(notify.ps1)이 있음에도 불구하고, 현재 설정은 그것을 사용하고 있지 않습니다.

수정이 필요한 항목:

  1. Notification 훅 (12행)

    • 현재: python3 .claude/hooks/notify.py 2>/dev/null || python .claude/hooks/notify.py
    • 문제: Unix 셸 리다이렉션(2>/dev/null)과 논리 연산자(||) 불가
    • 해결: PowerShell을 명시적으로 호출하도록 변경 필요
  2. PostToolUse 훅 (23행)

    • 현재: python3 .claude/hooks/post-edit-check.py 2>/dev/null || python .claude/hooks/post-edit-check.py
    • 문제: 동일한 유닉스 셸 문법 사용
    • 해결: 크로스플랫폼 호환 명령어로 변경 필요

두 훅 모두 공식 권장사항(PowerShell 명시적 호출)에 따라 수정하면 Windows에서도 안정적으로 작동합니다. 저장소에 이미 있는 notify.ps1 같은 리소스를 활용하여 완전한 Windows 지원을 갖출 수 있습니다.

🤖 Prompt for AI Agents
In @.claude/settings.json at line 12, Update the two hook command strings in
.claude/settings.json to remove Unix-only shell syntax and explicitly invoke
PowerShell on Windows: replace the Notification hook command that references
notify.py and the PostToolUse hook command that references post-edit-check.py so
they no longer use "2>/dev/null" or "||"; instead call PowerShell to run the
corresponding .ps1 scripts (use the existing .claude/hooks/notify.ps1 or a
post-edit-check PowerShell script if present) and fall back to the Python script
when PowerShell is not available, ensuring the JSON "command" values for those
hooks (the Notification and PostToolUse entries) are cross-platform and
Windows-compatible.

}
]
}
Expand All @@ -20,7 +20,7 @@
"hooks": [
{
"type": "command",
"command": "python3 .claude/hooks/post-edit-check.py"
"command": "python3 .claude/hooks/post-edit-check.py 2>/dev/null || python .claude/hooks/post-edit-check.py"
}
]
}
Expand Down
Loading