Skip to content

fix: prevent Windows SessionEnd hook hang (#76)#77

Merged
yyiilluu merged 2 commits into
mainfrom
fix/issue-76-windows-sessionend-hang
Jun 15, 2026
Merged

fix: prevent Windows SessionEnd hook hang (#76)#77
yyiilluu merged 2 commits into
mainfrom
fix/issue-76-windows-sessionend-hang

Conversation

@yyiilluu

@yyiilluu yyiilluu commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Fixes Windows detached hook spawning so background services cannot keep Claude Code hook stdout/stderr pipes open.
  • Bounds login-shell PATH lookup globally so slow or stuck shell startup cannot hang hook_entry.sh or service hooks.
  • Skips expensive login-shell PATH lookup for backend/dashboard session-end no-op hooks.
  • Preserves explicit log redirection for detached installer/dashboard recovery spawns while still closing hook-runner pipes by default.
  • Adds regression coverage for Windows pipe detachment, bounded login-shell lookup, SessionEnd login-shell avoidance, and log-preserving detached spawns.

Test Plan

  • git diff --check
  • bash -n plugin/scripts/_lib.sh plugin/scripts/hook_entry.sh plugin/scripts/backend-service.sh plugin/scripts/dashboard-service.sh plugin/scripts/smart-install.sh
  • uv run --project plugin pytest tests/test_install_scripts.py -q
  • uv run --project plugin pytest tests/test_install_scripts.py::test_windows_detached_spawn_closes_hook_output_pipes tests/test_install_scripts.py::test_login_shell_path_lookup_is_bounded tests/test_install_scripts.py::test_detached_spawns_with_log_redirection_preserve_output_on_windows tests/test_install_scripts.py::test_session_end_service_hooks_skip_login_shell_path_lookup tests/test_install_scripts.py::test_service_start_scripts_recover_missing_dependencies_without_cli_command -q

Fixes #76

Summary by CodeRabbit

Release Notes

  • Chores

    • Improved login-shell PATH capture with a bounded timeout to prevent long waits.
    • Enhanced Windows behavior for detached background processes by suppressing unwanted stdout/stderr output unless output is explicitly kept.
    • Updated service startup logic to avoid unnecessary environment setup for session-end.
    • Adjusted Windows recovery/installer and dashboard spawns to preserve output when configured.
  • Tests

    • Added regression tests covering Windows detached output redirection and session-end environment setup skipping.
    • Added a timeout-focused test to ensure PATH capture does not hang on slow shells.

@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 3b379740-3a42-4de2-91a8-36da5f03171e

📥 Commits

Reviewing files that changed from the base of the PR and between bbe73fb and 1d8e1a0.

📒 Files selected for processing (5)
  • plugin/scripts/_lib.sh
  • plugin/scripts/backend-service.sh
  • plugin/scripts/dashboard-service.sh
  • plugin/scripts/hook_entry.sh
  • tests/test_install_scripts.py

📝 Walkthrough

Walkthrough

Fixes for Windows CLI hang via three mechanisms: bounded timeout on login shell PATH capture (prevents indefinite shell startup waits), redirected stdout/stderr on Windows detached spawns (prevents background processes from keeping hook pipes alive), and skipped login path lookup in session-end hooks (avoids timeout on fast shutdown paths). Consistent CLAUDE_SMART_SPAWN_KEEP_OUTPUT environment variable propagated across all service spawn invocations. Recovery hint output refactored from heredoc to printf format. Four new regression tests validate timeout bounding, Windows pipe detachment, session-end guards, and output control propagation.

Changes

Windows Hook Hang and Timeout Fixes

Layer / File(s) Summary
Bounded login shell PATH capture with timeout
plugin/scripts/_lib.sh, tests/test_install_scripts.py
New claude_smart_login_path_timeout_seconds() and claude_smart_capture_login_path() helpers capture login shell PATH by backgrounding $SHELL -lc and reading from temp file with configurable timeout, preventing indefinite waits. claude_smart_source_login_path() refactored to use this capture routine. Test verifies timeout deadline is respected and slow results are not exposed.
Windows detached spawn stdout/stderr redirection
plugin/scripts/_lib.sh, tests/test_install_scripts.py
Windows branch of claude_smart_spawn_detached() adds > /dev/null 2>&1 to nohup invocation (controlled by CLAUDE_SMART_SPAWN_KEEP_OUTPUT), closing stdout and stderr so background processes no longer inherit hook runner pipes. Test asserts exact redirection string and keep-output gating.
Skip login shell PATH lookup for session-end
plugin/scripts/backend-service.sh, plugin/scripts/dashboard-service.sh, tests/test_install_scripts.py
Both service scripts parse CMD before environment initialization. When CMD is session-end, claude_smart_source_login_path() (and other setup calls in backend) are skipped entirely, avoiding slow login shell startup that exceeds the 10-second session-end timeout on Windows. Test asserts the CMD != "session-end" guard block in both scripts.
Consistent CLAUDE_SMART_SPAWN_KEEP_OUTPUT across service spawns
plugin/scripts/backend-service.sh, plugin/scripts/dashboard-service.sh, plugin/scripts/hook_entry.sh, tests/test_install_scripts.py
All detached spawns (smart-install.sh recovery, dashboard-build.sh, npm run start, hook bootstrap recovery) now set CLAUDE_SMART_SPAWN_KEEP_OUTPUT=1 in their environment, ensuring consistent output control across all service spawn invocations. Test verifies the environment variable is present across hook entry and both service scripts.
Refactor node recovery hint output to printf
plugin/scripts/_lib.sh
claude_smart_node_recovery_hint() replaces heredoc cat blocks with printf statements for conditional OS-specific messages (Windows, Darwin, other), while preserving identical output and recovery instruction text.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • ReflexioAI/claude-smart#9: Modifies the same claude_smart_spawn_detached() Windows nohup path and detached spawn infrastructure in _lib.sh.
  • ReflexioAI/claude-smart#61: Updates the same backend and dashboard service bootstrapping flows to propagate environment variables through detached spawns.

Poem

🐇 A shell-login hung for seconds on end,
While pipes stayed alive, with no hook to fend,
We bounded the timeout, we closed every file,
And skipped the whole PATH lookup for session-end's trial.
Now Claude hops along with a zip and a bound,
No more Windows hang — safe ground all around! 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix: prevent Windows SessionEnd hook hang (#76)' clearly and specifically describes the main objective of the PR: fixing a Windows SessionEnd hook hang issue linked to #76.
Linked Issues check ✅ Passed The PR addresses all three root causes identified in #76: (1) Windows detached process pipes now redirect stdout/stderr to /dev/null, (2) session-end hooks skip unnecessary claude_smart_source_login_path() calls, and (3) test coverage validates both behaviors.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing the three identified problems in #76: Windows process detachment, login path optimization for session-end hooks, and corresponding test coverage.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/issue-76-windows-sessionend-hang

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@yyiilluu yyiilluu merged commit 777e2ee into main Jun 15, 2026
7 checks passed
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.

Plugin hangs Claude Code CLI indefinitely on Windows (SessionEnd hooks)

1 participant