Skip to content

Fix Windows statusLine hook never firing under Git Bash#68

Merged
aqua5230 merged 1 commit into
mainfrom
agent/windows-claude-statusline-not-firing
Jul 15, 2026
Merged

Fix Windows statusLine hook never firing under Git Bash#68
aqua5230 merged 1 commit into
mainfrom
agent/windows-claude-statusline-not-firing

Conversation

@aqua5230

Copy link
Copy Markdown
Owner

Summary

  • On Windows, Claude Code runs statusLine commands through Git Bash when it's installed. Backslashes are escape characters there, so the backslash-separated python.exe/script paths setup_hook.py wrote into ~/.claude/settings.json's statusLine.command silently failed to launch — ~/.claude/usage-status.json was never produced, and the app's Claude usage card had nothing to show.
  • _shell_arg now emits forward-slash paths on Windows (valid for both Git Bash and PowerShell). Existing installs are migrated automatically on the next self-heal pass or --setup run.
  • doctor.py gained a status command: line that flags any remaining un-migrated backslash command, to make this diagnosable without reading source.
  • Fixes a latent bug this exposed in _resume_restore_context (session_hooks.py): it classified the installed resume-hook command by comparing against str(Path) (backslash form), so on Windows that classification silently degraded to registered=other once the command itself switched to forward slashes. Now compares against .as_posix().
  • Bilingual CHANGELOG.md / CHANGELOG.zh-TW.md entries added under Unreleased.

Test plan

  • ruff check — clean
  • mypy . — clean
  • pytest -v — 699 passed, 2 skipped (pre-existing, environment-specific)
  • New tests cover the migration function and doctor's backslash detection, via monkeypatch only — no real ~/.claude/ access
  • Root cause confirmed by manually invoking the installed hook script directly (it ran fine — the bug was in the command Claude Code invokes, not the script itself)
  • Found and fixed 5 pre-existing test assertions (in test_setup_hook_resume.py, test_setup_hook_terse.py, test_setup_hook_coexistence.py) that compared against the old backslash path format and broke once the fix legitimately changed the emitted command format

🤖 Generated with Claude Code

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8d0526c859

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread setup_hook.py
Comment on lines +141 to 142
value = value.replace("\\", "/")
return subprocess.list2cmdline([value])

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Quote Windows commands for the shell

When Claude Code invokes this through Git Bash, subprocess.list2cmdline is still Windows argv quoting, not shell quoting: it leaves Bash metacharacters unescaped, so a valid path like C:\Users\R&D\.claude\usage-statusline.py becomes C:/Users/R&D/... and Bash treats & as a control operator before the hook runs. The statusLine docs say the command field runs in a shell, so after making the command Bash-compatible with forward slashes this also needs shell-safe quoting for Windows paths with characters such as &, $, or parentheses.

Useful? React with 👍 / 👎.

Comment thread setup_hook.py
Comment on lines +168 to +171
if "usage-statusline-forwarder" in command:
new_command = _forwarder_command()
elif "usage-statusline" in command:
new_command = _statusline_command()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Migrate companion hook commands too

For Windows users who already enabled Resume or Terse mode before upgrading, the existing hooks.SessionStart/UserPromptSubmit commands were written by the old _shell_arg with backslash paths, but this migration only rewrites statusLine. Claude hooks are shell commands as well, so those opt-in hooks continue to fail under Git Bash until the user manually disables and re-enables them; self-heal should also rewrite usage-owned usage_session_resume, usage_terse_mode, and reminder hook commands.

Useful? React with 👍 / 👎.

Claude Code runs Windows statusLine commands through Git Bash when it
is installed, where backslashes are escape characters — so the
backslash-separated python.exe/script paths setup_hook.py wrote there
silently failed to launch, and usage-status.json was never produced.

_shell_arg now emits forward-slash paths on Windows (valid for both
Git Bash and PowerShell). Existing installs are migrated automatically
by self-heal and --setup. doctor.py's new "status command" line flags
any remaining un-migrated backslash command.

Also fixes a latent bug this exposed in
_resume_restore_context: it compared the resume hook's installed
command against str(Path) (backslash form) to classify whether the
command still points at the source or target script, so on Windows
that classification silently degraded to "other" once the command
itself switched to forward slashes. Compares against as_posix() now.
@aqua5230 aqua5230 force-pushed the agent/windows-claude-statusline-not-firing branch from 8d0526c to 25e9d26 Compare July 15, 2026 20:51
@aqua5230 aqua5230 merged commit 16e8260 into main Jul 15, 2026
5 checks passed
@aqua5230 aqua5230 deleted the agent/windows-claude-statusline-not-firing branch July 15, 2026 20:58
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.

1 participant