Skip to content

fix(cua-driver-rs): TTY hint instead of silent stdin hang on bare invocation - #1672

Merged
f-trycua merged 1 commit into
mainfrom
mcp-tty-hint
May 24, 2026
Merged

fix(cua-driver-rs): TTY hint instead of silent stdin hang on bare invocation#1672
f-trycua merged 1 commit into
mainfrom
mcp-tty-hint

Conversation

@f-trycua

@f-trycua f-trycua commented May 24, 2026

Copy link
Copy Markdown
Collaborator

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

  • Build clean on Windows (`cargo build --release -p cua-driver` — 0 warnings)
  • `cargo test -p cua-driver` — 49/49 pass
  • `cua-driver --version` still works
  • `cua-driver list-tools` still works
  • Reviewer: confirm hint appears when run bare from a real terminal on macOS / Linux
  • Reviewer: confirm piped invocation (e.g. `echo '{...}' | cua-driver`) still enters MCP loop

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features

    • Added helpful guidance message when running the CLI with no arguments in an interactive terminal, explaining the default MCP server behavior and listing available subcommands.
  • Bug Fixes

    • Improved CLI experience to reduce confusion from apparent hangs when running in interactive mode by providing clear instructions.

Review Change Stack

…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.
@vercel

vercel Bot commented May 24, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Ignored Ignored May 24, 2026 9:46am

Request Review

@coderabbitai

coderabbitai Bot commented May 24, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7e251dd9-3700-4d23-a427-033679d83cdf

📥 Commits

Reviewing files that changed from the base of the PR and between 7436ba8 and d7616cd.

📒 Files selected for processing (1)
  • libs/cua-driver-rs/crates/cua-driver/src/cli.rs

📝 Walkthrough

Walkthrough

The CLI command parser now distinguishes bare invocation from explicit mcp subcommand entry. When invoked with no subcommand and stdin is a TTY, it prints guidance explaining JSON-RPC reading behavior and recommended alternatives, then exits. Non-TTY stdin and explicit MCP subcommand both proceed to MCP mode unchanged.

Changes

CLI bare invocation user guidance

Layer / File(s) Summary
TTY-aware bare invocation dispatch
libs/cua-driver-rs/crates/cua-driver/src/cli.rs
Bare cua-driver invocation now detects whether stdin is a terminal and, if so, prints guidance about default JSON-RPC reading and exits; non-TTY stdin falls through to MCP mode, while explicit cua-driver mcp subcommand behavior is unchanged.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • trycua/cua#1580: Both PRs modify cua-driver's MCP command dispatch flow where this PR improves bare invocation UX and the retrieved PR changes daemon-proxy vs in-process MCP behavior on Windows/Linux.

Poem

A rabbit hops bare through the shell today,
"Hold on," it chirps with codes on display,
"JSON-RPC flows through stdin's great stream—
Try --help or subcommands to scheme!" 🐰✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main change: adding a TTY hint to prevent the appearance of a silent hang when bare invoking cua-driver, replacing the previous silent stdin hang behavior.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ 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 mcp-tty-hint

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.

@f-trycua
f-trycua merged commit 386004b into main May 24, 2026
5 checks passed
@f-trycua
f-trycua deleted the mcp-tty-hint branch May 24, 2026 10:00
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