Summary
On Windows, the bundled installer creates only a codegraph.cmd launcher (%LOCALAPPDATA%\codegraph\current\bin\codegraph.cmd). Git Bash — which is what Claude Code on Windows uses both for its Bash tool and for hook execution — does not do PATHEXT resolution, so the extensionless command codegraph is unresolvable there:
$ codegraph --version
bash: codegraph: command not found # exit 127
$ codegraph.cmd --version
1.4.1 # the .cmd itself works fine from bash
This breaks two things out of the box:
- The installer's own UserPromptSubmit hook.
codegraph install --target=claude writes "command": "codegraph prompt-hook" into ~/.claude/settings.json. Claude Code runs hook commands through Git Bash on Windows, so every prompt submission shows a UserPromptSubmit hook error banner (exit 127) and the context injection never happens.
- Agent CLI usage. Any agent following the "use
codegraph explore before grep/read" instructions fails with command not found when its shell tool is Git Bash, and typically falls back to grep/read loops (silently losing the token savings).
PowerShell and cmd.exe are unaffected (they resolve codegraph.cmd via PATHEXT).
Environment
- codegraph 1.4.1, bundled installer (
%LOCALAPPDATA%\codegraph\current)
- Windows 11 Home 10.0.26200
- Claude Code CLI (hooks + Bash tool run under Git Bash /
/usr/bin/bash)
Reproduction
- Install codegraph on Windows via the bundled installer,
codegraph install --target=claude.
- Open Git Bash (or let Claude Code run any hook):
echo '{"prompt":"test"}' | codegraph prompt-hook
- →
bash: codegraph: command not found, exit 127. In Claude Code, this surfaces as a UserPromptSubmit hook error on every prompt.
Suggested fix
Ship an extensionless POSIX sh launcher next to codegraph.cmd, the same way npm does (npm + npm.cmd side by side in the same bin dir):
#!/bin/sh
basedir=$(dirname "$(readlink -f "$0" 2>/dev/null || echo "$0")")
exec "$basedir/../node.exe" --liftoff-only "$basedir/../lib/dist/bin/codegraph.js" "$@"
With both launchers present, codegraph resolves in every shell (bash picks the sh script, cmd/PowerShell pick the .cmd), and the installed hook command can stay extensionless.
Workaround (current)
A user-level shim on PATH, e.g. ~/.local/bin/codegraph:
#!/bin/sh
exec codegraph.cmd "$@"
Works, but every Windows + Git Bash user has to discover exit 127 in the hook banner and hand-build this — and codegraph upgrade rewriting the hook entry can't know about it.
Summary
On Windows, the bundled installer creates only a
codegraph.cmdlauncher (%LOCALAPPDATA%\codegraph\current\bin\codegraph.cmd). Git Bash — which is what Claude Code on Windows uses both for its Bash tool and for hook execution — does not do PATHEXT resolution, so the extensionless commandcodegraphis unresolvable there:This breaks two things out of the box:
codegraph install --target=claudewrites"command": "codegraph prompt-hook"into~/.claude/settings.json. Claude Code runs hook commands through Git Bash on Windows, so every prompt submission shows aUserPromptSubmit hook errorbanner (exit 127) and the context injection never happens.codegraph explorebefore grep/read" instructions fails withcommand not foundwhen its shell tool is Git Bash, and typically falls back to grep/read loops (silently losing the token savings).PowerShell and cmd.exe are unaffected (they resolve
codegraph.cmdvia PATHEXT).Environment
%LOCALAPPDATA%\codegraph\current)/usr/bin/bash)Reproduction
codegraph install --target=claude.echo '{"prompt":"test"}' | codegraph prompt-hookbash: codegraph: command not found, exit 127. In Claude Code, this surfaces as aUserPromptSubmit hook erroron every prompt.Suggested fix
Ship an extensionless POSIX sh launcher next to
codegraph.cmd, the same way npm does (npm+npm.cmdside by side in the same bin dir):With both launchers present,
codegraphresolves in every shell (bash picks the sh script, cmd/PowerShell pick the.cmd), and the installed hook command can stay extensionless.Workaround (current)
A user-level shim on PATH, e.g.
~/.local/bin/codegraph:Works, but every Windows + Git Bash user has to discover exit 127 in the hook banner and hand-build this — and
codegraph upgraderewriting the hook entry can't know about it.