aider-ruby 0.1.0
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 +7 -0
- data/LICENSE +21 -0
- data/README.md +542 -0
- data/bin/aider-ruby +320 -0
- data/lib/aider_ruby/client.rb +571 -0
- data/lib/aider_ruby/config.rb +371 -0
- data/lib/aider_ruby/error_handling.rb +57 -0
- data/lib/aider_ruby/models.rb +204 -0
- data/lib/aider_ruby/task_executor.rb +301 -0
- data/lib/aider_ruby/validation.rb +103 -0
- data/lib/aider_ruby/version.rb +3 -0
- data/lib/aider_ruby.rb +30 -0
- metadata +154 -0
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
require 'tempfile'
|
|
3
|
+
|
|
4
|
+
module AiderRuby
|
|
5
|
+
class TaskExecutor
|
|
6
|
+
attr_reader :client, :task_history
|
|
7
|
+
|
|
8
|
+
def initialize(client)
|
|
9
|
+
@client = client
|
|
10
|
+
@task_history = []
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Execute a coding task with multiple steps
|
|
14
|
+
def execute_coding_task(description, files = [], options = {})
|
|
15
|
+
task = {
|
|
16
|
+
id: generate_task_id,
|
|
17
|
+
type: :coding,
|
|
18
|
+
description: description,
|
|
19
|
+
files: files,
|
|
20
|
+
status: :pending,
|
|
21
|
+
steps: [],
|
|
22
|
+
created_at: Time.now
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@task_history << task
|
|
26
|
+
|
|
27
|
+
begin
|
|
28
|
+
task[:status] = :running
|
|
29
|
+
|
|
30
|
+
# Add files to client
|
|
31
|
+
files.each { |file| @client.add_files(file) }
|
|
32
|
+
|
|
33
|
+
# Execute the task
|
|
34
|
+
result = @client.execute(description, options)
|
|
35
|
+
|
|
36
|
+
task[:status] = :completed
|
|
37
|
+
task[:result] = result
|
|
38
|
+
task[:completed_at] = Time.now
|
|
39
|
+
|
|
40
|
+
result
|
|
41
|
+
rescue StandardError => e
|
|
42
|
+
task[:status] = :failed
|
|
43
|
+
task[:error] = e.message
|
|
44
|
+
task[:failed_at] = Time.now
|
|
45
|
+
raise e
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Execute a refactoring task
|
|
50
|
+
def execute_refactoring_task(description, files = [], options = {})
|
|
51
|
+
task = {
|
|
52
|
+
id: generate_task_id,
|
|
53
|
+
type: :refactoring,
|
|
54
|
+
description: description,
|
|
55
|
+
files: files,
|
|
56
|
+
status: :pending,
|
|
57
|
+
steps: [],
|
|
58
|
+
created_at: Time.now
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@task_history << task
|
|
62
|
+
|
|
63
|
+
begin
|
|
64
|
+
task[:status] = :running
|
|
65
|
+
|
|
66
|
+
# Add files to client
|
|
67
|
+
files.each { |file| @client.add_files(file) }
|
|
68
|
+
|
|
69
|
+
# Enable git and auto-commits for refactoring
|
|
70
|
+
refactoring_options = options.merge(
|
|
71
|
+
git: true,
|
|
72
|
+
auto_commits: true,
|
|
73
|
+
lint: true,
|
|
74
|
+
auto_lint: true
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
result = @client.execute(description, refactoring_options)
|
|
78
|
+
|
|
79
|
+
task[:status] = :completed
|
|
80
|
+
task[:result] = result
|
|
81
|
+
task[:completed_at] = Time.now
|
|
82
|
+
|
|
83
|
+
result
|
|
84
|
+
rescue StandardError => e
|
|
85
|
+
task[:status] = :failed
|
|
86
|
+
task[:error] = e.message
|
|
87
|
+
task[:failed_at] = Time.now
|
|
88
|
+
raise e
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Execute a debugging task
|
|
93
|
+
def execute_debugging_task(description, files = [], options = {})
|
|
94
|
+
task = {
|
|
95
|
+
id: generate_task_id,
|
|
96
|
+
type: :debugging,
|
|
97
|
+
description: description,
|
|
98
|
+
files: files,
|
|
99
|
+
status: :pending,
|
|
100
|
+
steps: [],
|
|
101
|
+
created_at: Time.now
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
@task_history << task
|
|
105
|
+
|
|
106
|
+
begin
|
|
107
|
+
task[:status] = :running
|
|
108
|
+
|
|
109
|
+
# Add files to client
|
|
110
|
+
files.each { |file| @client.add_files(file) }
|
|
111
|
+
|
|
112
|
+
# Enable verbose output and testing for debugging
|
|
113
|
+
debugging_options = options.merge(
|
|
114
|
+
verbose: true,
|
|
115
|
+
test: true,
|
|
116
|
+
auto_test: true,
|
|
117
|
+
show_diffs: true
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
result = @client.execute(description, debugging_options)
|
|
121
|
+
|
|
122
|
+
task[:status] = :completed
|
|
123
|
+
task[:result] = result
|
|
124
|
+
task[:completed_at] = Time.now
|
|
125
|
+
|
|
126
|
+
result
|
|
127
|
+
rescue StandardError => e
|
|
128
|
+
task[:status] = :failed
|
|
129
|
+
task[:error] = e.message
|
|
130
|
+
task[:failed_at] = Time.now
|
|
131
|
+
raise e
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# Execute a documentation task
|
|
136
|
+
def execute_documentation_task(description, files = [], options = {})
|
|
137
|
+
task = {
|
|
138
|
+
id: generate_task_id,
|
|
139
|
+
type: :documentation,
|
|
140
|
+
description: description,
|
|
141
|
+
files: files,
|
|
142
|
+
status: :pending,
|
|
143
|
+
steps: [],
|
|
144
|
+
created_at: Time.now
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
@task_history << task
|
|
148
|
+
|
|
149
|
+
begin
|
|
150
|
+
task[:status] = :running
|
|
151
|
+
|
|
152
|
+
# Add files to client
|
|
153
|
+
files.each { |file| @client.add_files(file) }
|
|
154
|
+
|
|
155
|
+
# Use a model good for documentation
|
|
156
|
+
doc_options = options.merge(
|
|
157
|
+
model: 'claude-3-5-sonnet-20241022',
|
|
158
|
+
pretty: true
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
result = @client.execute(description, doc_options)
|
|
162
|
+
|
|
163
|
+
task[:status] = :completed
|
|
164
|
+
task[:result] = result
|
|
165
|
+
task[:completed_at] = Time.now
|
|
166
|
+
|
|
167
|
+
result
|
|
168
|
+
rescue StandardError => e
|
|
169
|
+
task[:status] = :failed
|
|
170
|
+
task[:error] = e.message
|
|
171
|
+
task[:failed_at] = Time.now
|
|
172
|
+
raise e
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
# Execute a test generation task
|
|
177
|
+
def execute_test_generation_task(description, files = [], options = {})
|
|
178
|
+
task = {
|
|
179
|
+
id: generate_task_id,
|
|
180
|
+
type: :test_generation,
|
|
181
|
+
description: description,
|
|
182
|
+
files: files,
|
|
183
|
+
status: :pending,
|
|
184
|
+
steps: [],
|
|
185
|
+
created_at: Time.now
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
@task_history << task
|
|
189
|
+
|
|
190
|
+
begin
|
|
191
|
+
task[:status] = :running
|
|
192
|
+
|
|
193
|
+
# Add files to client
|
|
194
|
+
files.each { |file| @client.add_files(file) }
|
|
195
|
+
|
|
196
|
+
# Enable testing and auto-test for test generation
|
|
197
|
+
test_options = options.merge(
|
|
198
|
+
test: true,
|
|
199
|
+
auto_test: true,
|
|
200
|
+
test_cmd: 'rspec' # Default to RSpec for Ruby
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
result = @client.execute(description, test_options)
|
|
204
|
+
|
|
205
|
+
task[:status] = :completed
|
|
206
|
+
task[:result] = result
|
|
207
|
+
task[:completed_at] = Time.now
|
|
208
|
+
|
|
209
|
+
result
|
|
210
|
+
rescue StandardError => e
|
|
211
|
+
task[:status] = :failed
|
|
212
|
+
task[:error] = e.message
|
|
213
|
+
task[:failed_at] = Time.now
|
|
214
|
+
raise e
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
# Execute a multi-step task with checkpoints
|
|
219
|
+
def execute_multi_step_task(steps, files = [], options = {})
|
|
220
|
+
task = {
|
|
221
|
+
id: generate_task_id,
|
|
222
|
+
type: :multi_step,
|
|
223
|
+
description: "Multi-step task with #{steps.length} steps",
|
|
224
|
+
files: files,
|
|
225
|
+
status: :pending,
|
|
226
|
+
steps: steps,
|
|
227
|
+
created_at: Time.now
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
@task_history << task
|
|
231
|
+
|
|
232
|
+
begin
|
|
233
|
+
task[:status] = :running
|
|
234
|
+
|
|
235
|
+
# Add files to client
|
|
236
|
+
files.each { |file| @client.add_files(file) }
|
|
237
|
+
|
|
238
|
+
results = []
|
|
239
|
+
|
|
240
|
+
steps.each_with_index do |step, index|
|
|
241
|
+
step_result = @client.execute(step, options)
|
|
242
|
+
results << step_result
|
|
243
|
+
|
|
244
|
+
# Add checkpoint
|
|
245
|
+
task[:steps][index][:result] = step_result
|
|
246
|
+
task[:steps][index][:completed_at] = Time.now
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
task[:status] = :completed
|
|
250
|
+
task[:result] = results
|
|
251
|
+
task[:completed_at] = Time.now
|
|
252
|
+
|
|
253
|
+
results
|
|
254
|
+
rescue StandardError => e
|
|
255
|
+
task[:status] = :failed
|
|
256
|
+
task[:error] = e.message
|
|
257
|
+
task[:failed_at] = Time.now
|
|
258
|
+
raise e
|
|
259
|
+
end
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
# Get task history
|
|
263
|
+
def get_task_history(filter = {})
|
|
264
|
+
tasks = @task_history
|
|
265
|
+
|
|
266
|
+
tasks = tasks.select { |task| task[:type] == filter[:type] } if filter[:type]
|
|
267
|
+
|
|
268
|
+
tasks = tasks.select { |task| task[:status] == filter[:status] } if filter[:status]
|
|
269
|
+
|
|
270
|
+
tasks = tasks.select { |task| task[:created_at] >= filter[:since] } if filter[:since]
|
|
271
|
+
|
|
272
|
+
tasks
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
# Get task by ID
|
|
276
|
+
def get_task(task_id)
|
|
277
|
+
@task_history.find { |task| task[:id] == task_id }
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
# Export task history to JSON
|
|
281
|
+
def export_history(file_path = nil)
|
|
282
|
+
if file_path
|
|
283
|
+
File.write(file_path, JSON.pretty_generate(@task_history))
|
|
284
|
+
else
|
|
285
|
+
JSON.pretty_generate(@task_history)
|
|
286
|
+
end
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
# Import task history from JSON
|
|
290
|
+
def import_history(file_path)
|
|
291
|
+
history = JSON.parse(File.read(file_path), symbolize_names: true)
|
|
292
|
+
@task_history.concat(history)
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
private
|
|
296
|
+
|
|
297
|
+
def generate_task_id
|
|
298
|
+
"task_#{Time.now.to_i}_#{rand(1000)}"
|
|
299
|
+
end
|
|
300
|
+
end
|
|
301
|
+
end
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
module AiderRuby
|
|
2
|
+
module Validation
|
|
3
|
+
class Validator
|
|
4
|
+
VALID_EDIT_FORMATS = %w[whole diff diff-fenced].freeze
|
|
5
|
+
VALID_REASONING_EFFORTS = %w[low medium high].freeze
|
|
6
|
+
VALID_VOICE_FORMATS = %w[wav webm mp3].freeze
|
|
7
|
+
VALID_LINE_ENDINGS = %w[platform lf crlf cr].freeze
|
|
8
|
+
VALID_ENCODINGS = %w[utf-8 utf-16 utf-32 ascii].freeze
|
|
9
|
+
|
|
10
|
+
def self.validate_model_name(model_name)
|
|
11
|
+
return if model_name.nil? || model_name.empty?
|
|
12
|
+
|
|
13
|
+
unless Models.supported_model?(model_name)
|
|
14
|
+
ErrorHandling.handle_validation_error("Unsupported model: #{model_name}")
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.validate_edit_format(format)
|
|
19
|
+
return if format.nil? || format.empty?
|
|
20
|
+
|
|
21
|
+
unless VALID_EDIT_FORMATS.include?(format)
|
|
22
|
+
ErrorHandling.handle_validation_error("Invalid edit format: #{format}. Valid formats: #{VALID_EDIT_FORMATS.join(', ')}")
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def self.validate_reasoning_effort(effort)
|
|
27
|
+
return if effort.nil? || effort.empty?
|
|
28
|
+
|
|
29
|
+
unless VALID_REASONING_EFFORTS.include?(effort.to_s)
|
|
30
|
+
ErrorHandling.handle_validation_error("Invalid reasoning effort: #{effort}. Valid efforts: #{VALID_REASONING_EFFORTS.join(', ')}")
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.validate_thinking_tokens(tokens)
|
|
35
|
+
return if tokens.nil? || tokens.empty?
|
|
36
|
+
|
|
37
|
+
# Support formats like "1k", "8k", "1000", etc.
|
|
38
|
+
token_str = tokens.to_s.downcase
|
|
39
|
+
unless token_str.match?(/\A\d+[km]?\z/)
|
|
40
|
+
ErrorHandling.handle_validation_error("Invalid thinking tokens format: #{tokens}. Use formats like '1k', '8k', '1000'")
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def self.validate_voice_format(format)
|
|
45
|
+
return if format.nil? || format.empty?
|
|
46
|
+
|
|
47
|
+
unless VALID_VOICE_FORMATS.include?(format)
|
|
48
|
+
ErrorHandling.handle_validation_error("Invalid voice format: #{format}. Valid formats: #{VALID_VOICE_FORMATS.join(', ')}")
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def self.validate_line_endings(endings)
|
|
53
|
+
return if endings.nil? || endings.empty?
|
|
54
|
+
|
|
55
|
+
unless VALID_LINE_ENDINGS.include?(endings)
|
|
56
|
+
ErrorHandling.handle_validation_error("Invalid line endings: #{endings}. Valid endings: #{VALID_LINE_ENDINGS.join(', ')}")
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def self.validate_encoding(encoding)
|
|
61
|
+
return if encoding.nil? || encoding.empty?
|
|
62
|
+
|
|
63
|
+
unless VALID_ENCODINGS.include?(encoding)
|
|
64
|
+
ErrorHandling.handle_validation_error("Invalid encoding: #{encoding}. Valid encodings: #{VALID_ENCODINGS.join(', ')}")
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def self.validate_file_path(file_path)
|
|
69
|
+
return if file_path.nil? || file_path.empty?
|
|
70
|
+
|
|
71
|
+
unless File.exist?(file_path)
|
|
72
|
+
ErrorHandling.handle_file_error(Errno::ENOENT.new(file_path))
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def self.validate_api_key(key, provider)
|
|
77
|
+
return if key.nil? || key.empty?
|
|
78
|
+
|
|
79
|
+
if key.length < 10
|
|
80
|
+
ErrorHandling.handle_validation_error("Invalid #{provider} API key: too short")
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def self.validate_timeout(timeout)
|
|
85
|
+
return if timeout.nil?
|
|
86
|
+
|
|
87
|
+
timeout_int = timeout.to_i
|
|
88
|
+
if timeout_int <= 0 || timeout_int > 3600
|
|
89
|
+
ErrorHandling.handle_validation_error("Invalid timeout: #{timeout}. Must be between 1 and 3600 seconds")
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def self.validate_map_tokens(tokens)
|
|
94
|
+
return if tokens.nil?
|
|
95
|
+
|
|
96
|
+
tokens_int = tokens.to_i
|
|
97
|
+
if tokens_int <= 0 || tokens_int > 100000
|
|
98
|
+
ErrorHandling.handle_validation_error("Invalid map tokens: #{tokens}. Must be between 1 and 100000")
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
data/lib/aider_ruby.rb
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require_relative 'aider_ruby/version'
|
|
2
|
+
|
|
3
|
+
module AiderRuby
|
|
4
|
+
class Error < StandardError; end
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
require_relative 'aider_ruby/error_handling'
|
|
8
|
+
require_relative 'aider_ruby/validation'
|
|
9
|
+
require_relative 'aider_ruby/client'
|
|
10
|
+
require_relative 'aider_ruby/config'
|
|
11
|
+
require_relative 'aider_ruby/models'
|
|
12
|
+
require_relative 'aider_ruby/task_executor'
|
|
13
|
+
|
|
14
|
+
module AiderRuby
|
|
15
|
+
# Main entry point for the gem
|
|
16
|
+
def self.new_client(options = {}, &block)
|
|
17
|
+
Client::Client.new(options, &block)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def self.configure(&block)
|
|
21
|
+
Config::Configuration.configure(&block)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.version
|
|
25
|
+
VERSION
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# NOTE: Use AiderRuby::Client::Client and AiderRuby::Config::Configuration directly
|
|
29
|
+
# Aliases are available but may cause warnings
|
|
30
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: aider-ruby
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Renaud Gagnon
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2025-09-30 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: json
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '2.0'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '2.0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: open3
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0.1'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0.1'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: thor
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '1.0'
|
|
48
|
+
type: :runtime
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '1.0'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: yaml
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - "~>"
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0.1'
|
|
62
|
+
type: :runtime
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - "~>"
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '0.1'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: rake
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - "~>"
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '13.0'
|
|
76
|
+
type: :development
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - "~>"
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '13.0'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: rspec
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - "~>"
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '3.0'
|
|
90
|
+
type: :development
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - "~>"
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '3.0'
|
|
97
|
+
- !ruby/object:Gem::Dependency
|
|
98
|
+
name: rubocop
|
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - "~>"
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: '1.0'
|
|
104
|
+
type: :development
|
|
105
|
+
prerelease: false
|
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - "~>"
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: '1.0'
|
|
111
|
+
description: A Ruby gem that provides a wrapper for aider, enabling configuration
|
|
112
|
+
of LLMs and execution of tasks through command line interface
|
|
113
|
+
email:
|
|
114
|
+
- renaud.gagnon@example.com
|
|
115
|
+
executables:
|
|
116
|
+
- aider-ruby
|
|
117
|
+
extensions: []
|
|
118
|
+
extra_rdoc_files: []
|
|
119
|
+
files:
|
|
120
|
+
- LICENSE
|
|
121
|
+
- README.md
|
|
122
|
+
- bin/aider-ruby
|
|
123
|
+
- lib/aider_ruby.rb
|
|
124
|
+
- lib/aider_ruby/client.rb
|
|
125
|
+
- lib/aider_ruby/config.rb
|
|
126
|
+
- lib/aider_ruby/error_handling.rb
|
|
127
|
+
- lib/aider_ruby/models.rb
|
|
128
|
+
- lib/aider_ruby/task_executor.rb
|
|
129
|
+
- lib/aider_ruby/validation.rb
|
|
130
|
+
- lib/aider_ruby/version.rb
|
|
131
|
+
homepage: https://github.com/renaudgagnon/aider-ruby
|
|
132
|
+
licenses:
|
|
133
|
+
- MIT
|
|
134
|
+
metadata: {}
|
|
135
|
+
post_install_message:
|
|
136
|
+
rdoc_options: []
|
|
137
|
+
require_paths:
|
|
138
|
+
- lib
|
|
139
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
140
|
+
requirements:
|
|
141
|
+
- - ">="
|
|
142
|
+
- !ruby/object:Gem::Version
|
|
143
|
+
version: '0'
|
|
144
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
145
|
+
requirements:
|
|
146
|
+
- - ">="
|
|
147
|
+
- !ruby/object:Gem::Version
|
|
148
|
+
version: '0'
|
|
149
|
+
requirements: []
|
|
150
|
+
rubygems_version: 3.3.3
|
|
151
|
+
signing_key:
|
|
152
|
+
specification_version: 4
|
|
153
|
+
summary: Ruby wrapper for aider - AI pair programming tool
|
|
154
|
+
test_files: []
|