lex-swarm-github 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +5 -1
- data/lex-swarm-github.gemspec +0 -1
- data/lib/legion/extensions/swarm_github/runners/pull_request_reviewer.rb +59 -0
- data/lib/legion/extensions/swarm_github/version.rb +1 -1
- data/lib/legion/extensions/swarm_github.rb +1 -0
- data/spec/legion/extensions/swarm_github/runners/pull_request_reviewer_spec.rb +82 -0
- metadata +4 -16
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d40757aca13c9bab82f57b358f6206276198c6dfd04ffa3be18c5ad4e1a967e5
|
|
4
|
+
data.tar.gz: d76193d6b724bca39020124a8131e57cc7a2746caa05237acb30c6060c39b1c0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ff0459d83eeb35e01951212ee17867bfe8ad7f4e38f6df0af3dde9a59a193c3e15cf86b790b4994bb3484bf70cd192d0e337c93043e89c2fe0f99fe8d327e29f
|
|
7
|
+
data.tar.gz: 147be637157b8cddb282d39944ee03f5085c33ca52e2210c9788e1b8ae457b0978efd0bd29116dea418eb88a7ab8fc9e686907d7113b23f795d46c8f7d2e378d
|
data/Gemfile
CHANGED
|
@@ -8,4 +8,8 @@ gem 'rspec', '~> 3.13'
|
|
|
8
8
|
gem 'rubocop', '~> 1.75', require: false
|
|
9
9
|
gem 'rubocop-rspec', require: false
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
if File.exist?(File.expand_path('../../legion-gaia', __dir__))
|
|
12
|
+
gem 'legion-gaia', path: '../../legion-gaia'
|
|
13
|
+
else
|
|
14
|
+
gem 'legion-gaia'
|
|
15
|
+
end
|
data/lex-swarm-github.gemspec
CHANGED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module SwarmGithub
|
|
6
|
+
module Runners
|
|
7
|
+
module PullRequestReviewer
|
|
8
|
+
def review_pull_request(owner:, repo:, pull_number:)
|
|
9
|
+
files = fetch_pr_files(owner: owner, repo: repo, pull_number: pull_number)
|
|
10
|
+
return { status: 'skipped', reason: 'no files' } if files.empty?
|
|
11
|
+
|
|
12
|
+
diff_text = files.map { |f| "#{f[:filename]}:\n#{f[:patch]}" }.join("\n\n")
|
|
13
|
+
review = generate_review(diff_text)
|
|
14
|
+
|
|
15
|
+
{
|
|
16
|
+
status: 'reviewed',
|
|
17
|
+
pr: "#{owner}/#{repo}##{pull_number}",
|
|
18
|
+
files_reviewed: files.size,
|
|
19
|
+
comments: review[:comments] || [],
|
|
20
|
+
summary: review[:summary]
|
|
21
|
+
}
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
def fetch_pr_files(owner:, repo:, pull_number:)
|
|
27
|
+
return [] unless defined?(Legion::Extensions::Github::Client)
|
|
28
|
+
|
|
29
|
+
Legion::Extensions::Github::Client.new.list_pull_request_files(
|
|
30
|
+
owner: owner, repo: repo, pull_number: pull_number
|
|
31
|
+
)[:result] || []
|
|
32
|
+
rescue StandardError
|
|
33
|
+
[]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def generate_review(diff_text)
|
|
37
|
+
return { summary: 'LLM unavailable', comments: [] } unless defined?(Legion::LLM)
|
|
38
|
+
|
|
39
|
+
result = Legion::LLM.chat(
|
|
40
|
+
message: "#{code_review_prompt}\n\n#{diff_text[0..12_000]}"
|
|
41
|
+
)
|
|
42
|
+
::JSON.parse(result[:content] || '{}', symbolize_names: true)
|
|
43
|
+
rescue StandardError => e
|
|
44
|
+
{ summary: "Review failed: #{e.message}", comments: [] }
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def code_review_prompt
|
|
48
|
+
<<~PROMPT
|
|
49
|
+
Review this code diff. Return JSON with:
|
|
50
|
+
- "summary": 1-2 sentence overall assessment
|
|
51
|
+
- "comments": array of {"file", "line", "severity", "message"}
|
|
52
|
+
Severity: info, warning, error. Focus on bugs and security issues.
|
|
53
|
+
PROMPT
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -4,6 +4,7 @@ require 'legion/extensions/swarm_github/version'
|
|
|
4
4
|
require 'legion/extensions/swarm_github/helpers/pipeline'
|
|
5
5
|
require 'legion/extensions/swarm_github/helpers/issue_tracker'
|
|
6
6
|
require 'legion/extensions/swarm_github/runners/github_swarm'
|
|
7
|
+
require 'legion/extensions/swarm_github/runners/pull_request_reviewer'
|
|
7
8
|
|
|
8
9
|
module Legion
|
|
9
10
|
module Extensions
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
require 'legion/extensions/swarm_github/runners/pull_request_reviewer'
|
|
5
|
+
|
|
6
|
+
RSpec.describe Legion::Extensions::SwarmGithub::Runners::PullRequestReviewer do
|
|
7
|
+
let(:reviewer) { Class.new { include Legion::Extensions::SwarmGithub::Runners::PullRequestReviewer }.new }
|
|
8
|
+
|
|
9
|
+
describe '#review_pull_request' do
|
|
10
|
+
context 'when PR has no files' do
|
|
11
|
+
before do
|
|
12
|
+
allow(reviewer).to receive(:fetch_pr_files).and_return([])
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it 'returns skipped status' do
|
|
16
|
+
result = reviewer.review_pull_request(owner: 'test', repo: 'repo', pull_number: 1)
|
|
17
|
+
expect(result[:status]).to eq('skipped')
|
|
18
|
+
expect(result[:reason]).to eq('no files')
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
context 'when PR has files' do
|
|
23
|
+
let(:files) do
|
|
24
|
+
[{ filename: 'lib/foo.rb', patch: '+ def bar; end' }]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
before do
|
|
28
|
+
allow(reviewer).to receive(:fetch_pr_files).and_return(files)
|
|
29
|
+
allow(reviewer).to receive(:generate_review).and_return(
|
|
30
|
+
{ summary: 'Looks good', comments: [] }
|
|
31
|
+
)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it 'returns reviewed status with file count' do
|
|
35
|
+
result = reviewer.review_pull_request(owner: 'test', repo: 'repo', pull_number: 42)
|
|
36
|
+
expect(result[:status]).to eq('reviewed')
|
|
37
|
+
expect(result[:files_reviewed]).to eq(1)
|
|
38
|
+
expect(result[:pr]).to eq('test/repo#42')
|
|
39
|
+
expect(result[:summary]).to eq('Looks good')
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it 'includes comments array from review' do
|
|
43
|
+
result = reviewer.review_pull_request(owner: 'test', repo: 'repo', pull_number: 42)
|
|
44
|
+
expect(result[:comments]).to eq([])
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
context 'when PR has multiple files with comments' do
|
|
49
|
+
let(:files) do
|
|
50
|
+
[
|
|
51
|
+
{ filename: 'lib/foo.rb', patch: '+ def bar; end' },
|
|
52
|
+
{ filename: 'lib/baz.rb', patch: '+ x = dangerous_call(input)' }
|
|
53
|
+
]
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
let(:review_result) do
|
|
57
|
+
{
|
|
58
|
+
summary: 'Security issue found',
|
|
59
|
+
comments: [
|
|
60
|
+
{ file: 'lib/baz.rb', line: 1, severity: 'error', message: 'Unsafe call with user input' }
|
|
61
|
+
]
|
|
62
|
+
}
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
before do
|
|
66
|
+
allow(reviewer).to receive(:fetch_pr_files).and_return(files)
|
|
67
|
+
allow(reviewer).to receive(:generate_review).and_return(review_result)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
it 'returns correct file count' do
|
|
71
|
+
result = reviewer.review_pull_request(owner: 'test', repo: 'repo', pull_number: 5)
|
|
72
|
+
expect(result[:files_reviewed]).to eq(2)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
it 'passes through comments from review' do
|
|
76
|
+
result = reviewer.review_pull_request(owner: 'test', repo: 'repo', pull_number: 5)
|
|
77
|
+
expect(result[:comments].size).to eq(1)
|
|
78
|
+
expect(result[:comments].first[:severity]).to eq('error')
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
metadata
CHANGED
|
@@ -1,28 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lex-swarm-github
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Esity
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
-
dependencies:
|
|
12
|
-
- !ruby/object:Gem::Dependency
|
|
13
|
-
name: legion-gaia
|
|
14
|
-
requirement: !ruby/object:Gem::Requirement
|
|
15
|
-
requirements:
|
|
16
|
-
- - ">="
|
|
17
|
-
- !ruby/object:Gem::Version
|
|
18
|
-
version: '0'
|
|
19
|
-
type: :development
|
|
20
|
-
prerelease: false
|
|
21
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
-
requirements:
|
|
23
|
-
- - ">="
|
|
24
|
-
- !ruby/object:Gem::Version
|
|
25
|
-
version: '0'
|
|
11
|
+
dependencies: []
|
|
26
12
|
description: GitHub-specific swarm pipeline (finder/fixer/validator) for brain-modeled
|
|
27
13
|
agentic AI
|
|
28
14
|
email:
|
|
@@ -39,12 +25,14 @@ files:
|
|
|
39
25
|
- lib/legion/extensions/swarm_github/helpers/issue_tracker.rb
|
|
40
26
|
- lib/legion/extensions/swarm_github/helpers/pipeline.rb
|
|
41
27
|
- lib/legion/extensions/swarm_github/runners/github_swarm.rb
|
|
28
|
+
- lib/legion/extensions/swarm_github/runners/pull_request_reviewer.rb
|
|
42
29
|
- lib/legion/extensions/swarm_github/version.rb
|
|
43
30
|
- spec/legion/extensions/swarm_github/actors/stale_issues_spec.rb
|
|
44
31
|
- spec/legion/extensions/swarm_github/client_spec.rb
|
|
45
32
|
- spec/legion/extensions/swarm_github/helpers/issue_tracker_spec.rb
|
|
46
33
|
- spec/legion/extensions/swarm_github/helpers/pipeline_spec.rb
|
|
47
34
|
- spec/legion/extensions/swarm_github/runners/github_swarm_spec.rb
|
|
35
|
+
- spec/legion/extensions/swarm_github/runners/pull_request_reviewer_spec.rb
|
|
48
36
|
- spec/spec_helper.rb
|
|
49
37
|
homepage: https://github.com/LegionIO/lex-swarm-github
|
|
50
38
|
licenses:
|