Skip to content

fix(ssh): detect shell prompt before injecting remote init commands#1327

Merged
arnestrickmann merged 3 commits intogeneralaction:mainfrom
jschwxrz:emdash/fix-ssh-prompt-race-780
Mar 6, 2026
Merged

fix(ssh): detect shell prompt before injecting remote init commands#1327
arnestrickmann merged 3 commits intogeneralaction:mainfrom
jschwxrz:emdash/fix-ssh-prompt-race-780

Conversation

@jschwxrz
Copy link
Collaborator

@jschwxrz jschwxrz commented Mar 6, 2026

summary:

  • ssh remote sessions write setup commands (cd, export, agent launch) immediately after connecting, racing with login banner output
  • commands get garbled or lost on hosts with slow shell init causing agent startup failures

fix:

  • added waitForShellPrompt utility that watches PTY output for prompt patterns before writing, with a 15s timeout fallback
  • applied to both pty:start and pty:startDirect remote paths in ptyIpc and the ssh2 path in RemotePtyService

limits:

  • prompt detection operates per-chunk, not across chunks, a prompt split across TCP segments relies on the timeout fallback
  • in the regex could theoretically match non-prompt output, but the timeout makes this a non-issue in practice

fixes #1326
fixes #1289

@vercel
Copy link

vercel bot commented Mar 6, 2026

@jschwxrz is attempting to deploy a commit to the General Action Team on Vercel.

A member of the Team first needs to authorize it.

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Mar 6, 2026

Greptile Summary

This PR fixes a race condition where SSH init commands (cd, export, agent launch) were written to the PTY immediately after connecting, racing with login-banner output. The fix introduces waitForShellPrompt — a utility that subscribes to PTY output, strips ANSI codes, and uses a regex to detect common prompt endings before writing, with a 15-second timeout fallback. The utility is integrated into all three remote-session paths: pty:start and pty:startDirect in ptyIpc, and the ssh2 path in RemotePtyService.

The implementation is sound:

  • The prompt-detection regex matches all common shells ($, #, %, >, ❯)
  • ANSI code stripping handles CSI sequences and BEL-terminated OSC sequences
  • Tests are thorough, covering prompt variants, ANSI handling, timeout fallback, idempotency, and cleanup
  • Integration with both ptyIpc and RemotePtyService follows consistent patterns
  • Lifecycle management with handle tracking and cancellation works correctly
  • The timeout fallback ensures commands are eventually written even if prompt detection fails

Confidence Score: 5/5

  • This PR is safe to merge. The prompt-detection utility is well-designed, thoroughly tested, and correctly integrated with a fallback timeout that handles edge cases.
  • The implementation correctly addresses the reported issue of SSH init commands racing with banner output. The waitForShellPrompt utility uses a robust approach with prompt-pattern matching, ANSI stripping, and a 15-second timeout fallback. All test cases pass, including edge cases for MOTD content, multiple chunks, cancellation, and cleanup. The integration into both ptyIpc and RemotePtyService follows idiomatic Node.js patterns for stream event handling.
  • No files require special attention.

Last reviewed commit: 74cb886

@arnestrickmann arnestrickmann merged commit e86c53e into generalaction:main Mar 6, 2026
3 of 4 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.

[bug]: SSH prompt race condition fix(ssh): remote PTY keystroke injection races with SSH MOTD

2 participants