[bug] Windows hooks use bare ash and silently resolve to the WSL launcher (no-op)
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 4.8k
- Forks
- 342
- Avg merge
- 13h 48m
- Merged PRs (30d)
- 211
Description
Description
On Windows, the hook command rendered by teamai hooks inject is a bare shell string:
bash -lc "teamai hook-dispatch <event> --tool <tool> 2>/dev/null" || true
Windows CreateProcess resolves a bare bash to %SystemRoot%\System32\bash.exe (the WSL launcher) before any PATH entry. So on Windows the hook actually runs inside WSL, not Git Bash. Inside WSL the user's npm‑global teamai (and often Node ≥ 20) are not present, and the trailing 2>/dev/null || true swallows every error — so the hook fires, appears to succeed, and silently does nothing.
Affected tools: every tool whose hook is rendered as a shell command (Claude Code, Cursor, Qoder, Codex, …).
Not affected: WorkBuddy / CodeBuddy (they use the PATH‑prefix wrapper via getWrapperDispatchCommand) and ZCode (its toZcodeEntry already falls back to cmd /c on win32 for exactly this reason — see the comment in src/hooks.ts). Shell‑string tools just never got the same protection.
Reproduction
- Windows machine with Git for Windows installed and WSL enabled (the default on many dev boxes).
- Run
teamai hooks inject --tool claude(or go through onboarding). - Open the generated settings file and observe the hook command uses a bare
bash -lc "...". - In
cmd, runwhere bash—C:\Windows\System32\bash.exeis returned first (see Logs; on my box Git Bash is not even onPATH). - Trigger a hook event → nothing is recorded. Running the same command manually shows WSL errors that
2>/dev/null || truehides.
Expected behavior
Hook commands resolve to a working Bash on Windows (e.g. Git Bash by absolute path), so dispatch runs and records events instead of silently no‑opping — matching the intent already reflected for ZCode/WorkBuddy.
Environment
- OS: Windows 11 (25H2)
- Node.js: v22.23.2
- teamai CLI version: 0.22.0 (commit 470d229)
- Provider: GitHub
- AI tool: Claude Code / Cursor / Qoder / Codex
Logs
where bash on the affected machine:
C:\Windows\System32\bash.exe
C:\Users\L\AppData\Local\Microsoft\WindowsApps\bash.exe
Both hits are the WSL/Store launcher; there is no Git Bash on PATH, so CreateProcess always lands in WSL and the hook no-ops.
I have a candidate fix (resolve Git Bash by absolute path on win32, quoted + forward slashes so it stays JSON‑safe and tolerates the "Program Files" space; POSIX and the golden fixtures unchanged) and will open a PR referencing this issue.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
The relevant entry points are src/hooks.ts, getWrapperDispatchCommand, and toZcodeEntry; start by comparing existing win32 handling with shell-string hook rendering. Done means Windows-generated commands select a working Git Bash path while POSIX output and golden fixtures remain unchanged; verify via hooks inject and the affected generated settings.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- cli
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100