wralph 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.
@@ -0,0 +1,116 @@
1
+ # frozen_string_literal: true
2
+
3
+ begin
4
+ require 'reline'
5
+ rescue LoadError
6
+ # Fallback for older Ruby versions - reline was added in Ruby 2.7
7
+ # Use basic $stdin.gets for multiline input
8
+ end
9
+
10
+ require_relative '../interfaces/repo'
11
+ require_relative '../interfaces/print'
12
+ require_relative '../interfaces/shell'
13
+ require_relative '../interfaces/agent'
14
+ require_relative 'init'
15
+ require_relative 'iterate_ci'
16
+
17
+ module Wralph
18
+ module Run
19
+ module Feedback
20
+ def self.run(issue_number)
21
+ Init.ensure_initialized!
22
+
23
+ branch_name = "issue-#{issue_number}".freeze
24
+ plan_file = Interfaces::Repo.plan_file(issue_number)
25
+
26
+ stdout, = Interfaces::Shell.run_command('git branch --show-current')
27
+ current_branch = stdout.strip
28
+ Interfaces::Shell.switch_into_worktree(branch_name, create_if_not_exists: false)
29
+
30
+ # Check that the Pull Request is open
31
+ stdout, = Interfaces::Shell.run_command("gh pr view #{branch_name} --json state -q .state")
32
+ if stdout.strip != 'OPEN'
33
+ Interfaces::Print.error "Pull Request #{issue_number} is not open. Please open it and try again."
34
+ exit 1
35
+ end
36
+
37
+ # Get input from user on changes to make to the Pull Request
38
+ Interfaces::Print.info "Please review the changes to the Pull Request and provide feedback on what changes to make."
39
+ Interfaces::Print.info " - Press Enter for a new line"
40
+ Interfaces::Print.info " - Press Enter three times to submit"
41
+
42
+ if defined?(Reline)
43
+ changes = Reline.readmultiline("> ", true) do |buffer|
44
+ # Submit when the last line is empty (user pressed Enter on empty line)
45
+ # Buffer ends with "\n\n" when user presses Enter on an empty line
46
+ # We need content before the empty line
47
+ next false if buffer.empty? || buffer == "\n"
48
+
49
+ # Check if buffer ends with double newline (empty line entered)
50
+ if buffer.end_with?("\n\n\n")
51
+ # Verify we have at least one non-empty line
52
+ lines = buffer.split("\n")
53
+ lines.any? { |line| !line.strip.empty? }
54
+ else
55
+ false
56
+ end
57
+ end
58
+ # Remove the trailing empty line if present
59
+ else
60
+ # Fallback for older Ruby versions without reline
61
+ changes = ""
62
+ puts "> "
63
+ loop do
64
+ line = $stdin.gets
65
+ break if line.nil? || line.strip.empty?
66
+
67
+ changes += line
68
+ # Check if we've had two consecutive empty lines
69
+ if changes.end_with?("\n\n")
70
+ changes = changes.chomp
71
+ break
72
+ end
73
+ end
74
+ end
75
+ changes = changes.chomp
76
+
77
+ # Ask Claude to make the changes
78
+ Interfaces::Print.info "Asking Claude to evaluate your comments to the Pull Request..."
79
+ instructions = <<~INSTRUCTIONS
80
+ Background: You previously created a plan (found in the file #{plan_file}) and executed changes into a Pull Request
81
+ from the current branch (#{branch_name}) to the git origin. You can compare this branch against master
82
+ to see your proposed changes.
83
+
84
+ The user has reviewed your Pull Request and requested the following changes:
85
+
86
+ #{changes}
87
+
88
+ Do as follows:
89
+ 1. Review your original plan that you documented in the plan file: `#{plan_file}`
90
+ 2. Analyze the code changes that you've made in this branch by comparing it to the master branch
91
+ 2. Review the user input
92
+ 3. Make the necessary changes address the issues raised by the user
93
+ 4. Commit and push the changes to the Pull Request branch
94
+ 5. After pushing, output "FIXES_PUSHED" so I know you've completed the fixes
95
+ INSTRUCTIONS
96
+
97
+ # Run claude code with instructions
98
+ claude_output = Interfaces::Agent.run(instructions)
99
+ puts "CLAUDE_OUTPUT: #{claude_output}"
100
+
101
+ # Check if fixes were pushed
102
+ if claude_output.include?('FIXES_PUSHED')
103
+ Interfaces::Print.success 'Fixes have been pushed. Waiting before checking build status again...'
104
+ sleep 60 # Wait a bit for CircleCI to pick up the new commit
105
+ else
106
+ Interfaces::Print.error 'Could not confirm that fixes were pushed. Please check manually.'
107
+ exit 1
108
+ end
109
+
110
+ IterateCI.run(issue_number)
111
+
112
+ Interfaces::Shell.switch_into_worktree(current_branch)
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'fileutils'
4
+ require_relative '../interfaces/repo'
5
+ require_relative '../interfaces/print'
6
+
7
+ module Wralph
8
+ module Run
9
+ module Init
10
+ def self.run
11
+ wralph_dir = Interfaces::Repo.wralph_dir
12
+ plans_dir = Interfaces::Repo.plans_dir
13
+
14
+ if Dir.exist?(wralph_dir)
15
+ Interfaces::Print.warning ".wralph directory already exists at #{wralph_dir}"
16
+ Interfaces::Print.info "Skipping initialization"
17
+ return
18
+ end
19
+
20
+ # Create .wralph directory
21
+ FileUtils.mkdir_p(wralph_dir)
22
+ Interfaces::Print.success "Created .wralph directory at #{wralph_dir}"
23
+
24
+ # Create plans subdirectory
25
+ FileUtils.mkdir_p(plans_dir)
26
+ Interfaces::Print.success "Created .wralph/plans directory"
27
+
28
+ # Create secrets.yaml template
29
+ secrets_file = Interfaces::Repo.secrets_file
30
+ unless File.exist?(secrets_file)
31
+ secrets_fixture = Interfaces::Repo.fixture_file('secrets.yaml')
32
+ if File.exist?(secrets_fixture)
33
+ FileUtils.cp(secrets_fixture, secrets_file)
34
+ Interfaces::Print.success "Created .wralph/secrets.yaml template"
35
+ else
36
+ Interfaces::Print.warning "Fixture file not found: #{secrets_fixture}"
37
+ end
38
+ end
39
+
40
+ # Create config.yaml template
41
+ config_file = Interfaces::Repo.config_file
42
+ unless File.exist?(config_file)
43
+ config_fixture = Interfaces::Repo.fixture_file('config.yaml')
44
+ if File.exist?(config_fixture)
45
+ FileUtils.cp(config_fixture, config_file)
46
+ Interfaces::Print.success "Created .wralph/config.yaml template"
47
+ else
48
+ Interfaces::Print.warning "Fixture file not found: #{config_fixture}"
49
+ end
50
+ end
51
+
52
+ # Ensure .wralph/secrets.yaml is in .gitignore
53
+ update_gitignore
54
+
55
+ Interfaces::Print.success "WRALPH initialized successfully!"
56
+ Interfaces::Print.info "You can now use 'wralph plan <issue_number>' to get started"
57
+ end
58
+
59
+ def self.initialized?
60
+ wralph_dir = Interfaces::Repo.wralph_dir
61
+ Dir.exist?(wralph_dir)
62
+ end
63
+
64
+ def self.ensure_initialized!
65
+ return if initialized?
66
+
67
+ Interfaces::Print.error "WRALPH has not been initialized in this repository."
68
+ Interfaces::Print.error ""
69
+ Interfaces::Print.error "Please run 'wralph init' first to set up WRALPH."
70
+ exit 1
71
+ rescue SystemExit
72
+ raise
73
+ rescue StandardError => e
74
+ Interfaces::Print.error "Error checking initialization: #{e.message}"
75
+ exit 1
76
+ end
77
+
78
+ def self.update_gitignore
79
+ repo_root = Interfaces::Repo.repo_root
80
+ gitignore_path = File.join(repo_root, '.gitignore')
81
+ secrets_ignore_entry = '.wralph/secrets.yaml'
82
+
83
+ # Check if entry already exists
84
+ if File.exist?(gitignore_path)
85
+ content = File.read(gitignore_path)
86
+ return if content.include?(secrets_ignore_entry)
87
+ end
88
+
89
+ # Add entry to .gitignore
90
+ entry = "\n# WRALPH secrets\n#{secrets_ignore_entry}\n"
91
+ File.open(gitignore_path, 'a') do |f|
92
+ f.write(entry)
93
+ end
94
+ Interfaces::Print.success "Added .wralph/secrets.yaml to .gitignore"
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,120 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'fileutils'
4
+ require_relative '../interfaces/repo'
5
+ require_relative '../interfaces/print'
6
+ require_relative '../interfaces/shell'
7
+ require_relative '../interfaces/agent'
8
+ require_relative '../interfaces/ci'
9
+
10
+ module Wralph
11
+ module Run
12
+ module IterateCI
13
+ MAX_RETRIES = 10
14
+
15
+ def self.run(issue_number, pr_number = nil)
16
+ branch_name = "issue-#{issue_number}".freeze
17
+ pr_number ||= begin
18
+ stdout, = Interfaces::Shell.run_command("gh pr list --head #{branch_name} --json number -q '.[0].number'")
19
+ pr_num = stdout.strip
20
+ pr_num.empty? || pr_num == 'null' ? nil : pr_num
21
+ end
22
+
23
+ stdout, = Interfaces::Shell.run_command('git branch --show-current')
24
+ current_branch = stdout.strip
25
+ if current_branch != branch_name
26
+ Interfaces::Print.error "You are not on the branch #{branch_name}. Please switch to the branch #{branch_name} and try again."
27
+ exit 1
28
+ end
29
+
30
+ if pr_number.nil?
31
+ Interfaces::Print.error "Could not determine PR number from the branch name."
32
+ exit 1
33
+ end
34
+
35
+ plan_file = Interfaces::Repo.plan_file(issue_number)
36
+
37
+ api_token = Interfaces::Ci.api_token
38
+ if api_token.nil? || api_token.empty?
39
+ Interfaces::Print.error 'ci_api_token is not set in .wralph/secrets.yaml'
40
+ Interfaces::Print.error ''
41
+ Interfaces::Print.error 'Please add your CircleCI API token to .wralph/secrets.yaml:'
42
+ Interfaces::Print.error ' ci_api_token: your-token-here'
43
+ exit 1
44
+ else
45
+ Interfaces::Print.success 'Loaded CI API token from .wralph/secrets.yaml'
46
+ end
47
+ retry_count = 0
48
+
49
+ # Get repository info
50
+ repo_owner, = Interfaces::Shell.run_command('gh repo view --json owner -q .owner.login')
51
+ repo_name, = Interfaces::Shell.run_command('gh repo view --json name -q .name')
52
+
53
+ # Ensure tmp directory exists
54
+ FileUtils.mkdir_p(Interfaces::Repo.tmp_dir)
55
+
56
+ while retry_count < MAX_RETRIES
57
+ Interfaces::Print.info "Iteration #{retry_count + 1}/#{MAX_RETRIES}"
58
+
59
+ # Wait for build to complete
60
+ if Interfaces::Ci.wait_for_build(pr_number, repo_owner, repo_name, api_token)
61
+ Interfaces::Print.success "CircleCI build passed! Issue ##{issue_number} has been successfully solved."
62
+ return true
63
+ end
64
+
65
+ # Build failed, get failure details
66
+ Interfaces::Print.warning 'Build failed. Analyzing failures...'
67
+ failure_details = Interfaces::Ci.build_failures(pr_number, repo_owner, repo_name, api_token) || 'Could not fetch failure details'
68
+
69
+ Interfaces::Print.info 'Failure details:'
70
+ puts failure_details
71
+
72
+ retry_count += 1
73
+
74
+ if retry_count >= MAX_RETRIES
75
+ Interfaces::Print.error "Maximum retry count (#{MAX_RETRIES}) reached. Please fix the issues manually."
76
+ exit 1
77
+ end
78
+
79
+ # Store the failure details in a new file for each iteration
80
+ filename = Interfaces::Repo.failure_details_file(branch_name, retry_count)
81
+ File.write(filename, failure_details)
82
+
83
+ # Fix the issues
84
+ Interfaces::Print.info "Attempting to fix the issues (attempt #{retry_count}/#{MAX_RETRIES})..."
85
+
86
+ fix_instructions = <<~FIX_INSTRUCTIONS
87
+ The CircleCI build for PR ##{pr_number} has failed. The failure details have been logged into the following file:
88
+
89
+ #{filename}
90
+
91
+ Do as follows:
92
+ 1. Review your original plan that you documented in the plan file: `#{plan_file}`
93
+ 2. Analyze the failures above
94
+ 3. Make the necessary changes to fix the issues
95
+ 4. Commit and push the changes to the PR branch
96
+ 5. After pushing, output "FIXES_PUSHED" so I know you've completed the fixes
97
+
98
+ The PR branch is: `issue-#{issue_number}`
99
+ FIX_INSTRUCTIONS
100
+
101
+ # Pass fix instructions to claude code
102
+ fix_output = Interfaces::Agent.run(fix_instructions)
103
+ puts "FIX_OUTPUT: #{fix_output}"
104
+
105
+ # Check if fixes were pushed
106
+ if fix_output.include?('FIXES_PUSHED')
107
+ Interfaces::Print.success 'Fixes have been pushed. Waiting before checking build status again...'
108
+ sleep 60 # Wait a bit for CircleCI to pick up the new commit
109
+ else
110
+ Interfaces::Print.error 'Could not confirm that fixes were pushed. Please check manually.'
111
+ exit 1
112
+ end
113
+ end
114
+
115
+ Interfaces::Print.error "Failed to resolve CircleCI build issues after #{MAX_RETRIES} attempts"
116
+ exit 1
117
+ end
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'fileutils'
4
+ require_relative '../interfaces/repo'
5
+ require_relative '../interfaces/print'
6
+ require_relative '../interfaces/shell'
7
+ require_relative '../interfaces/agent'
8
+ require_relative '../interfaces/objective_repository'
9
+ require_relative 'init'
10
+ require_relative 'execute_plan'
11
+
12
+ module Wralph
13
+ module Run
14
+ module Plan
15
+ def self.run(issue_number)
16
+ Init.ensure_initialized!
17
+
18
+ plan_file = Interfaces::Repo.plan_file(issue_number)
19
+ branch_name = "issue-#{issue_number}".freeze
20
+
21
+ # Ensure plans directory exists
22
+ FileUtils.mkdir_p(Interfaces::Repo.plans_dir)
23
+
24
+ # Check if GitHub CLI is authenticated
25
+ _, _, success = Interfaces::Shell.run_command('gh auth status')
26
+ unless success
27
+ Interfaces::Print.error 'GitHub CLI is not authenticated. Please run \'gh auth login\''
28
+ exit 1
29
+ end
30
+
31
+ # Check for uncommitted changes
32
+ _, _, success = Interfaces::Shell.run_command('git diff-index --quiet HEAD --')
33
+ unless success
34
+ Interfaces::Print.warning 'You have uncommitted changes. The script will create a new branch, but consider committing or stashing your changes first.'
35
+ Interfaces::Shell.ask_user_to_continue('Continue anyway? (y/N) ')
36
+ end
37
+
38
+ # Fetch issue details to verify it exists and download it
39
+ Interfaces::Print.info "Fetching GitHub issue ##{issue_number}..."
40
+ begin
41
+ Interfaces::ObjectiveRepository.download!(issue_number)
42
+ rescue StandardError => e
43
+ Interfaces::Print.error "Issue ##{issue_number} not found or not accessible: #{e.message}"
44
+ exit 1
45
+ end
46
+
47
+ # Check if branch already exists (locally or remotely)
48
+ Interfaces::Print.info "Checking if branch '#{branch_name}' already exists..."
49
+ _, _, success = Interfaces::Shell.run_command("git show-ref --verify --quiet refs/heads/#{branch_name}")
50
+ if success
51
+ Interfaces::Print.error "Branch '#{branch_name}' already exists locally. Please delete it first."
52
+ exit 1
53
+ end
54
+
55
+ stdout, = Interfaces::Shell.run_command("git ls-remote --heads origin #{branch_name}")
56
+ if stdout.include?(branch_name)
57
+ Interfaces::Print.error "Branch '#{branch_name}' already exists on remote. Please delete it first."
58
+ exit 1
59
+ end
60
+
61
+ Interfaces::Print.success "Branch '#{branch_name}' does not exist locally or remotely. Proceeding..."
62
+
63
+ # Main workflow
64
+ Interfaces::Print.info "Starting workflow to solve GitHub issue ##{issue_number}"
65
+
66
+ # Step 1: Create initial plan and execute
67
+ Interfaces::Print.info 'Step 1: Creating plan and executing solution...'
68
+
69
+ objective_file = Interfaces::ObjectiveRepository.local_file_path(issue_number)
70
+ instructions_template = <<~INSTRUCTIONS
71
+ I need you to make a plan to solve the objective "#{issue_number}" in the file: `#{objective_file}`. You are not to make any code changes. Instead, here's what I need you to do:
72
+
73
+ 1. First, read the objective from the file
74
+
75
+ 2. Create a detailed plan for solving the issue. Write your thinking and plan in a markdown file at:
76
+ `#{plan_file}`
77
+
78
+ The plan should include:
79
+ - Analysis of the issue.
80
+ - Approach to solving it.
81
+ - Test cases that should be written to verify the solution.
82
+ - Steps you'll take.
83
+ - Any potential risks or considerations.
84
+ - A list of questions for any clarifications you need to ask the user. If you do not need any clarifications, you can say "No questions needed".
85
+ INSTRUCTIONS
86
+
87
+ # Run claude code with instructions
88
+ Interfaces::Print.info "Running Claude Code to create a plan to solve issue ##{issue_number}..."
89
+ claude_output = Interfaces::Agent.run(instructions_template)
90
+ puts "CLAUDE_OUTPUT: #{claude_output}"
91
+
92
+ # Check if the plan file was created
93
+ unless File.exist?(plan_file)
94
+ Interfaces::Print.error "Plan file '#{plan_file}' was not created. Please check the Claude Code output manually."
95
+ Interfaces::Print.error "Output: #{claude_output}"
96
+ exit 1
97
+ end
98
+
99
+ Interfaces::Print.success "Plan file '#{plan_file}' was created. Please review it, answering any questions Claude has asked."
100
+ Interfaces::Shell.ask_user_to_continue('When you are ready to proceed, answer "y" to continue (y/N) ')
101
+
102
+ # Execute the plan
103
+ ExecutePlan.run(issue_number)
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../interfaces/print'
4
+ require_relative '../interfaces/shell'
5
+ require_relative 'init'
6
+
7
+ module Wralph
8
+ module Run
9
+ module Remove
10
+ def self.run(issue_number)
11
+ Init.ensure_initialized!
12
+
13
+ branch_name = "issue-#{issue_number}".freeze
14
+
15
+ # Delete local branch
16
+ _, _, success = Interfaces::Shell.run_command("git branch -D #{branch_name}")
17
+ if success
18
+ Interfaces::Print.info "Deleted branch '#{branch_name}' locally"
19
+ else
20
+ Interfaces::Print.warning "Branch '#{branch_name}' not found locally"
21
+ end
22
+
23
+ # Delete remote branch
24
+ _, _, success = Interfaces::Shell.run_command("git push origin --delete #{branch_name}")
25
+ if success
26
+ Interfaces::Print.info "Deleted branch '#{branch_name}' on remote"
27
+ else
28
+ Interfaces::Print.warning "Branch '#{branch_name}' not found on remote"
29
+ end
30
+
31
+ # Remove worktree
32
+ _, _, success = Interfaces::Shell.run_command("wt remove #{branch_name}")
33
+ if success
34
+ Interfaces::Print.info "Removed worktree for branch '#{branch_name}'"
35
+ else
36
+ Interfaces::Print.warning "Worktree for branch '#{branch_name}' not found"
37
+ end
38
+
39
+ Interfaces::Print.success "Cleanup completed for issue ##{issue_number}"
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wralph
4
+ VERSION = '0.1.2'
5
+ end
data/lib/wralph.rb ADDED
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'wralph/version'
4
+ require_relative 'wralph/config'
5
+ require_relative 'wralph/interfaces/repo'
6
+ require_relative 'wralph/interfaces/print'
7
+ require_relative 'wralph/interfaces/shell'
8
+ require_relative 'wralph/interfaces/agent'
9
+ require_relative 'wralph/interfaces/ci'
10
+ require_relative 'wralph/interfaces/objective_repository'
11
+ require_relative 'wralph/run/init'
12
+ require_relative 'wralph/run/plan'
13
+ require_relative 'wralph/run/execute_plan'
14
+ require_relative 'wralph/run/iterate_ci'
15
+ require_relative 'wralph/run/feedback'
16
+ require_relative 'wralph/run/remove'
17
+
18
+ module Wralph
19
+ end
metadata ADDED
@@ -0,0 +1,123 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: wralph
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.2
5
+ platform: ruby
6
+ authors:
7
+ - Nick Knipe
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: rake
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'
26
+ - !ruby/object:Gem::Dependency
27
+ name: rspec
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ - !ruby/object:Gem::Dependency
41
+ name: rubocop
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ type: :development
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ - !ruby/object:Gem::Dependency
55
+ name: webmock
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ type: :development
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ description: 'A CLI that wraps a coding agent and CI to autonomously complete software
69
+ objectives using the Ralph Wiggum technique. '
70
+ email:
71
+ - nick@hellodrifter.com
72
+ executables:
73
+ - wralph
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - README.md
78
+ - bin/wralph
79
+ - lib/wralph.rb
80
+ - lib/wralph/adapters/agents.rb
81
+ - lib/wralph/adapters/agents/claude_code.rb
82
+ - lib/wralph/adapters/cis.rb
83
+ - lib/wralph/adapters/cis/circle_ci.rb
84
+ - lib/wralph/adapters/objective_repositories.rb
85
+ - lib/wralph/adapters/objective_repositories/github_issues.rb
86
+ - lib/wralph/config.rb
87
+ - lib/wralph/fixtures/config.yaml
88
+ - lib/wralph/fixtures/secrets.yaml
89
+ - lib/wralph/interfaces/agent.rb
90
+ - lib/wralph/interfaces/ci.rb
91
+ - lib/wralph/interfaces/objective_repository.rb
92
+ - lib/wralph/interfaces/print.rb
93
+ - lib/wralph/interfaces/repo.rb
94
+ - lib/wralph/interfaces/shell.rb
95
+ - lib/wralph/run/execute_plan.rb
96
+ - lib/wralph/run/feedback.rb
97
+ - lib/wralph/run/init.rb
98
+ - lib/wralph/run/iterate_ci.rb
99
+ - lib/wralph/run/plan.rb
100
+ - lib/wralph/run/remove.rb
101
+ - lib/wralph/version.rb
102
+ homepage: https://github.com/niborg/wralph
103
+ licenses:
104
+ - MIT
105
+ metadata: {}
106
+ rdoc_options: []
107
+ require_paths:
108
+ - lib
109
+ required_ruby_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: 3.0.0
114
+ required_rubygems_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ requirements: []
120
+ rubygems_version: 3.6.9
121
+ specification_version: 4
122
+ summary: Human-In-The-Loop AI Factory
123
+ test_files: []