fix(cua-driver-rs): TTY hint instead of silent stdin hang on bare invocation - #1672
Conversation
…ocation Bare \`cua-driver\` (no subcommand) defaults to MCP mode and reads JSON-RPC from stdin forever. When invoked from an interactive terminal that looks like a hang — users see no output and assume the binary is broken. Add an \`IsTerminal\` check (stable since Rust 1.70): if stdin is a TTY, print a hint listing the common subcommands and exit cleanly. Piped / redirected stdin — the normal MCP client case (Claude Code, Claude Desktop, etc.) — falls through to MCP mode unchanged. Explicit \`cua-driver mcp\` bypasses the check for power users who want to pipe JSON-RPC by hand. Hint goes to stderr to avoid any risk of contaminating an MCP wire, exit code 0 since we're successfully diagnosing the situation.
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThe CLI command parser now distinguishes bare invocation from explicit ChangesCLI bare invocation user guidance
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
Summary
Bare `cua-driver` (no subcommand) defaults to MCP mode and reads JSON-RPC from stdin forever. From an interactive terminal that looks like a hang — users see no output and assume the binary is broken.
This PR adds a stdin-is-a-TTY check. When true, print a one-paragraph hint and exit 0. When stdin is piped/redirected (the normal MCP client case — Claude Code, Claude Desktop, etc.), behaviour is unchanged.
Before
```
PS> cua-driver
```
After
```
PS> cua-driver
cua-driver: bare invocation defaults to the MCP server, which reads
JSON-RPC from stdin. From a terminal that looks like a hang.
You probably meant one of:
cua-driver list-tools # available tools
cua-driver status # check the daemon
cua-driver mcp-config --client claude-code # wire into a client
cua-driver --help # everything else
To run the MCP server explicitly (and pipe JSON-RPC by hand):
cua-driver mcp
PS> $LASTEXITCODE
0
```
Explicit `cua-driver mcp` bypasses the check for power users who want to pipe JSON-RPC by hand.
Implementation
`std::io::IsTerminal` (stable since Rust 1.70) on `stdin()`. Hint to stderr so it never collides with an MCP wire on stdout. Exit 0 since this is a successful diagnosis, not a failure.
Test plan
🤖 Generated with Claude Code
Summary by CodeRabbit
Release Notes
New Features
Bug Fixes