ai_refactor 0.5.1 → 0.5.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e50d610e50fdbccc133cd5951cee61244602b402917aa2eb1ab37713b3a6b276
4
- data.tar.gz: eee461b016a3dec20476828383da3571999649097472eedc68f736d6ea759057
3
+ metadata.gz: 5f916993ff53967b44cbbc81138c87d518518618d3edc932cefa6aea9f0a4c4c
4
+ data.tar.gz: 5d3bd3b9cea6d7bd39e0028caa5ccf24527dd03fcd98d643498a65743a2cac5e
5
5
  SHA512:
6
- metadata.gz: c4c913a3263949687e98681697e5fe2631748aa57dbc3ea4c7aa3f367a3ce98cb6d2d3ea86653f2e949fd65d055dd9c0f67d93c79602742fb179a27568639ed6
7
- data.tar.gz: 41324b5dd54d62f59d749638c7b813e4d2fcc4d75528aaf4e37ba4027773b87195a1dad6ffc4400b9ce34ba38004319d7385879b8d01f00a8161a86eec842a6a
6
+ metadata.gz: 41cb1f31ceb6e503cdbeeb972f17a91e1826eccb4fb66e8a73b3b54bb3899ff9572d9cb4783c67fe7e7fee8999f7f25f2b19ae7ab9fde6c766e895e4fb4a1b32
7
+ data.tar.gz: 57626f38b266521d820bb411dbf517dd3273ed6e4bd44412d4c4e4b0306a3347252a1b87d0214c148f5f5e35c20cd81c6325648f878dd34d67fe58226156118d
data/Gemfile CHANGED
@@ -11,7 +11,7 @@ gem "minitest", "~> 5.0"
11
11
 
12
12
  gem "standard", "~> 1.3"
13
13
 
14
- gem "dotenv"
14
+ gem "steep"
15
15
 
16
16
  # for the examples
17
17
 
data/Steepfile ADDED
@@ -0,0 +1,27 @@
1
+ # D = Steep::Diagnostic
2
+ #
3
+ # target :lib do
4
+ # signature "sig"
5
+ #
6
+ # check "lib" # Directory name
7
+ # check "Gemfile" # File name
8
+ # check "app/models/**/*.rb" # Glob
9
+ # # ignore "lib/templates/*.rb"
10
+ #
11
+ # # library "pathname" # Standard libraries
12
+ # # library "strong_json" # Gems
13
+ #
14
+ # # configure_code_diagnostics(D::Ruby.default) # `default` diagnostics setting (applies by default)
15
+ # # configure_code_diagnostics(D::Ruby.strict) # `strict` diagnostics setting
16
+ # # configure_code_diagnostics(D::Ruby.lenient) # `lenient` diagnostics setting
17
+ # # configure_code_diagnostics(D::Ruby.silent) # `silent` diagnostics setting
18
+ # # configure_code_diagnostics do |hash| # You can setup everything yourself
19
+ # # hash[D::Ruby::NoMethod] = :information
20
+ # # end
21
+ # end
22
+
23
+ # A steep target to check our example
24
+ target :examples do
25
+ signature "examples/outputs"
26
+ check "examples/ex2_input.rb"
27
+ end
data/ai_refactor.gemspec CHANGED
@@ -31,6 +31,6 @@ Gem::Specification.new do |spec|
31
31
  # Uncomment to register a new dependency of your gem
32
32
  spec.add_dependency "colorize", "< 2.0"
33
33
  spec.add_dependency "open3", "< 2.0"
34
- spec.add_dependency "ruby-openai", ">= 3.4.0", "< 5.0"
34
+ spec.add_dependency "ruby-openai", ">= 3.4.0", "< 6.0"
35
35
  spec.add_dependency "zeitwerk", "~> 2.6"
36
36
  end
@@ -2,6 +2,7 @@ refactor: rails/minitest/rspec_to_minitest
2
2
  input_file_paths:
3
3
  - examples/ex1_input_spec.rb
4
4
  # We need to add context here as otherwise to tell the AI to require our local test_helper.rb file so that we can run the tests after
5
- context_text: "In the output test use `require_relative` to include 'test_helper'."
5
+ context_text: "In the output test use `require_relative '../test_helper'` to include 'test_helper'."
6
6
  # By default, ai_refactor runs "bundle exec rails test" but this isn't going to work here as we are not actually in a Rails app context in the examples
7
7
  minitest_run_command: ruby __FILE__
8
+ output_file_path: examples/outputs/ex1_input_test.rb
@@ -0,0 +1,17 @@
1
+ # example from https://blog.kiprosh.com/type-checking-in-ruby-3-using-rbs/
2
+ # basic_math.rb
3
+
4
+ class BasicMath
5
+ def initialize(num1, num2)
6
+ @num1 = num1
7
+ @num2 = num2
8
+ end
9
+
10
+ def first_less_than_second?
11
+ @num1 < @num2
12
+ end
13
+
14
+ def add
15
+ @num1 + @num2
16
+ end
17
+ end
@@ -0,0 +1,7 @@
1
+ refactor: ruby/write_rbs
2
+ input_file_paths:
3
+ - examples/ex2_input.rb
4
+ # We need to add context here as our class doesnt actually give any context.
5
+ context_text: "Assume that the inputs can be any numeric type."
6
+ # By default this refactor writes to `sig/...` but here we just put the result in `examples/...`
7
+ output_file_path: examples/outputs/ex2_input.rbs
data/exe/ai_refactor CHANGED
@@ -6,8 +6,6 @@ require "openai"
6
6
  require "shellwords"
7
7
  require_relative "../lib/ai_refactor"
8
8
 
9
- require "dotenv/load"
10
-
11
9
  supported_refactors = AIRefactor::Refactors.all
12
10
  refactors_descriptions = AIRefactor::Refactors.descriptions
13
11
 
@@ -70,7 +70,7 @@ module AIRefactor
70
70
 
71
71
  def input_to_process
72
72
  return File.read(@input_file_path) if @input_file_path
73
- @input_content
73
+ @input_content || ""
74
74
  end
75
75
 
76
76
  def input_prompt
@@ -39,7 +39,7 @@ module AIRefactor
39
39
 
40
40
  def file_processor
41
41
  context = ::AIRefactor::Context.new(files: options[:context_file_paths], text: options[:context_text], logger: logger)
42
- prompt = ::AIRefactor::Prompt.new(input_content: input_content, input_path: input_file, output_file_path: output_file_path, prompt: prompt_input, context: context, logger: logger, options: options)
42
+ prompt = ::AIRefactor::Prompt.new(input_content: input_content, input_path: input_file, output_file_path: output_file_path, prompt: prompt_input, context: context, logger: logger, prompt_footer: prompt_footer, options: options)
43
43
  AIRefactor::FileProcessor.new(prompt: prompt, ai_client: ai_client, output_path: output_file_path, logger: logger, options: options)
44
44
  end
45
45
 
@@ -102,22 +102,46 @@ module AIRefactor
102
102
  false
103
103
  end
104
104
 
105
- def prompt_input
106
- if options && options[:prompt]&.length&.positive?
107
- return options[:prompt]
108
- end
105
+ def prompt_template_for_refactor
106
+ location = Module.const_source_location(::AIRefactor::Refactors::BaseRefactor.name)
107
+ File.join(File.dirname(location.first), "#{refactor_name}.md")
108
+ end
109
+
110
+ def prompt_template_for_refactor?
111
+ File.exist?(prompt_template_for_refactor)
112
+ end
113
+
114
+ def user_provided_prompt_template?
115
+ options[:prompt_file_path]&.length&.positive?
116
+ end
109
117
 
110
- file = if options && options[:prompt_file_path]&.length&.positive?
111
- options[:prompt_file_path]
118
+ def prompt_from_file?
119
+ user_provided_prompt_template? || prompt_template_for_refactor?
120
+ end
121
+
122
+ def user_provided_prompt?
123
+ options[:prompt]&.length&.positive?
124
+ end
125
+
126
+ def prompt_input
127
+ if user_provided_prompt_template?
128
+ file = options[:prompt_file_path]
129
+ raise "No prompt file '#{file}' found. Check prompt_file_path is valid" unless File.exist?(file)
130
+ File.read(file)
112
131
  else
113
- location = Module.const_source_location(::AIRefactor::Refactors::BaseRefactor.name)
114
- File.join(File.dirname(location.first), "#{refactor_name}.md")
115
- end
116
- file.tap do |prompt|
117
- raise "No prompt file '#{prompt}' found for #{refactor_name}" unless File.exist?(prompt)
132
+ file = prompt_template_for_refactor
133
+ if File.exist?(file)
134
+ File.read(file)
135
+ elsif user_provided_prompt?
136
+ options[:prompt]
137
+ else
138
+ raise "No prompt was provided. Please provide one with the --prompt option or with a command file."
139
+ end
118
140
  end
141
+ end
119
142
 
120
- File.read(file)
143
+ def prompt_footer
144
+ options[:prompt] if user_provided_prompt? && prompt_from_file?
121
145
  end
122
146
 
123
147
  def output_file_path
@@ -4,7 +4,7 @@ module AIRefactor
4
4
  module Refactors
5
5
  class Custom < BaseRefactor
6
6
  def run
7
- logger.verbose "Custom refactor to #{input_file}... (using user supplied prompt #{prompt_file_path})"
7
+ logger.verbose "Custom refactor to #{input_file}... (using user supplied prompt #{prompt_file_path || "from options"})"
8
8
  logger.verbose "Write output to #{output_file_path}..." if output_file_path
9
9
 
10
10
  begin
@@ -26,6 +26,7 @@ module AIRefactor
26
26
  private
27
27
 
28
28
  def prompt_file_path
29
+ return if options[:prompt]&.length&.positive?
29
30
  specified_prompt_path = options[:prompt_file_path]
30
31
  if specified_prompt_path&.length&.positive?
31
32
  if File.exist?(specified_prompt_path)
@@ -5,6 +5,4 @@ __{{prompt_header}}__
5
5
  The input file is: __{{input_file_path}}__
6
6
  The output file path is: __{{output_file_path}}__
7
7
 
8
- __{{content}}__
9
-
10
8
  __{{prompt_footer}}__
@@ -0,0 +1,118 @@
1
+ You are an expert Ruby senior software developer.
2
+
3
+ You will be writing the type signatures for the Ruby code below, in RBS format.
4
+
5
+ RBS is a language to describe the structure of Ruby programs. You can write down the definition of a class or module: methods defined in the class, instance variables and their types, and inheritance/mix-in relations. It also allows declaring constants and global variables.
6
+
7
+ The following is a small example of RBS for a chat app.
8
+
9
+ Given the Ruby
10
+ ```ruby
11
+ module ChatApp
12
+ VERSION = "1.0.0"
13
+ class User
14
+ attr_reader :login, :email
15
+
16
+ def initialize(login:, email:); end
17
+
18
+ def my_method(String arg1, Integer arg2); end
19
+ end
20
+
21
+ class Bot
22
+ attr_reader :name
23
+ attr_reader :email
24
+ attr_reader :owner
25
+
26
+ def initialize(name:, owner:); end
27
+ end
28
+
29
+ class Message
30
+ attr_reader :id, :string, :from, :reply_to
31
+
32
+ def initialize(from:, string:); end
33
+
34
+ def reply(from:, string:)
35
+ Message.new(from, string)
36
+ end
37
+ end
38
+
39
+ class Channel
40
+ attr_reader :name, :messages, :users, :bots
41
+
42
+ def initialize(name)
43
+ @name = name
44
+ @messages = []
45
+ @users = []
46
+ @bots = []
47
+ end
48
+
49
+ def each_member(&block)
50
+ members = users + bots
51
+ block? ? members.each(&block) : members.each
52
+ end
53
+ end
54
+ end
55
+ ```
56
+
57
+ We can write the RBS as follows:
58
+ ```
59
+ module ChatApp
60
+ VERSION: String
61
+
62
+ class User
63
+ attr_reader login: String
64
+ attr_reader email: String
65
+
66
+ # If a method takes keyword arguments then use `key: Type` syntax.
67
+ def initialize: (login: String, email: String) -> void
68
+
69
+ # If a method takes positional arguments then put the type before the argument name.
70
+ def my_method: (String arg1, Integer arg2) -> String
71
+ end
72
+
73
+ class Bot
74
+ attr_reader name: String
75
+ attr_reader email: String
76
+ attr_reader owner: User
77
+
78
+ def initialize: (name: String, owner: User) -> void
79
+ end
80
+
81
+ class Message
82
+ attr_reader id: String
83
+ attr_reader string: String
84
+ attr_reader from: User | Bot # `|` means union types: `#from` can be `User` or `Bot`
85
+ attr_reader reply_to: Message? # `?` means optional type: `#reply_to` can be `nil`
86
+
87
+ def initialize: (from: User | Bot, string: String) -> void
88
+
89
+ def reply: (from: User | Bot, string: String) -> Message
90
+ end
91
+
92
+ class Channel
93
+ attr_reader name: String
94
+ attr_reader messages: Array[Message]
95
+ attr_reader users: Array[User]
96
+ attr_reader bots: Array[Bot]
97
+
98
+ def initialize: (String name) -> void
99
+
100
+ def each_member: () { (User | Bot) -> void } -> void # `{` and `}` means block.
101
+ | () -> Enumerator[User | Bot, void] # Method can be overloaded.
102
+ end
103
+ end
104
+ ```
105
+
106
+ Note, when writing the RBS for a class method, eg one in a `class << self` block, use `def self.method` in the
107
+ type definition.
108
+
109
+ Do not include comments in your RBS code or start the file with 'rbs' or '.rbs'.
110
+
111
+ __{{context}}__
112
+
113
+ __{{prompt_header}}__
114
+
115
+ The input file is: __{{input_file_path}}__
116
+ The output file path is: __{{output_file_path}}__
117
+
118
+ __{{prompt_footer}}__
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AIRefactor
4
+ module Refactors
5
+ module Ruby
6
+ class WriteRbs < BaseRefactor
7
+ def run
8
+ logger.verbose "Write some RBS for #{input_file}..."
9
+ logger.verbose "Write output to #{output_file_path}..." if output_file_path
10
+
11
+ begin
12
+ output_content = process!(strip_ticks: true)
13
+ rescue => e
14
+ logger.error "Failed to process #{input_file}: #{e.message}"
15
+ return false
16
+ end
17
+
18
+ return false unless output_content
19
+
20
+ if output_file_path
21
+ steep_runner = AIRefactor::TestRunners::SteepRunner.new(input_file, command_template: options.minitest_run_command)
22
+
23
+ logger.verbose "Run steep against generated RBS file #{output_file_path} (`#{steep_runner.command}`)..."
24
+ test_run = steep_runner.run
25
+
26
+ if test_run.failed?
27
+ logger.warn "#{input_file} was translated to #{output_file_path} but the resulting RBS fails to pass a steep check..."
28
+ logger.error "Failed to run test, exited with status #{test_run.exitstatus}. Stdout: #{test_run.stdout}\n\nStderr: #{test_run.stderr}\n\n"
29
+ logger.error "New RBS failed!", bold: true
30
+ self.failed_message = "Generated RBS file failed to pass checks"
31
+ return false
32
+ end
33
+
34
+ logger.verbose "\nNew RBS file passed checks"
35
+ end
36
+
37
+ output_file_path ? true : output_content
38
+ end
39
+
40
+ def self.description
41
+ "User supplied prompt to write RBS for some Ruby"
42
+ end
43
+
44
+ def default_output_path
45
+ File.join("sig", input_file.gsub(/\.rb$/, ".rbs"))
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -2,6 +2,4 @@ __{{context}}__
2
2
 
3
3
  __{{prompt_header}}__
4
4
 
5
- __{{content}}__
6
-
7
5
  __{{prompt_footer}}__
@@ -17,7 +17,6 @@ module AIRefactor
17
17
  path = @template.dup
18
18
  @template.scan(/\[(FILE|NAME|DIR|REFACTOR|EXT)(\|([^|]+)\|([^\]]*))?\]/).each do |match|
19
19
  type, sub, old_value, new_value = match
20
- puts "type: #{type}, sub: #{sub}, old_value: #{old_value}, new_value: #{new_value}"
21
20
  value = send(type.downcase.to_sym)
22
21
  value = value.gsub(old_value, new_value) if sub
23
22
  path.gsub!("[#{type}#{sub}]", value)
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "open3"
4
+
5
+ module AIRefactor
6
+ module TestRunners
7
+ class SteepRunner
8
+ def initialize(file_path, command_template: "bundle exec steep __FILE__")
9
+ @file_path = file_path
10
+ @command_template = command_template
11
+ end
12
+
13
+ def command
14
+ @command_template.gsub("__FILE__", @file_path)
15
+ end
16
+
17
+ def run
18
+ stdout, stderr, status = Open3.capture3(command)
19
+ # TODO: parse output
20
+ # look initally for Cannot find a configuration at Steepfile
21
+ #
22
+ # _matched, runs, _assertions, failures, errors, skips = stdout.match(/(\d+) runs, (\d+) assertions, (\d+) failures, (\d+) errors, (\d+) skips/).to_a
23
+ TestRunResult.new(stdout, stderr, status) # , runs, failures, skips, errors)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -5,7 +5,7 @@ module AIRefactor
5
5
  class TestRunResult
6
6
  attr_reader :stdout, :stderr, :example_count, :failure_count, :pending_count
7
7
 
8
- def initialize(stdout, stderr, status, example_count, failure_count, pending_count, errored)
8
+ def initialize(stdout, stderr, status, example_count = 0, failure_count = 0, pending_count = 0, errored = 0)
9
9
  @stdout = stdout
10
10
  @stderr = stderr
11
11
  @status = status
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AIRefactor
4
- VERSION = "0.5.1"
4
+ VERSION = "0.5.3"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ai_refactor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.5.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen Ierodiaconou
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-09-21 00:00:00.000000000 Z
11
+ date: 2024-02-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize
@@ -47,7 +47,7 @@ dependencies:
47
47
  version: 3.4.0
48
48
  - - "<"
49
49
  - !ruby/object:Gem::Version
50
- version: '5.0'
50
+ version: '6.0'
51
51
  type: :runtime
52
52
  prerelease: false
53
53
  version_requirements: !ruby/object:Gem::Requirement
@@ -57,7 +57,7 @@ dependencies:
57
57
  version: 3.4.0
58
58
  - - "<"
59
59
  - !ruby/object:Gem::Version
60
- version: '5.0'
60
+ version: '6.0'
61
61
  - !ruby/object:Gem::Dependency
62
62
  name: zeitwerk
63
63
  requirement: !ruby/object:Gem::Requirement
@@ -84,14 +84,15 @@ files:
84
84
  - ".standard.yml"
85
85
  - CHANGELOG.md
86
86
  - Gemfile
87
- - Gemfile.lock
88
87
  - LICENSE.txt
89
88
  - README.md
90
89
  - Rakefile
90
+ - Steepfile
91
91
  - ai_refactor.gemspec
92
- - examples/.gitignore
93
92
  - examples/ex1_convert_a_rspec_test_to_minitest.yml
94
93
  - examples/ex1_input_spec.rb
94
+ - examples/ex2_input.rb
95
+ - examples/ex2_write_rbs.yml
95
96
  - examples/rails_helper.rb
96
97
  - examples/test_helper.rb
97
98
  - exe/ai_refactor
@@ -117,12 +118,15 @@ files:
117
118
  - lib/ai_refactor/refactors/rspec/minitest_to_rspec.rb
118
119
  - lib/ai_refactor/refactors/ruby/refactor_ruby.md
119
120
  - lib/ai_refactor/refactors/ruby/refactor_ruby.rb
121
+ - lib/ai_refactor/refactors/ruby/write_rbs.md
122
+ - lib/ai_refactor/refactors/ruby/write_rbs.rb
120
123
  - lib/ai_refactor/refactors/ruby/write_ruby.md
121
124
  - lib/ai_refactor/refactors/ruby/write_ruby.rb
122
125
  - lib/ai_refactor/run_configuration.rb
123
126
  - lib/ai_refactor/templated_path.rb
124
127
  - lib/ai_refactor/test_runners/minitest_runner.rb
125
128
  - lib/ai_refactor/test_runners/rspec_runner.rb
129
+ - lib/ai_refactor/test_runners/steep_runner.rb
126
130
  - lib/ai_refactor/test_runners/test_run_diff_report.rb
127
131
  - lib/ai_refactor/test_runners/test_run_result.rb
128
132
  - lib/ai_refactor/version.rb
@@ -147,7 +151,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
147
151
  - !ruby/object:Gem::Version
148
152
  version: '0'
149
153
  requirements: []
150
- rubygems_version: 3.4.19
154
+ rubygems_version: 3.4.20
151
155
  signing_key:
152
156
  specification_version: 4
153
157
  summary: Use AI to convert a Rails RSpec test suite to minitest.
data/Gemfile.lock DELETED
@@ -1,244 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- ai_refactor (0.5.1)
5
- colorize (< 2.0)
6
- open3 (< 2.0)
7
- ruby-openai (>= 3.4.0, < 5.0)
8
- zeitwerk (~> 2.6)
9
-
10
- GEM
11
- remote: https://rubygems.org/
12
- specs:
13
- actioncable (7.0.8)
14
- actionpack (= 7.0.8)
15
- activesupport (= 7.0.8)
16
- nio4r (~> 2.0)
17
- websocket-driver (>= 0.6.1)
18
- actionmailbox (7.0.8)
19
- actionpack (= 7.0.8)
20
- activejob (= 7.0.8)
21
- activerecord (= 7.0.8)
22
- activestorage (= 7.0.8)
23
- activesupport (= 7.0.8)
24
- mail (>= 2.7.1)
25
- net-imap
26
- net-pop
27
- net-smtp
28
- actionmailer (7.0.8)
29
- actionpack (= 7.0.8)
30
- actionview (= 7.0.8)
31
- activejob (= 7.0.8)
32
- activesupport (= 7.0.8)
33
- mail (~> 2.5, >= 2.5.4)
34
- net-imap
35
- net-pop
36
- net-smtp
37
- rails-dom-testing (~> 2.0)
38
- actionpack (7.0.8)
39
- actionview (= 7.0.8)
40
- activesupport (= 7.0.8)
41
- rack (~> 2.0, >= 2.2.4)
42
- rack-test (>= 0.6.3)
43
- rails-dom-testing (~> 2.0)
44
- rails-html-sanitizer (~> 1.0, >= 1.2.0)
45
- actiontext (7.0.8)
46
- actionpack (= 7.0.8)
47
- activerecord (= 7.0.8)
48
- activestorage (= 7.0.8)
49
- activesupport (= 7.0.8)
50
- globalid (>= 0.6.0)
51
- nokogiri (>= 1.8.5)
52
- actionview (7.0.8)
53
- activesupport (= 7.0.8)
54
- builder (~> 3.1)
55
- erubi (~> 1.4)
56
- rails-dom-testing (~> 2.0)
57
- rails-html-sanitizer (~> 1.1, >= 1.2.0)
58
- activejob (7.0.8)
59
- activesupport (= 7.0.8)
60
- globalid (>= 0.3.6)
61
- activemodel (7.0.8)
62
- activesupport (= 7.0.8)
63
- activerecord (7.0.8)
64
- activemodel (= 7.0.8)
65
- activesupport (= 7.0.8)
66
- activestorage (7.0.8)
67
- actionpack (= 7.0.8)
68
- activejob (= 7.0.8)
69
- activerecord (= 7.0.8)
70
- activesupport (= 7.0.8)
71
- marcel (~> 1.0)
72
- mini_mime (>= 1.1.0)
73
- activesupport (7.0.8)
74
- concurrent-ruby (~> 1.0, >= 1.0.2)
75
- i18n (>= 1.6, < 2)
76
- minitest (>= 5.1)
77
- tzinfo (~> 2.0)
78
- ast (2.4.2)
79
- builder (3.2.4)
80
- colorize (0.8.1)
81
- concurrent-ruby (1.2.2)
82
- crass (1.0.6)
83
- date (3.3.3)
84
- diff-lcs (1.5.0)
85
- dotenv (2.8.1)
86
- erubi (1.12.0)
87
- faraday (2.7.4)
88
- faraday-net_http (>= 2.0, < 3.1)
89
- ruby2_keywords (>= 0.0.4)
90
- faraday-multipart (1.0.4)
91
- multipart-post (~> 2)
92
- faraday-net_http (3.0.2)
93
- globalid (1.2.1)
94
- activesupport (>= 6.1)
95
- i18n (1.14.1)
96
- concurrent-ruby (~> 1.0)
97
- json (2.6.3)
98
- language_server-protocol (3.17.0.3)
99
- lint_roller (1.0.0)
100
- loofah (2.21.3)
101
- crass (~> 1.0.2)
102
- nokogiri (>= 1.12.0)
103
- mail (2.8.1)
104
- mini_mime (>= 0.1.1)
105
- net-imap
106
- net-pop
107
- net-smtp
108
- marcel (1.0.2)
109
- method_source (1.0.0)
110
- mini_mime (1.1.5)
111
- minitest (5.18.0)
112
- multipart-post (2.3.0)
113
- net-imap (0.3.7)
114
- date
115
- net-protocol
116
- net-pop (0.1.2)
117
- net-protocol
118
- net-protocol (0.2.1)
119
- timeout
120
- net-smtp (0.3.3)
121
- net-protocol
122
- nio4r (2.5.9)
123
- nokogiri (1.15.4-arm64-darwin)
124
- racc (~> 1.4)
125
- open3 (0.1.2)
126
- parallel (1.23.0)
127
- parser (3.2.2.1)
128
- ast (~> 2.4.1)
129
- racc (1.7.1)
130
- rack (2.2.8)
131
- rack-test (2.1.0)
132
- rack (>= 1.3)
133
- rails (7.0.8)
134
- actioncable (= 7.0.8)
135
- actionmailbox (= 7.0.8)
136
- actionmailer (= 7.0.8)
137
- actionpack (= 7.0.8)
138
- actiontext (= 7.0.8)
139
- actionview (= 7.0.8)
140
- activejob (= 7.0.8)
141
- activemodel (= 7.0.8)
142
- activerecord (= 7.0.8)
143
- activestorage (= 7.0.8)
144
- activesupport (= 7.0.8)
145
- bundler (>= 1.15.0)
146
- railties (= 7.0.8)
147
- rails-dom-testing (2.2.0)
148
- activesupport (>= 5.0.0)
149
- minitest
150
- nokogiri (>= 1.6)
151
- rails-html-sanitizer (1.6.0)
152
- loofah (~> 2.21)
153
- nokogiri (~> 1.14)
154
- railties (7.0.8)
155
- actionpack (= 7.0.8)
156
- activesupport (= 7.0.8)
157
- method_source
158
- rake (>= 12.2)
159
- thor (~> 1.0)
160
- zeitwerk (~> 2.5)
161
- rainbow (3.1.1)
162
- rake (13.0.6)
163
- regexp_parser (2.8.0)
164
- rexml (3.2.5)
165
- rspec (3.12.0)
166
- rspec-core (~> 3.12.0)
167
- rspec-expectations (~> 3.12.0)
168
- rspec-mocks (~> 3.12.0)
169
- rspec-core (3.12.2)
170
- rspec-support (~> 3.12.0)
171
- rspec-expectations (3.12.3)
172
- diff-lcs (>= 1.2.0, < 2.0)
173
- rspec-support (~> 3.12.0)
174
- rspec-mocks (3.12.6)
175
- diff-lcs (>= 1.2.0, < 2.0)
176
- rspec-support (~> 3.12.0)
177
- rspec-rails (6.0.3)
178
- actionpack (>= 6.1)
179
- activesupport (>= 6.1)
180
- railties (>= 6.1)
181
- rspec-core (~> 3.12)
182
- rspec-expectations (~> 3.12)
183
- rspec-mocks (~> 3.12)
184
- rspec-support (~> 3.12)
185
- rspec-support (3.12.1)
186
- rubocop (1.50.2)
187
- json (~> 2.3)
188
- parallel (~> 1.10)
189
- parser (>= 3.2.0.0)
190
- rainbow (>= 2.2.2, < 4.0)
191
- regexp_parser (>= 1.8, < 3.0)
192
- rexml (>= 3.2.5, < 4.0)
193
- rubocop-ast (>= 1.28.0, < 2.0)
194
- ruby-progressbar (~> 1.7)
195
- unicode-display_width (>= 2.4.0, < 3.0)
196
- rubocop-ast (1.28.1)
197
- parser (>= 3.2.1.0)
198
- rubocop-performance (1.16.0)
199
- rubocop (>= 1.7.0, < 2.0)
200
- rubocop-ast (>= 0.4.0)
201
- ruby-openai (4.1.0)
202
- faraday (>= 1)
203
- faraday-multipart (>= 1)
204
- ruby-progressbar (1.13.0)
205
- ruby2_keywords (0.0.5)
206
- shoulda-matchers (5.3.0)
207
- activesupport (>= 5.2.0)
208
- standard (1.28.2)
209
- language_server-protocol (~> 3.17.0.2)
210
- lint_roller (~> 1.0)
211
- rubocop (~> 1.50.2)
212
- standard-custom (~> 1.0.0)
213
- standard-performance (~> 1.0.1)
214
- standard-custom (1.0.0)
215
- lint_roller (~> 1.0)
216
- standard-performance (1.0.1)
217
- lint_roller (~> 1.0)
218
- rubocop-performance (~> 1.16.0)
219
- thor (1.2.2)
220
- timeout (0.4.0)
221
- tzinfo (2.0.6)
222
- concurrent-ruby (~> 1.0)
223
- unicode-display_width (2.4.2)
224
- websocket-driver (0.7.6)
225
- websocket-extensions (>= 0.1.0)
226
- websocket-extensions (0.1.5)
227
- zeitwerk (2.6.8)
228
-
229
- PLATFORMS
230
- arm64-darwin-22
231
-
232
- DEPENDENCIES
233
- ai_refactor!
234
- dotenv
235
- minitest (~> 5.0)
236
- rails
237
- rake (~> 13.0)
238
- rspec
239
- rspec-rails
240
- shoulda-matchers
241
- standard (~> 1.3)
242
-
243
- BUNDLED WITH
244
- 2.4.10
data/examples/.gitignore DELETED
@@ -1 +0,0 @@
1
- ex1_input_test.rb