sloprb 0.0.1 → 0.1.1

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: 6ff98879a675d5126bf4e37c9401d8d87fa35e0cdb42e033abc7ab4136aa53fd
4
- data.tar.gz: 745f8d3681d84fe32cc2ea7a09d24e9ed96aa06bbfbc67674b9f20538a82c6f5
3
+ metadata.gz: 58e1a220d3b716251ffc2d18e26eba840c87010b06c87d2551f5a3838dc9bc85
4
+ data.tar.gz: e595902a25e97cc83b841689c814e85d32bb90ba657d57ab0b0c7668cb748b84
5
5
  SHA512:
6
- metadata.gz: 2f7be175ddca3b762712a0316f9901c0c7142cefa3588824a799eb5a0d7eaf132f13930a8afb0d68f944f8bb9e775d5c559a2db53e1aeb3a02e6f2f1cdd93bda
7
- data.tar.gz: 013c7d4091e2254d5dc7fddd5862e993dbee44e5a7159c55f408ca4127c4265d68e901c818bd37adf7288d979dc265148c541d9492b4ff75c9ee9e4e10d6aeb7
6
+ metadata.gz: ade7937bcab79f4073a295a2942c1b996779fdad9d47f6d274f8b34ff1355c3f7a57136d212f510274fec12c1622801236dd336e0a6e817941ad56696b5d5740
7
+ data.tar.gz: 2cc575c4e56be00cbb73ef57f8e8bb7b5f3ce46188eeeeecbff18ea121ba457405535872a4975a86eb5f153adecbbcbf1b428426b1b0766acbfb85dd867cf693
data/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
1
  # Change log
2
2
 
3
3
  ## master
4
+
5
+ ## 0.1.1 (2026-05-28)
6
+
7
+ - Get the source path from SyntaxError in Typoeater.
8
+
9
+ ## 0.1.0 (2026-05-28)
10
+
11
+ - Initial release. ([@palkan][])
12
+
13
+ [@palkan]: https://github.com/palkan
data/README.md CHANGED
@@ -3,45 +3,163 @@
3
3
 
4
4
  # Sloprb
5
5
 
6
- TBD
6
+ Stop writing code, let LLMs slop it for you at boot time 🦾.
7
+
8
+ SlopRB uses [Require Hooks][require-hooks] to intercept Ruby's `require` calls and generate some code for you using LLMs. Currently supported scenarios:
9
+ - [Slop method implementations](#slopping-methods) on the fly. Just mark a method with `# :slop:`, describe what it should do in comments, and SlopRB fills in the body when the file is loaded.
10
+ - [Auto-correct syntax errors](#eating-typos). When loading a file fails with a SyntaxError, the LLM fixes it, persists the fix, and retries the load.
7
11
 
8
12
  ## Installation
9
13
 
10
- Adding to a gem:
14
+ Add to your Gemfile:
15
+
16
+ ```ruby
17
+ gem "sloprb"
18
+ ```
19
+
20
+ ## Slopping methods
21
+
22
+ 1. You write a method stub with a `# :slop:` marker and optional doc comments describing the desired behavior.
23
+ 2. When the file is required, SlopRB parses it with [Prism](https://github.com/ruby/prism), extracts all slop-marked methods, and sends the source to an LLM.
24
+ 3. The LLM generates the method bodies, SlopRB splices them into the source, validates syntax, and returns the transformed code to Ruby.
25
+
26
+ Consider an example:
11
27
 
12
28
  ```ruby
13
- # my-cool-gem.gemspec
14
- Gem::Specification.new do |spec|
15
- # ...
16
- spec.add_dependency "sloprb"
17
- # ...
29
+ class Calculator
30
+ # Evaluates the passed arithmetic expression.
31
+ def evaluate(expr) # :slop:
32
+ end
18
33
  end
34
+
35
+ puts Calculator.new.evaluate("2 + 2 * 3") #=> 8
19
36
  ```
20
37
 
21
- Or adding to your project:
38
+ You can also provide a sketch of the method or some hints in the body:
22
39
 
23
40
  ```ruby
24
- # Gemfile
25
- gem "sloprb"
41
+ class Greeting
42
+ # Generate a friendly greeting message for the given name.
43
+ def greet(name) # :slop:
44
+ stable_index = ... # generate stable index based on name
45
+ samples = [...] # three random greeting phrases (avoid common, most popular options, be creative)
46
+ # return <greeting>, <name> in the end
47
+ end
48
+ end
49
+
50
+ puts Greeting.new.greet("Vova")
51
+ ```
52
+
53
+ ### Setup
54
+
55
+ Load `sloprb/setup` before any code containing slop-marked methods:
56
+
57
+ ```ruby
58
+ require "sloprb/setup"
26
59
  ```
27
60
 
28
- ### Supported Ruby versions
61
+ This configures the LLM provider (auto-detected from environment variables) and registers the Require Hooks source transformer.
29
62
 
30
- - Ruby (MRI) >= 3.0
63
+ ### Using with `ruby` executable
31
64
 
32
- ## Usage
65
+ You can also setup SlopRB via a command-line switch (which is just a `#require` statement):
33
66
 
34
- TBD
67
+ ```sh
68
+ ruby -rbslop examples/calculator.rb
69
+ ```
35
70
 
36
- ## Contributing
71
+ Use `-rbslop/debug` to also write the generated source to `<path>.slop.rb` files:
37
72
 
38
- Bug reports and pull requests are welcome on GitHub at [https://github.com/palkan/sloprb](https://github.com/palkan/sloprb).
73
+ ```sh
74
+ ruby -rbslop/debug examples/greeting.rb
75
+ ```
76
+
77
+ ### Marking methods
78
+
79
+ Add `# :slop:` as a trailing comment on any `def` line:
80
+
81
+ ```ruby
82
+ class Stoplight
83
+ COLORS = %i[green yellow red].freeze
84
+
85
+ # Initialize the stoplight with a starting color.
86
+ # Default to green.
87
+ def initialize(color = :green) # :slop:
88
+ end
89
+
90
+ # Advance the stoplight to the next color in the cycle:
91
+ # green -> yellow -> red -> green
92
+ def next # :slop:
93
+ end
94
+ end
95
+ ```
96
+
97
+ Comments immediately above the `def` line are sent to the LLM as guidance. The enclosing class/module context, method parameters, and surrounding source are also included in the prompt.
39
98
 
40
- ## Credits
99
+ ### Caching with Bootsnap
41
100
 
42
- This gem is generated via [`newgem` template](https://github.com/palkan/newgem) by [@palkan](https://github.com/palkan).
101
+ If you use [Bootsnap][], the generated code is automatically cached and invalidated on every source file change thanks to the Bootsnap support in Require Hooks. You can try it yourself using our examples:
102
+
103
+ ```ruby
104
+ $ OPENAI_API_KEY=<your key> bundle exec ruby -Ilib -r ./examples/bootsnap -rbslop examples/calculator.rb "42 / 7"
105
+
106
+ 6.0
107
+
108
+ # now, you can run it without LLM creds, and it will still work
109
+ bundle exec ruby -Ilib -r ./examples/bootsnap -rbslop examples/calculator.rb "25 + 26"
110
+
111
+ 51.0
112
+ ```
113
+
114
+ ## Eating typos
115
+
116
+ SlopRB's _Typoeater_ extension automatically fixes syntax errors. When a file fails to load with a `SyntaxError`, the LLM attempts to fix it, validates the correction with Prism, and retries the load — transparently.
117
+
118
+ ```ruby
119
+ require "sloprb/typoeater"
120
+ ```
121
+
122
+ Or via command line:
123
+
124
+ ```sh
125
+ ruby -r sloprb/typoeater my_script.rb
126
+ ```
127
+
128
+ When a required file has a syntax error, Typoeater:
129
+ 1. Captures the error and reads the file source
130
+ 2. Sends both to the LLM for correction
131
+ 3. Validates the fix with Prism (bad LLM output = original error raised, file untouched)
132
+ 4. Overwrites the file and retries the load (once)
133
+
134
+ Typoeater works independently from slop method generation — you can use either or both. When both are active, they share the same LLM configuration.
135
+
136
+ ## LLM configuration
137
+
138
+ SlopRB auto-detects the LLM provider from environment variables, checked in this order:
139
+
140
+ | Provider | Required env var | Optional env vars |
141
+ |-----------|----------------------|---------------------------|
142
+ | OpenAI | `OPENAI_API_KEY` | `SLOPRB_MODEL` |
143
+ | Anthropic | `ANTHROPIC_API_KEY` | `SLOPRB_MODEL` |
144
+ | Ollama | `OLLAMA_BASE_URL`, `SLOPRB_MODEL` | |
145
+
146
+ For OpenAI and Anthropic, `SLOPRB_MODEL` is optional (sensible defaults are used). For Ollama, it is required.
147
+
148
+ Set `SLOPRB_MODEL` to override the default model:
149
+
150
+ ```sh
151
+ SLOPRB_MODEL=claude-sonnet-4-6 ruby -r bslop examples/calculator.rb
152
+ ```
153
+
154
+ Enable debug output with `SLOPRB_DEBUG=1` to write `.slop.rb` files with the generated source.
155
+
156
+ ## Contributing
157
+
158
+ Bug reports and pull requests are welcome on GitHub at [https://github.com/palkan/sloprb](https://github.com/palkan/sloprb).
43
159
 
44
160
  ## License
45
161
 
46
162
  The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
47
163
 
164
+ [require-hooks]: https://github.com/ruby-next/require-hooks
165
+ [Bootsnap]: https://github.com/rails/bootsnap
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ ENV["SLOPRB_DEBUG"] = "1"
4
+ require "bslop"
data/lib/bslop.rb ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "sloprb/setup"
4
+
5
+ if $0 && File.exist?($0)
6
+ load($0)
7
+ exit!(0)
8
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sloprb
4
+ class Configuration
5
+ PROVIDERS = [
6
+ [:openai, ->(env) { env["OPENAI_API_KEY"] }, ->(env) {
7
+ {openai_api_key: env["OPENAI_API_KEY"]}
8
+ }],
9
+ [:anthropic, ->(env) { env["ANTHROPIC_API_KEY"] }, ->(env) {
10
+ {anthropic_api_key: env["ANTHROPIC_API_KEY"]}
11
+ }],
12
+ [:ollama, ->(env) { env["OLLAMA_BASE_URL"] }, ->(env) {
13
+ base = env["OLLAMA_BASE_URL"].chomp("/")
14
+ base += "/v1" unless base.end_with?("/v1")
15
+ {openai_api_key: "ollama", ollama_api_base: base}
16
+ }]
17
+ ].freeze
18
+
19
+ attr_reader :provider, :model
20
+
21
+ def initialize(env = ENV)
22
+ @env = env
23
+ @provider, @config = detect_provider(env)
24
+ @model = env.fetch("SLOPRB_MODEL") { default_model }
25
+ @configured = false
26
+ end
27
+
28
+ def configure_ruby_llm!
29
+ raise "sloprb: SLOPRB_MODEL is required for the #{@provider} provider." unless @model
30
+
31
+ RubyLLM.configure do |c|
32
+ @config.each { |k, v| c.public_send(:"#{k}=", v) }
33
+ c.log_level = :unknown unless @env["SLOPRB_DEBUG"]
34
+ end
35
+ end
36
+
37
+ def ensure_ruby_llm_configured!
38
+ return if @configured
39
+
40
+ raise "sloprb: No LLM provider configured. Set OPENAI_API_KEY, ANTHROPIC_API_KEY, or OLLAMA_BASE_URL." unless @provider
41
+
42
+ @configured = true
43
+
44
+ configure_ruby_llm!
45
+ RubyLLM::Models.refresh! if provider == :ollama
46
+ end
47
+
48
+ private
49
+
50
+ def detect_provider(env)
51
+ PROVIDERS.each do |name, detect, config|
52
+ return [name, config.call(env)] if detect.call(env)
53
+ end
54
+
55
+ []
56
+ end
57
+
58
+ def default_model
59
+ case provider
60
+ when :openai then "gpt-5.3-codex"
61
+ when :anthropic then "claude-opus-4-6"
62
+ when :ollama then nil
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sloprb
4
+ module Generator
5
+ SYSTEM_PROMPT = <<~PROMPT
6
+ You are a Ruby code generator. You will be given a Ruby source file containing method stubs marked with `# :slop:`.
7
+ Your job is to generate the implementation for each marked method.
8
+
9
+ Some methods may contain sketch code, incomplete expressions (like `...`), pseudo-code, or comment instructions in their body.
10
+ Treat these as structural hints and guidance for your implementation — fill in the blanks, replace placeholders,
11
+ and follow the instructions to produce a complete working method body.
12
+
13
+ Rules:
14
+ - Return ONLY the method bodies, not the full method definitions
15
+ - Use `### method_name` as a delimiter before each method body
16
+ - Do not include `def` or `end` lines
17
+ - Use the comments above each method and any sketch code inside the method as guidance
18
+ - Use the class/module context to understand the domain
19
+ - Write idiomatic Ruby
20
+ PROMPT
21
+
22
+ class << self
23
+ def call(source, slop_methods, chat: nil)
24
+ chat ||= default_chat
25
+
26
+ user_prompt = build_prompt(source, slop_methods)
27
+ response = chat.with_instructions(SYSTEM_PROMPT).ask(user_prompt)
28
+
29
+ parse_response(response.content, slop_methods)
30
+ end
31
+
32
+ private
33
+
34
+ def default_chat
35
+ Sloprb.configuration.ensure_ruby_llm_configured!
36
+ RubyLLM.chat(model: Sloprb.configuration.model)
37
+ end
38
+
39
+ def build_prompt(source, slop_methods)
40
+ method_list = slop_methods.map { |m|
41
+ desc = m.leading_comments.empty? ? "" : "\n Comments: #{m.leading_comments}"
42
+ sketch = m.body_sketch.empty? ? "" : "\n Sketch:\n#{m.body_sketch.lines.map { |l| " #{l}" }.join}"
43
+ "- #{m.name}#{m.parameters}#{desc}#{sketch}"
44
+ }.join("\n")
45
+
46
+ <<~PROMPT
47
+ Here is the Ruby source file:
48
+
49
+ ```ruby
50
+ #{source}
51
+ ```
52
+
53
+ Generate implementations for these methods:
54
+ #{method_list}
55
+
56
+ Return only the method bodies using `### method_name` delimiters.
57
+ PROMPT
58
+ end
59
+
60
+ def parse_response(content, slop_methods)
61
+ bodies = {}
62
+ current_method = nil
63
+ current_lines = []
64
+
65
+ content.each_line do |line|
66
+ if line.match?(/^```\w*\s*$/)
67
+ next
68
+ elsif line.match?(/^###\s+\S+/)
69
+ if current_method
70
+ bodies[current_method] = current_lines.join.strip
71
+ end
72
+ current_method = line.strip.sub(/^###\s+/, "")
73
+ current_lines = []
74
+ else
75
+ current_lines << line
76
+ end
77
+ end
78
+
79
+ bodies[current_method] = current_lines.join.strip if current_method
80
+
81
+ missing = slop_methods.map(&:name) - bodies.keys
82
+ unless missing.empty?
83
+ raise "sloprb: LLM response missing implementations for: #{missing.join(", ")}"
84
+ end
85
+
86
+ bodies
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,112 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sloprb
4
+ module Parser
5
+ SlopMethod = Data.define(:name, :parameters, :start_offset, :end_offset, :leading_comments, :enclosing_context, :start_column, :body_sketch)
6
+
7
+ class Visitor < Prism::Visitor
8
+ attr_reader :slop_methods
9
+
10
+ def initialize(source, comments)
11
+ super()
12
+ @source = source
13
+ @comments = comments
14
+ @context_stack = []
15
+ @slop_methods = []
16
+ end
17
+
18
+ def visit_class_node(node)
19
+ @context_stack.push(constant_name(node))
20
+ super
21
+ @context_stack.pop
22
+ end
23
+
24
+ def visit_module_node(node)
25
+ @context_stack.push(constant_name(node))
26
+ super
27
+ @context_stack.pop
28
+ end
29
+
30
+ def visit_def_node(node)
31
+ def_line = node.location.start_line
32
+
33
+ trailing = @comments.find { |c|
34
+ c.location.start_line == def_line &&
35
+ c.location.start_column > node.name_loc.end_column
36
+ }
37
+
38
+ if trailing&.location&.slice&.include?(":slop:")
39
+ params = node.parameters ? node.location.slice[/\(.*?\)/] : nil
40
+ leading = collect_leading_comments(def_line)
41
+ sketch = extract_body_sketch(node)
42
+
43
+ @slop_methods << SlopMethod.new(
44
+ name: node.name.to_s,
45
+ parameters: params,
46
+ start_offset: node.location.start_offset,
47
+ end_offset: node.location.end_offset,
48
+ leading_comments: leading,
49
+ enclosing_context: @context_stack.dup,
50
+ start_column: node.location.start_column,
51
+ body_sketch: sketch
52
+ )
53
+ end
54
+
55
+ super
56
+ end
57
+
58
+ private
59
+
60
+ def constant_name(node)
61
+ node.constant_path.full_name
62
+ rescue Prism::DynamicPartsInConstantPathError
63
+ node.constant_path.slice
64
+ end
65
+
66
+ def extract_body_sketch(node)
67
+ end_kw = node.end_keyword_loc
68
+ return "" unless end_kw
69
+
70
+ def_line_end = @source.index("\n", node.location.start_offset)
71
+ return "" unless def_line_end
72
+
73
+ body_start = def_line_end + 1
74
+ body_end = end_kw.start_offset
75
+ return "" if body_start >= body_end
76
+
77
+ raw = @source[body_start...body_end]
78
+ dedent(raw).strip
79
+ end
80
+
81
+ def dedent(text)
82
+ lines = text.lines
83
+ non_blank = lines.reject { |l| l.strip.empty? }
84
+ return text if non_blank.empty?
85
+
86
+ min_indent = non_blank.map { |l| l[/^ */].length }.min
87
+ lines.map { |l| l.sub(/^ {0,#{min_indent}}/, "") }.join
88
+ end
89
+
90
+ def collect_leading_comments(def_line)
91
+ lines = []
92
+ line = def_line - 1
93
+
94
+ while line >= 1
95
+ comment = @comments.find { |c| c.location.start_line == line }
96
+ break unless comment
97
+ lines.unshift(comment.location.slice)
98
+ line -= 1
99
+ end
100
+
101
+ lines.join("\n")
102
+ end
103
+ end
104
+
105
+ def self.call(source)
106
+ result = Prism.parse(source)
107
+ visitor = Visitor.new(source, result.comments)
108
+ visitor.visit(result.value)
109
+ visitor.slop_methods
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "sloprb"
4
+
5
+ Sloprb.setup
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sloprb
4
+ module Transformer
5
+ class SyntaxError < ::SyntaxError; end
6
+
7
+ class << self
8
+ def call(path, source, chat: nil)
9
+ source ||= File.read(path)
10
+
11
+ return unless source.include?(":slop:")
12
+
13
+ slop_methods = Parser.call(source)
14
+ return if slop_methods.empty?
15
+
16
+ bodies = Generator.call(source, slop_methods, chat:)
17
+ transformed = splice(source, slop_methods, bodies)
18
+
19
+ validate_syntax!(transformed)
20
+
21
+ if ENV["SLOPRB_DEBUG"]
22
+ File.write("#{path.sub(/\.rb$/, "")}.slop.rb", transformed)
23
+ end
24
+
25
+ transformed
26
+ rescue => e
27
+ raise if e.is_a?(SyntaxError)
28
+ warn "sloprb: Failed to generate methods for #{path}: #{e.message}"
29
+ nil
30
+ end
31
+
32
+ private
33
+
34
+ def splice(source, slop_methods, bodies)
35
+ result = source.dup
36
+
37
+ slop_methods.sort_by(&:start_offset).reverse_each do |method|
38
+ body = bodies[method.name]
39
+ indent = " " * (method.start_column + 2)
40
+ indented_body = body.lines.map { |line| "#{indent}#{line}" }.join.rstrip
41
+
42
+ params = method.parameters || ""
43
+ replacement = "def #{method.name}#{params}\n#{indented_body}\n#{" " * method.start_column}end"
44
+
45
+ result[method.start_offset...method.end_offset] = replacement
46
+ end
47
+
48
+ result
49
+ end
50
+
51
+ def validate_syntax!(source)
52
+ result = Prism.parse(source)
53
+ return if result.errors.empty?
54
+
55
+ raise SyntaxError, "sloprb: Generated source has syntax errors:\n#{result.errors.map(&:message).join("\n")}\n\nSource:\n#{source}"
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "sloprb"
4
+
5
+ module Sloprb
6
+ module Typoeater
7
+ SYSTEM_PROMPT = <<~PROMPT
8
+ You are a Ruby syntax error fixer. You will be given a Ruby source file that has a syntax error, along with the error message.
9
+ Your job is to fix the syntax error and return the corrected source file.
10
+
11
+ Rules:
12
+ - Return ONLY the complete corrected Ruby source file
13
+ - Do not include any explanation, comments about the fix, or markdown formatting
14
+ - Do not change any logic or behavior — only fix the syntax error
15
+ - Preserve all existing comments, whitespace style, and formatting
16
+ PROMPT
17
+
18
+ class << self
19
+ def call(path, error, chat: nil)
20
+ chat ||= default_chat
21
+
22
+ source = File.read(path)
23
+ error_context = error.respond_to?(:detailed_message) ? error.detailed_message(highlight: false) : error.message
24
+
25
+ user_prompt = <<~PROMPT
26
+ Here is the Ruby source file with a syntax error:
27
+
28
+ ```ruby
29
+ #{source}
30
+ ```
31
+
32
+ Syntax error:
33
+ #{error_context}
34
+
35
+ Return the complete corrected Ruby source file.
36
+ PROMPT
37
+
38
+ response = chat.with_instructions(SYSTEM_PROMPT).ask(user_prompt)
39
+ corrected = strip_fences(response.content)
40
+ corrected << "\n" unless corrected.end_with?("\n")
41
+
42
+ result = Prism.parse(corrected)
43
+ return if result.errors.any?
44
+
45
+ corrected
46
+ rescue => e
47
+ warn "[sloprb] failed to autocorrect #{path}: #{e.message}" if ENV["SLOPRB_DEBUG"]
48
+ nil
49
+ end
50
+
51
+ def register_hook
52
+ require "require-hooks/setup"
53
+
54
+ RequireHooks.around_load do |path, &load_block|
55
+ load_block.call
56
+ rescue ::SyntaxError => original_error
57
+ error_path = original_error.path
58
+ corrected = Typoeater.call(error_path, original_error)
59
+ raise original_error unless corrected
60
+
61
+ File.write(error_path, corrected)
62
+
63
+ warn "[sloprb] auto-corrected syntax error in #{error_path}"
64
+
65
+ begin
66
+ load(error_path)
67
+ rescue ::SyntaxError
68
+ raise original_error
69
+ end
70
+ end
71
+ end
72
+
73
+ private
74
+
75
+ def default_chat
76
+ Sloprb.configuration.ensure_ruby_llm_configured!
77
+ RubyLLM.chat(model: Sloprb.configuration.model)
78
+ end
79
+
80
+ def strip_fences(content)
81
+ content.sub(/\A\s*```\w*\n/, "").sub(/\n```\s*\z/, "")
82
+ end
83
+ end
84
+ end
85
+ end
86
+
87
+ Sloprb.configuration ||= Sloprb::Configuration.new
88
+ Sloprb::Typoeater.register_hook
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sloprb # :nodoc:
4
- VERSION = "0.0.1"
4
+ VERSION = "0.1.1"
5
5
  end
data/lib/sloprb.rb CHANGED
@@ -1,3 +1,28 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "prism"
4
+ require "ruby_llm"
5
+
3
6
  require "sloprb/version"
7
+ require "sloprb/configuration"
8
+ require "sloprb/parser"
9
+ require "sloprb/generator"
10
+ require "sloprb/transformer"
11
+
12
+ module Sloprb
13
+ class << self
14
+ attr_accessor :configuration
15
+
16
+ def setup(env = ENV)
17
+ @configuration = Configuration.new(env)
18
+ register_hook
19
+ end
20
+
21
+ def register_hook
22
+ require "require-hooks/setup"
23
+ RequireHooks.source_transform do |path, source|
24
+ Transformer.call(path, source)
25
+ end
26
+ end
27
+ end
28
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sloprb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vova Dem
@@ -9,20 +9,48 @@ bindir: bin
9
9
  cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: require-hooks
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '0'
19
+ type: :runtime
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: ruby_llm
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
12
40
  - !ruby/object:Gem::Dependency
13
41
  name: bundler
14
42
  requirement: !ruby/object:Gem::Requirement
15
43
  requirements:
16
44
  - - ">="
17
45
  - !ruby/object:Gem::Version
18
- version: '4.0'
46
+ version: '2.6'
19
47
  type: :development
20
48
  prerelease: false
21
49
  version_requirements: !ruby/object:Gem::Requirement
22
50
  requirements:
23
51
  - - ">="
24
52
  - !ruby/object:Gem::Version
25
- version: '4.0'
53
+ version: '2.6'
26
54
  - !ruby/object:Gem::Dependency
27
55
  name: rake
28
56
  requirement: !ruby/object:Gem::Requirement
@@ -61,7 +89,15 @@ files:
61
89
  - CHANGELOG.md
62
90
  - LICENSE.txt
63
91
  - README.md
92
+ - lib/bslop.rb
93
+ - lib/bslop/debug.rb
64
94
  - lib/sloprb.rb
95
+ - lib/sloprb/configuration.rb
96
+ - lib/sloprb/generator.rb
97
+ - lib/sloprb/parser.rb
98
+ - lib/sloprb/setup.rb
99
+ - lib/sloprb/transformer.rb
100
+ - lib/sloprb/typoeater.rb
65
101
  - lib/sloprb/version.rb
66
102
  homepage: https://github.com/palkan/sloprb
67
103
  licenses: