Module: RosettAi::Ui::TtyHelper

Defined in:
lib/rosett_ai/ui/tty_helper.rb

Overview

TTY detection and safe interactive helpers for CLI commands.

Provides guards for interactive prompts and spinners that degrade gracefully when stdout/stdin are not terminals (e.g., piped or redirected). Commands should use these helpers instead of calling TTY::Prompt or TTY::Spinner directly.

Class Method Summary collapse

Class Method Details

.ask(question, option_hint: nil) ⇒ String

Ask for free-text input.

In non-interactive mode, raises a Thor::Error with a hint about the equivalent CLI option.

Parameters:

  • question (String)

    the prompt text

  • option_hint (String, nil) (defaults to: nil)

    CLI option name (e.g. 'description')

Returns:

  • (String)

Raises:

  • (Thor::Error)

    when non-interactive



53
54
55
56
57
58
59
# File 'lib/rosett_ai/ui/tty_helper.rb', line 53

def ask(question, option_hint: nil)
  hint = option_hint ? "Use --#{option_hint} to provide the value." : nil
  require_interactive!(hint)

  require 'tty-prompt'
  TTY::Prompt.new.ask(question, required: true)
end

.confirm?(question, force: false) ⇒ Boolean

Ask a yes/no confirmation question.

Returns true immediately when +force+ is true. In non-interactive mode (piped stdin/stdout), raises a Thor::Error with a hint to use --force.

Parameters:

  • question (String)

    the confirmation question

  • force (Boolean) (defaults to: false)

    skip the prompt entirely

Returns:

  • (Boolean)

Raises:

  • (Thor::Error)

    when non-interactive and not forced



35
36
37
38
39
40
41
42
# File 'lib/rosett_ai/ui/tty_helper.rb', line 35

def confirm?(question, force: false)
  return true if force

  require_interactive!('Use --force to skip confirmation.')

  require 'tty-prompt'
  TTY::Prompt.new.yes?(question)
end

.interactive?Boolean

Whether stdout and stdin are both connected to a terminal.

Returns:

  • (Boolean)


21
22
23
# File 'lib/rosett_ai/ui/tty_helper.rb', line 21

def interactive?
  $stdout.tty? && $stdin.tty?
end

.require_interactive!(hint = nil) ⇒ Object

Guard that raises if the terminal is not interactive.

Parameters:

  • hint (String, nil) (defaults to: nil)

    additional guidance for the user

Raises:

  • (Thor::Error)


65
66
67
68
69
70
71
# File 'lib/rosett_ai/ui/tty_helper.rb', line 65

def require_interactive!(hint = nil)
  return if interactive?

  message = 'Interactive input required but terminal is not available.'
  message = "#{message} #{hint}" if hint
  raise ::Thor::Error, message
end