Class: Aidp::Watch::ReviewProcessor

Inherits:
Object
  • Object
show all
Includes:
MessageDisplay
Defined in:
lib/aidp/watch/review_processor.rb

Overview

Handles the aidp-review label trigger by performing multi-persona code review and posting categorized findings back to the PR.

Constant Summary collapse

DEFAULT_REVIEW_LABEL =

Default label names

"aidp-review"
COMMENT_HEADER =
"## 🤖 AIDP Code Review"

Constants included from MessageDisplay

MessageDisplay::COLOR_MAP

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from MessageDisplay

#display_message, #in_test_environment?, included, #message_display_prompt, #suppress_display_message?

Constructor Details

#initialize(repository_client:, state_store:, provider_name: nil, project_dir: Dir.pwd, label_config: {}, verbose: false) ⇒ ReviewProcessor

Returns a new instance of ReviewProcessor.



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/aidp/watch/review_processor.rb', line 26

def initialize(repository_client:, state_store:, provider_name: nil, project_dir: Dir.pwd, label_config: {}, verbose: false)
  @repository_client = repository_client
  @state_store = state_store
  @provider_name = provider_name
  @project_dir = project_dir
  @verbose = verbose

  # Load label configuration
  @review_label = label_config[:review_trigger] || label_config["review_trigger"] || DEFAULT_REVIEW_LABEL

  # Initialize reviewers
  @reviewers = [
    Reviewers::SeniorDevReviewer.new(provider_name: provider_name),
    Reviewers::SecurityReviewer.new(provider_name: provider_name),
    Reviewers::PerformanceReviewer.new(provider_name: provider_name)
  ]
end

Instance Attribute Details

#review_labelObject (readonly)

Returns the value of attribute review_label.



24
25
26
# File 'lib/aidp/watch/review_processor.rb', line 24

def review_label
  @review_label
end

Instance Method Details

#process(pr) ⇒ Object



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
# File 'lib/aidp/watch/review_processor.rb', line 44

def process(pr)
  number = pr[:number]

  if @state_store.review_processed?(number)
    display_message("â„šī¸  Review for PR ##{number} already posted. Skipping.", type: :muted)
    return
  end

  display_message("🔍 Reviewing PR ##{number} (#{pr[:title]})", type: :info)

  # Fetch PR details
  pr_data = @repository_client.fetch_pull_request(number)
  files = @repository_client.fetch_pull_request_files(number)
  diff = @repository_client.fetch_pull_request_diff(number)

  # Run reviews in parallel (conceptually - actual implementation is sequential)
  review_results = run_reviews(pr_data: pr_data, files: files, diff: diff)

  # Log review results
  log_review(number, review_results)

  # Format and post comment
  comment_body = format_review_comment(pr: pr_data, review_results: review_results)
  @repository_client.post_comment(number, comment_body)

  display_message("đŸ’Ŧ Posted review comment for PR ##{number}", type: :success)
  @state_store.record_review(number, {
    timestamp: Time.now.utc.iso8601,
    reviewers: review_results.map { |r| r[:persona] },
    total_findings: review_results.sum { |r| r[:findings].length }
  })

  # Remove review label after processing
  begin
    @repository_client.remove_labels(number, @review_label)
    display_message("đŸˇī¸  Removed '#{@review_label}' label after review", type: :info)
  rescue => e
    display_message("âš ī¸  Failed to remove review label: #{e.message}", type: :warn)
  end
rescue => e
  display_message("❌ Review failed: #{e.message}", type: :error)
  Aidp.log_error("review_processor", "Review failed", pr: number, error: e.message, backtrace: e.backtrace&.first(10))

  # Post error comment
  error_comment = <<~COMMENT
    #{COMMENT_HEADER}

    ❌ Automated review failed: #{e.message}

    Please review manually or retry by re-adding the `#{@review_label}` label.
  COMMENT
  begin
    @repository_client.post_comment(number, error_comment)
  rescue
    nil
  end
end