Module: Ace::Review::CLI

Defined in:
lib/ace/review/cli.rb,
lib/ace/review/cli/commands/review.rb,
lib/ace/review/cli/commands/feedback.rb,
lib/ace/review/cli/commands/feedback/list.rb,
lib/ace/review/cli/commands/feedback/show.rb,
lib/ace/review/cli/commands/feedback/skip.rb,
lib/ace/review/cli/commands/feedback/create.rb,
lib/ace/review/cli/commands/feedback/verify.rb,
lib/ace/review/cli/commands/feedback/resolve.rb,
lib/ace/review/cli/commands/feedback/session_discovery.rb

Overview

CLI namespace for ace-review command loading.

ace-review uses a single-command ace-support-cli entrypoint that calls CLI::Commands::Review directly from the executable.

Defined Under Namespace

Modules: Commands

Constant Summary collapse

ARRAY_SEPARATOR =

Separator for array options that won't conflict with internal commas ASCII Unit Separator (0x1F) is designed for separating fields

"\x1F"
CONTEXT_FLAGS =
%w[--evidence-session].freeze

Class Method Summary collapse

Class Method Details

.extract_flag_value(arg, args, index) ⇒ String

Extract value from flag argument

Parameters:

  • arg (String) —

    Current argument (may be --flag=value or just --flag)

  • args (Array<String>) —

    All arguments

  • index (Integer) —

    Current index

Returns:

  • (String) —

    Extracted value



86
87
88
89
90
91
92
93
94
# File 'lib/ace/review/cli.rb', line 86

def self.extract_flag_value(arg, args, index)
  if arg.include?("=")
    arg.split("=", 2)[1]
  elsif index + 1 < args.length && !args[index + 1].start_with?("--")
    args[index + 1]
  else
    ""
  end
end

.preprocess_array_options(args) ⇒ Array<String>

Pre-process array options to work around ace-support-cli limitation

ace-support-cli's type: :array only captures the last occurrence of a flag. This method merges multiple occurrences using ARRAY_SEPARATOR (not comma) to preserve internal commas in subject values like "files:a.rb,b.rb".

Parameters:

  • args (Array<String>) —

    Raw command-line arguments

Returns:

  • (Array<String>) —

    Pre-processed arguments with merged array options



30
31
32
33
34
35
36
37
38
39
40
41
42
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
# File 'lib/ace/review/cli.rb', line 30

def self.preprocess_array_options(args)
  result = []
  i = 0
  accumulated_subject = []
  accumulated_model = []
  accumulated_context = Hash.new { |hash, key| hash[key] = [] }

  while i < args.length
    arg = args[i]

    # Track --subject occurrences for merging
    if arg == "--subject" || arg.start_with?("--subject=")
      value = extract_flag_value(arg, args, i)
      accumulated_subject << value
      i = skip_to_next_arg(args, i)
      next
    end

    # Track --model occurrences for merging
    if arg == "--model" || arg.start_with?("--model=")
      value = extract_flag_value(arg, args, i)
      accumulated_model << value
      i = skip_to_next_arg(args, i)
      next
    end

    CONTEXT_FLAGS.each do |flag|
      next unless arg == flag || arg.start_with?("#{flag}=")

      accumulated_context[flag] << extract_flag_value(arg, args, i)
      i = skip_to_next_arg(args, i)
      break
    end
    next if CONTEXT_FLAGS.any? { |flag| arg == flag || arg.start_with?("#{flag}=") }

    result << arg
    i += 1
  end

  # Insert merged flags at position 0 (single-command mode, no command name to skip)
  result.insert(0, "--model", accumulated_model.join(",")) unless accumulated_model.empty?
  # Subject uses ARRAY_SEPARATOR to preserve internal commas (e.g., files:a.rb,b.rb)
  result.insert(0, "--subject", accumulated_subject.join(ARRAY_SEPARATOR)) unless accumulated_subject.empty?
  accumulated_context.each do |flag, values|
    result.insert(0, flag, values.join(ARRAY_SEPARATOR)) unless values.empty?
  end

  result
end

.skip_to_next_arg(args, index) ⇒ Integer

Calculate next index after consuming flag value

Parameters:

  • args (Array<String>) —

    All arguments

  • index (Integer) —

    Current index

Returns:

  • (Integer) —

    Next index to process



101
102
103
104
105
106
107
108
109
# File 'lib/ace/review/cli.rb', line 101

def self.skip_to_next_arg(args, index)
  if args[index].include?("=")
    index + 1
  elsif index + 1 < args.length && !args[index + 1].start_with?("--")
    index + 2
  else
    index + 1
  end
end

.start(args) ⇒ Object

Entry point for CLI invocation (used by tests via cli_helpers)

Parameters:

  • args (Array<String>) —

    Command-line arguments



114
115
116
# File 'lib/ace/review/cli.rb', line 114

def self.start(args)
  Ace::Support::Cli::Runner.new(Commands::Review).call(args: args)
end