Class: Aidp::CLI

Inherits:
Object
  • Object
show all
Extended by:
MessageDisplay::ClassMethods, RescueLogging
Includes:
MessageDisplay, RescueLogging
Defined in:
lib/aidp/cli.rb,
lib/aidp/cli/terminal_io.rb,
lib/aidp/cli/eval_command.rb,
lib/aidp/cli/jobs_command.rb,
lib/aidp/cli/mcp_dashboard.rb,
lib/aidp/cli/tools_command.rb,
lib/aidp/cli/config_command.rb,
lib/aidp/cli/enhanced_input.rb,
lib/aidp/cli/models_command.rb,
lib/aidp/cli/harness_command.rb,
lib/aidp/cli/first_run_wizard.rb,
lib/aidp/cli/security_command.rb,
lib/aidp/cli/providers_command.rb,
lib/aidp/cli/checkpoint_command.rb,
lib/aidp/cli/devcontainer_commands.rb

Overview

CLI interface for AIDP

Defined Under Namespace

Classes: CheckpointCommand, ConfigCommand, DevcontainerCommands, EnhancedInput, EvalCommand, FirstRunWizard, HarnessCommand, JobsCommand, McpDashboard, ModelsCommand, ProvidersCommand, SecurityCommand, TerminalIO, ToolsCommand

Constant Summary

Constants included from MessageDisplay

MessageDisplay::COLOR_MAP, MessageDisplay::CRITICAL_TYPES

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from MessageDisplay::ClassMethods

display_message, quiet_mode?

Methods included from RescueLogging

__log_rescue_impl, log_rescue

Methods included from MessageDisplay

#display_message, included, #message_display_prompt, #quiet_mode?

Constructor Details

#initialize(prompt: TTY::Prompt.new) ⇒ CLI

Returns a new instance of CLI.



22
23
24
# File 'lib/aidp/cli.rb', line 22

def initialize(prompt: TTY::Prompt.new)
  @prompt = prompt
end

Class Attribute Details

.last_optionsObject

Returns the value of attribute last_options.



37
38
39
# File 'lib/aidp/cli.rb', line 37

def last_options
  @last_options
end

Class Method Details

.create_promptObject



39
40
41
# File 'lib/aidp/cli.rb', line 39

def create_prompt
  ::TTY::Prompt.new
end

.log_rescue(error, component:, action:, fallback: nil, level: :warn, **context) ⇒ Object

Explicit singleton delegator (defensive: ensure availability even if extend fails to attach)



31
32
33
# File 'lib/aidp/cli.rb', line 31

def log_rescue(error, component:, action:, fallback: nil, level: :warn, **context)
  Aidp::RescueLogging.log_rescue(error, component: component, action: action, fallback: fallback, level: level, **context)
end

.run(args = ARGV) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/aidp/cli.rb', line 43

def run(args = ARGV)
  # Handle subcommands first (status, jobs, kb, harness)
  return run_subcommand(args) if subcommand?(args)

  options = parse_options(args)
  self.last_options = options

  # Validate incompatible options
  if options[:quiet] && options[:verbose]
    display_message("❌ --quiet and --verbose are mutually exclusive", type: :error)
    return 1
  end

  # --quiet is incompatible with default interactive mode (no subcommand)
  if options[:quiet] && !options[:help] && !options[:version]
    display_message("❌ --quiet is not compatible with interactive mode. Use with 'watch' command instead.", type: :error)
    return 1
  end

  if options[:help]
    display_message(options[:parser].to_s, type: :info)
    return 0
  end

  if options[:version]
    display_message("Aidp version #{Aidp::VERSION}", type: :info)
    return 0
  end

  # Undocumented: Launch test mode for CI/CD validation
  # Initializes app components and exits cleanly without running full workflows
  if options[:launch_test]
    return run_launch_test(:interactive)
  end

  # Initialize logger from aidp.yml config
  # Priority: ENV variable > aidp.yml > default (info)
  setup_logging(Dir.pwd)

  # Start the interactive TUI
  display_message("AIDP initializing...", type: :info)
  display_message("   Press Ctrl+C to stop\n", type: :highlight)

  # Handle configuration setup
  # Create a prompt for the wizard
  prompt = create_prompt

  if options[:setup_config]
    # Force setup/reconfigure even if config exists
    unless Aidp::CLI::FirstRunWizard.setup_config(Dir.pwd, prompt: prompt, non_interactive: ENV["CI"] == "true")
      display_message("Configuration setup cancelled. Aborting startup.", type: :info)
      return 1
    end
  else
    # First-time setup wizard (before TUI to avoid noisy errors)
    unless Aidp::CLI::FirstRunWizard.ensure_config(Dir.pwd, prompt: prompt, non_interactive: ENV["CI"] == "true")
      display_message("Configuration required. Aborting startup.", type: :info)
      return 1
    end
  end

  # Initialize the enhanced TUI
  tui = Aidp::Harness::UI::EnhancedTUI.new
  workflow_selector = Aidp::Harness::UI::EnhancedWorkflowSelector.new(tui, project_dir: Dir.pwd)

  begin
    # Copilot is now the default mode - no menu selection
    # The guided workflow selector will internally choose appropriate mode
    mode = :guided

    # Get workflow configuration (no spinner - may wait for user input)
    workflow_config = workflow_selector.select_workflow(harness_mode: false, mode: mode)

    # Use the mode determined by the guided workflow selector
    actual_mode = workflow_config[:mode] || :execute

    # Pass workflow configuration to harness
    harness_options = {
      mode: actual_mode,
      workflow_type: workflow_config[:workflow_type],
      selected_steps: workflow_config[:steps],
      user_input: workflow_config[:user_input]
    }

    # Create and run the enhanced harness
    harness_runner = Aidp::Harness::EnhancedRunner.new(Dir.pwd, actual_mode, harness_options)
    result = harness_runner.run
    display_harness_result(result)
    0
  rescue Interrupt
    display_message("\n\n⏹️  Interrupted by user", type: :warning)
    1
  rescue => e
    log_rescue(e, component: "cli", action: "run_harness", fallback: 1, mode: actual_mode)
    display_message("\n❌ Error: #{e.message}", type: :error)
    1
  ensure
    tui.restore_screen
  end
end