Fix: Resolve orphaned processes and keyboard input issues (#422, #423, #424)#458
Open
hyacz wants to merge 1 commit intoslopus:mainfrom
Open
Fix: Resolve orphaned processes and keyboard input issues (#422, #423, #424)#458hyacz wants to merge 1 commit intoslopus:mainfrom
hyacz wants to merge 1 commit intoslopus:mainfrom
Conversation
…slopus#423, slopus#424) **Issue slopus#422 & slopus#424: Orphaned Claude Code Processes** ✅ FIXED - Problem: Local → Remote switching left Claude Code child processes running as orphans - Orphaned processes continued to read from stdin, blocking subsequent input - Multiple Claude Code processes competing for stdin Solution: - Remove signal: opts.abort from child spawn options - Add HAPPY_SESSION_ID environment variable for process tracking - Implement pkill-based cleanup (SIGTERM → SIGKILL) in claudeLocal.ts - Add signal handlers in claude_local_launcher.cjs **Issue slopus#423: Terminal input stuck after exit** ✅ FIXED - Problem: Terminal raw mode not restored after exit, input became stuck - Root cause: Manual setRawMode(true) calls bypassed Ink's cleanup Solution: - Remove manual process.stdin.setRawMode() calls from claudeRemoteLauncher.ts - Let Ink handle all stdin management via stdin.ref()/unref() - Ink properly restores terminal state on cleanup **Additional Issue: Second Remote Keyboard Input** ✅ FIXED - Problem: Second Remote mode fails to receive keyboard input - Root cause: Orphaned processes (from slopus#422/slopus#424) modify terminal driver state Solution: - Force raw mode toggle in RemoteModeDisplay component mount - Wait 100ms for Ink to complete setup - Toggle: setRawMode(false) → setRawMode(true) with 10ms delay - Simplify stdin management in claudeRemoteLauncher.ts **Testing:** - Remote → Local → Remote keyboard input works correctly - No orphaned Claude processes after mode switches - Terminal state properly restored on exit - Multiple mode switches work reliably **Note:** Preserved all existing logger.debug() calls that were in commit 8691991. Only removed manual stdin management that was causing issues. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
ryuan-cw
approved these changes
Jan 24, 2026
8 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes Issue #422, #423, and #424 (all related to process and terminal management issues during mode switches).
Issue #422: "Bug: Input handler persists after remote-to-local mode switch" ✅
Problem: Input handler persists after switching from Local → Remote, with orphaned processes continuing to read from stdin and blocking subsequent input.
Root Cause: Child processes spawned with
signal: opts.abortwere not properly terminated when the parent process exited during Local → Remote switches.Solution:
signal: opts.abortfrom spawn optionsHAPPY_SESSION_IDenvironment variable to track process groupsclaudeLocal.ts(SIGTERM → SIGKILL)claude_local_launcher.cjsIssue #424: "After switching back to local mode, the input is starting to getting incomplete." ✅
Problem: After switching back to local mode, input is incomplete due to orphaned processes competing for stdin.
Root Cause: Same as Issue #422 - orphaned processes from Local mode continue reading from stdin.
Solution: Same fixes as Issue #422.
Issue #423: "Terminal input stuck after exit (raw mode not restored)" ✅
Problem: After exiting happy-cli (via Ctrl+C or normal exit), the terminal input becomes stuck at whitespace. Users need to run
stty saneorresetto restore normal terminal behavior.Root Cause: Manual
process.stdin.setRawMode(true)calls bypassed Ink's cleanup mechanism. When SIGINT/SIGTERM was caught,process.exit(0)terminated immediately, skipping thefinallyblock that should restore terminal state.Solution:
process.stdin.setRawMode()calls fromclaudeRemoteLauncher.tsstdin.ref()/unref()Additional Issue: Second Remote Fails to Receive Keyboard Input ✅
Problem: First Remote worked correctly, but after Local → Remote → Local → Remote, the second Remote's keyboard input was buffered (cooked mode behavior).
Root Cause: Orphaned processes (Issues #422/#424) from Local mode modify terminal driver state through
stdio: 'inherit'. When Ink callsprocess.stdin.setRawMode(true), the terminal driver doesn't actually enter raw mode.Solution:
RemoteModeDisplay.tsxcomponent mountsetRawMode(false)→setRawMode(true)with 10ms delayclaudeRemoteLauncher.ts(let Ink handle everything)Test Plan
ps aux | grep -i claude)stty sane)Files Changed
src/ui/ink/RemoteModeDisplay.tsx- Raw mode toggle fixsrc/claude/claudeRemoteLauncher.ts- Simplified stdin management, removed manual setRawModesrc/claude/claudeLocal.ts- Process cleanup logicscripts/claude_local_launcher.cjs- Signal handlersscripts/claude_version_utils.cjs- Session ID trackingNote: All existing
logger.debug()calls from commit 8691991 have been preserved. Only manual stdin management that was causing issues has been removed.🤖 Generated with Claude Code