Skip to content

feat: Add interactive prompts for missing required arguments - #97

Open
rts1-godaddy wants to merge 3 commits into
mainfrom
feat/generalized-interactivity
Open

feat: Add interactive prompts for missing required arguments#97
rts1-godaddy wants to merge 3 commits into
mainfrom
feat/generalized-interactivity

Conversation

@rts1-godaddy

Copy link
Copy Markdown
Collaborator

Summary

  • When a user runs a command and forgets a required argument, instead of showing a clap error, the CLI now prompts them interactively, as long as they are in a real terminal. Scripts, CI, and piped commands still get the existing error behavior unchanged.

Test plan

  • cargo fmt --all --check
  • cargo clippy --all-targets -- -D warnings
  • cargo test --all-targets

Manual verification

Setup:

# In the cli repo, temporarily override the engine dependency:
cd cli/rust
# Edit Cargo.toml → cli-engine = { features = ["pkce-auth"], path = "../../cli-engine" }
cargo build --release && cp target/release/gddy ~/.local/bin/gddy

Test WITHOUT the fix (baseline):

cd cli-engine && git checkout main
cd cli/rust && cargo build --release && cp target/release/gddy ~/.local/bin/gddy

## you shouldn't see any flags
gddy --help | grep interactive

Test WITH the fix:

cd cli-engine && git checkout <this-branch>
cd cli/rust && cargo build --release && cp target/release/gddy ~/.local/bin/gddy

## You should see the interactive flag description
gddy --help | grep interactive


## this command requires a domain name but its missing. 
## This should show an interactive message for missing arg
./target/debug/gddy domain available   

? Domain name to check (e.g. example.com) 

Cleanup:

# Revert cli/rust/Cargo.toml back to:
# cli-engine = { features = ["pkce-auth"], version = "<published-version>" }

@rts1-godaddy
rts1-godaddy requested a lite review from Copilot August 18, 2026 13:04
@rts1-godaddy rts1-godaddy changed the title Generalized interactivity for missing required arguments [feat]: Generalized interactivity for missing required arguments Aug 18, 2026
@rts1-godaddy rts1-godaddy changed the title [feat]: Generalized interactivity for missing required arguments feat: Generalized interactivity for missing required arguments Aug 18, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a generalized “interactivity” mode to cli-engine so that missing required arguments can be recovered via interactive prompts in real terminals, while preserving existing clap error behavior for non-interactive contexts (CI/scripts/piped runs).

Changes:

  • Introduces global interactivity detection + --interactive / --non-interactive flags, and threads the resulting mode through middleware and CommandContext.
  • Adds an interactive recovery path in Cli::run for MissingRequiredArgument errors, backed by a new prompt module (using inquire).
  • Adds unit/integration tests and updates public API coverage tests to account for the new interactive flag field.

Reviewed changes

Copilot reviewed 10 out of 11 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
cli-engine/tests/interactivity.rs New integration tests covering non-interactive error paths and flag conflict behavior.
cli-engine/tests/foundation.rs Updates expected GlobalFlags defaults to include interactive.
cli-engine/tests/exhaustive_public_api.rs Updates public API parsing expectations for new interactive field.
cli-engine/src/prompt.rs New prompt helpers + missing-required-arg recovery logic and unit tests.
cli-engine/src/middleware.rs Adds interactive to middleware snapshot state.
cli-engine/src/lib.rs Exposes prompt module and re-exports interactivity-related APIs.
cli-engine/src/flags.rs Adds interactivity detection, mode enum, and global flags; parses interactive into GlobalFlags.
cli-engine/src/command.rs Adds CommandContext accessors for interactivity.
cli-engine/src/cli.rs Hooks recovery into clap parse error handling and applies interactive to middleware.
cli-engine/Cargo.toml Adds inquire dependency for interactive prompts.
Cargo.lock Locks new transitive dependencies introduced by inquire.
Suppressed comments (2)

cli-engine/src/prompt.rs:130

  • The doc comment says user cancellation returns None, but the function actually returns Some(RecoveryResult::Cancelled { .. }) on cancel. This mismatch makes it easy for callers to handle cancellation incorrectly.
/// Returns `None` if recovery is not possible (non-interactive, not a missing
/// arg error, or the user cancelled a prompt).

cli-engine/src/prompt.rs:426

  • This test intends to validate the "non-interactive suppresses recovery" path, but the constructed clap Command does not define --non-interactive, so the error kind is UnknownArgument rather than MissingRequiredArgument. As written, it doesn't meaningfully cover the interactivity check.
        let cmd =
            clap::Command::new("test").arg(clap::Arg::new("name").long("name").required(true));
        let err = cmd
            .try_get_matches_from(["test", "--non-interactive"])
            .expect_err("should fail");

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread cli-engine/src/flags.rs
Comment thread cli-engine/src/prompt.rs
Comment thread cli-engine/src/prompt.rs
@rts1-godaddy rts1-godaddy changed the title feat: Generalized interactivity for missing required arguments feat: Add interactive prompts for missing required arguments Aug 18, 2026
@rts1-godaddy
rts1-godaddy marked this pull request as ready for review August 18, 2026 13:49
Comment thread cli-engine/src/flags.rs Outdated
Comment thread cli-engine/src/prompt.rs Outdated
@jpage-godaddy

Copy link
Copy Markdown
Collaborator

This is working pretty great! I just ran across a bug trying it out in gddy, though:

$ gddy domain purchase

> quote token <TOKEN 8a7594f3-47f8-49ec-83ff-0ea1417a45af
error: unexpected argument '8a7594f3-47f8-49ec-83ff-0ea1417a45af' found

Usage: gddy domain purchase [OPTIONS] --quote-token <TOKEN>

For more information, try '--help'.

@rts1-godaddy

Copy link
Copy Markdown
Collaborator Author

This is working pretty great! I just ran across a bug trying it out in gddy, though:

$ gddy domain purchase

> quote token <TOKEN 8a7594f3-47f8-49ec-83ff-0ea1417a45af
error: unexpected argument '8a7594f3-47f8-49ec-83ff-0ea1417a45af' found

Usage: gddy domain purchase [OPTIONS] --quote-token <TOKEN>

For more information, try '--help'.

Looks like my last commit broke this :/ . let me fix that

@jpage-godaddy

Copy link
Copy Markdown
Collaborator

Another thing... I wonder if we should do some punctuation after the prompt text (a colon maybe?) so it's more visually clear where the prompt ends and where the input begins.

Comment thread cli-engine/src/prompt.rs
/// `"<domain>"` → `"domain"`).
fn strip_arg_decoration(raw: &str) -> &str {
raw.trim_start_matches('-')
.trim_matches(['<', '>', '[', ']'])

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

trim_matches only strips <>[] from the ends, so clap's --quote-token <TOKEN> becomes quote-token <TOKEN (trailing > gone, <TOKEN stays). That doesn't match get_long()/get_id(), arg_def is None, and the value is replayed as a positional — the gddy domain purchase unexpected-argument failure. We should also add a unit test for this.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, didn't realize Jacob already commented on this, same bug.

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.

4 participants