garrytan / garrytan/gstack

SessionStart hook 'gstack-session-update' triggers Windows 'Select an app' popup every session

Open
#1,775 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
133k
Forks
19.9k
Avg merge
18h 46m
Merged PRs (30d)
26

Description

### Summary

On Windows, the `SessionStart` hook command emitted by gstack setup points directly at the bare shebang script `gstack-session-update` (no extension). Claude Code's Windows hook runner cannot honor the `#!/usr/bin/env bash` shebang, so the OS falls back to ShellExecute and pops the "Select an app to open 'gstack-session-update'" dialog on every Claude Code session start.

Net effect for the user: a modal Windows file-association dialog appears every time a session starts, the script never runs, and auto-upgrade silently fails.

### Environment

- OS: Windows 11
- gstack: v1.48.0.0 (`~/.claude/skills/gstack/VERSION`)
- Install type: global-git at `~/.claude/skills/gstack`
- `auto_upgrade: true`, `update_check: true`
- Shell: Git Bash (`bash` resolves to `/usr/bin/bash` on PATH)
- Claude Code (with `superpowers` and `elements-of-style` plugins active)

### Reproduce

1. Install gstack on Windows
2. Enable auto-upgrade (`gstack-config set auto_upgrade true`) — or choose "Always keep me up to date" when prompted by any skill preamble
3. Setup writes the following block to `~/.claude/settings.json`:

```json
"hooks": {
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "C:/Users/jeffr/.claude/skills/gstack/bin/gstack-session-update"
}
]
}
]
}
```

4. Start a new Claude Code session

### Expected

`gstack-session-update` runs silently, throttle-checks, and forks the auto-upgrade in the background. No UI.

### Actual

Windows pops:

> **Select an app to open 'gstack-session-update'**
> [Adobe Acrobat] [Audacity] [Cursor] [Firefox] [GIMP] [Microsoft Visual Studio Version Selector] [Notepad] ...
> [ Just once ]

Dismissing it lets the session continue, but the script never executed. Auto-upgrade is effectively disabled on Windows until the hook is fixed.

### Diagnosis

`gstack-session-update` is an extensionless bash script. Claude Code on Windows invokes hook commands via the OS shell, which doesn't process Unix shebangs. With no `.cmd` / `.bat` / `.ps1` / `.sh` extension and no registered handler for extensionless executables, Windows falls through to the file-association picker.

### Workaround (verified)

Edit `~/.claude/settings.json` to wrap the hook command in `bash`:

```json
"command": "bash C:/Users/jeffr/.claude/skills/gstack/bin/gstack-session-update"
```

This routes the script through Git Bash explicitly. Popup goes away, auto-upgrade resumes working. No change needed to the script itself.

### Suggested fixes (pick what fits)

- **A) Setup writes a platform-aware hook command.** On Windows, register the hook as `bash ` (or `"C:/Program Files/Git/bin/bash.exe" `). On macOS/Linux, register the bare script path as today. Single change in whatever code writes the SessionStart hook block in `~/.claude/settings.json`.
- **B) Ship a `.cmd` wrapper.** Create `gstack-session-update.cmd` alongside the bash script; it does `@bash "%~dp0gstack-session-update" %*`. Register the `.cmd` on Windows so Windows can launch it natively. Slightly more code but more robust if `bash` ever isn't on PATH.
- **C) Rename the script to `gstack-session-update.sh`.** Add an association hint, register `.sh` → bash. Cleanest if other tooling already handles `.sh` on Windows; risks breaking the existing convention of extensionless `bin/` scripts.

(A) feels lowest-risk and ships fastest. Happy to PR if you'd like — say the word and I'll target whichever branch you prefer.

### Severity

Low for the broader install base, but a hard block on Windows users who turn on `auto_upgrade`. Manual `/gstack-upgrade` still works fine.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.