rubyn 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 +251 -0
- data/Rakefile +12 -0
- data/exe/rubyn +5 -0
- data/lib/generators/rubyn/install_generator.rb +16 -0
- data/lib/rubyn/cli.rb +85 -0
- data/lib/rubyn/client/api_client.rb +172 -0
- data/lib/rubyn/commands/agent.rb +191 -0
- data/lib/rubyn/commands/base.rb +60 -0
- data/lib/rubyn/commands/config.rb +51 -0
- data/lib/rubyn/commands/dashboard.rb +85 -0
- data/lib/rubyn/commands/index.rb +101 -0
- data/lib/rubyn/commands/init.rb +166 -0
- data/lib/rubyn/commands/refactor.rb +175 -0
- data/lib/rubyn/commands/review.rb +61 -0
- data/lib/rubyn/commands/spec.rb +72 -0
- data/lib/rubyn/commands/usage.rb +56 -0
- data/lib/rubyn/config/credentials.rb +39 -0
- data/lib/rubyn/config/project_config.rb +42 -0
- data/lib/rubyn/config/settings.rb +53 -0
- data/lib/rubyn/context/codebase_indexer.rb +195 -0
- data/lib/rubyn/context/context_builder.rb +36 -0
- data/lib/rubyn/context/file_resolver.rb +235 -0
- data/lib/rubyn/context/project_scanner.rb +132 -0
- data/lib/rubyn/engine/app/assets/images/rubyn/RubynLogo.png +0 -0
- data/lib/rubyn/engine/app/assets/javascripts/rubyn/application.js +579 -0
- data/lib/rubyn/engine/app/assets/stylesheets/rubyn/application.css +1073 -0
- data/lib/rubyn/engine/app/controllers/rubyn/agent_controller.rb +26 -0
- data/lib/rubyn/engine/app/controllers/rubyn/application_controller.rb +44 -0
- data/lib/rubyn/engine/app/controllers/rubyn/dashboard_controller.rb +19 -0
- data/lib/rubyn/engine/app/controllers/rubyn/feedback_controller.rb +17 -0
- data/lib/rubyn/engine/app/controllers/rubyn/files_controller.rb +54 -0
- data/lib/rubyn/engine/app/controllers/rubyn/refactor_controller.rb +56 -0
- data/lib/rubyn/engine/app/controllers/rubyn/reviews_controller.rb +32 -0
- data/lib/rubyn/engine/app/controllers/rubyn/settings_controller.rb +17 -0
- data/lib/rubyn/engine/app/controllers/rubyn/specs_controller.rb +33 -0
- data/lib/rubyn/engine/app/views/layouts/rubyn/application.html.erb +63 -0
- data/lib/rubyn/engine/app/views/rubyn/agent/show.html.erb +22 -0
- data/lib/rubyn/engine/app/views/rubyn/dashboard/index.html.erb +120 -0
- data/lib/rubyn/engine/app/views/rubyn/files/index.html.erb +45 -0
- data/lib/rubyn/engine/app/views/rubyn/refactor/show.html.erb +28 -0
- data/lib/rubyn/engine/app/views/rubyn/reviews/show.html.erb +28 -0
- data/lib/rubyn/engine/app/views/rubyn/settings/show.html.erb +42 -0
- data/lib/rubyn/engine/app/views/rubyn/specs/show.html.erb +28 -0
- data/lib/rubyn/engine/config/routes.rb +13 -0
- data/lib/rubyn/engine/engine.rb +18 -0
- data/lib/rubyn/output/diff_renderer.rb +106 -0
- data/lib/rubyn/output/formatter.rb +123 -0
- data/lib/rubyn/output/spinner.rb +26 -0
- data/lib/rubyn/tools/base_tool.rb +74 -0
- data/lib/rubyn/tools/bundle_add.rb +77 -0
- data/lib/rubyn/tools/create_file.rb +32 -0
- data/lib/rubyn/tools/delete_file.rb +29 -0
- data/lib/rubyn/tools/executor.rb +68 -0
- data/lib/rubyn/tools/find_files.rb +33 -0
- data/lib/rubyn/tools/find_references.rb +72 -0
- data/lib/rubyn/tools/git_commit.rb +65 -0
- data/lib/rubyn/tools/git_create_branch.rb +58 -0
- data/lib/rubyn/tools/git_diff.rb +42 -0
- data/lib/rubyn/tools/git_log.rb +43 -0
- data/lib/rubyn/tools/git_status.rb +26 -0
- data/lib/rubyn/tools/list_directory.rb +82 -0
- data/lib/rubyn/tools/move_file.rb +35 -0
- data/lib/rubyn/tools/patch_file.rb +47 -0
- data/lib/rubyn/tools/rails_generate.rb +40 -0
- data/lib/rubyn/tools/rails_migrate.rb +55 -0
- data/lib/rubyn/tools/rails_routes.rb +35 -0
- data/lib/rubyn/tools/read_file.rb +45 -0
- data/lib/rubyn/tools/registry.rb +28 -0
- data/lib/rubyn/tools/run_command.rb +48 -0
- data/lib/rubyn/tools/run_tests.rb +52 -0
- data/lib/rubyn/tools/search_files.rb +82 -0
- data/lib/rubyn/tools/write_file.rb +30 -0
- data/lib/rubyn/version.rb +5 -0
- data/lib/rubyn/version_checker.rb +74 -0
- data/lib/rubyn.rb +95 -0
- data/sig/rubyn.rbs +4 -0
- metadata +379 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "open3"
|
|
4
|
+
require "timeout"
|
|
5
|
+
require_relative "base_tool"
|
|
6
|
+
require_relative "registry"
|
|
7
|
+
|
|
8
|
+
module Rubyn
|
|
9
|
+
module Tools
|
|
10
|
+
class RunCommand < BaseTool
|
|
11
|
+
DESCRIPTION = "Execute a shell command in the project directory"
|
|
12
|
+
PARAMETERS = {
|
|
13
|
+
command: { type: :string, description: "Shell command to execute", required: true },
|
|
14
|
+
timeout: { type: :integer, description: "Timeout in seconds (default 30)", required: false }
|
|
15
|
+
}.freeze
|
|
16
|
+
REQUIRES_CONFIRMATION = true
|
|
17
|
+
|
|
18
|
+
DEFAULT_TIMEOUT = 30
|
|
19
|
+
|
|
20
|
+
def execute(params)
|
|
21
|
+
command = params[:command]
|
|
22
|
+
return error("command is required") unless command && !command.strip.empty?
|
|
23
|
+
|
|
24
|
+
timeout_seconds = (params[:timeout] || DEFAULT_TIMEOUT).to_i
|
|
25
|
+
|
|
26
|
+
stdout, stderr, status = nil
|
|
27
|
+
begin
|
|
28
|
+
Timeout.timeout(timeout_seconds) do
|
|
29
|
+
stdout, stderr, status = Open3.capture3(command, chdir: project_root)
|
|
30
|
+
end
|
|
31
|
+
rescue Timeout::Error
|
|
32
|
+
return error("Command timed out after #{timeout_seconds} seconds")
|
|
33
|
+
rescue StandardError => e
|
|
34
|
+
return error("Failed to execute command: #{e.message}")
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
stdout = truncate_output(stdout)
|
|
38
|
+
stderr = truncate_output(stderr)
|
|
39
|
+
|
|
40
|
+
success(command: command, stdout: stdout, stderr: stderr, exit_code: status.exitstatus)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
Registry.register("run_command", RunCommand)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "open3"
|
|
4
|
+
require_relative "base_tool"
|
|
5
|
+
require_relative "registry"
|
|
6
|
+
|
|
7
|
+
module Rubyn
|
|
8
|
+
module Tools
|
|
9
|
+
class RunTests < BaseTool
|
|
10
|
+
DESCRIPTION = "Run tests for a specific file or the full test suite"
|
|
11
|
+
PARAMETERS = {
|
|
12
|
+
path: { type: :string, description: "Specific test file to run", required: false },
|
|
13
|
+
options: { type: :string, description: "Extra flags like --fail-fast", required: false }
|
|
14
|
+
}.freeze
|
|
15
|
+
REQUIRES_CONFIRMATION = true
|
|
16
|
+
|
|
17
|
+
def execute(params)
|
|
18
|
+
command = detect_test_command
|
|
19
|
+
return error("No test framework detected (no spec/ or test/ directory found)") unless command
|
|
20
|
+
|
|
21
|
+
command = "#{command} #{params[:path]}" if params[:path] && !params[:path].strip.empty?
|
|
22
|
+
command = "#{command} #{params[:options]}" if params[:options] && !params[:options].strip.empty?
|
|
23
|
+
|
|
24
|
+
begin
|
|
25
|
+
stdout, stderr, status = Open3.capture3(command, chdir: project_root)
|
|
26
|
+
rescue StandardError => e
|
|
27
|
+
return error("Failed to run tests: #{e.message}")
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
success(
|
|
31
|
+
command: command,
|
|
32
|
+
stdout: stdout,
|
|
33
|
+
stderr: stderr,
|
|
34
|
+
exit_code: status.exitstatus,
|
|
35
|
+
passed: status.exitstatus.zero?
|
|
36
|
+
)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
def detect_test_command
|
|
42
|
+
if Dir.exist?(File.join(project_root, "spec"))
|
|
43
|
+
"bundle exec rspec"
|
|
44
|
+
elsif Dir.exist?(File.join(project_root, "test"))
|
|
45
|
+
"bundle exec rails test"
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
Registry.register("run_tests", RunTests)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Rubyn
|
|
4
|
+
module Tools
|
|
5
|
+
class SearchFiles < BaseTool
|
|
6
|
+
DESCRIPTION = "Search file contents for a pattern (grep)"
|
|
7
|
+
PARAMETERS = {
|
|
8
|
+
pattern: { type: "string", required: true, description: "Search pattern (regular expression)" },
|
|
9
|
+
path: { type: "string", required: false, description: "Directory to search in (defaults to project root)" },
|
|
10
|
+
file_pattern: { type: "string", required: false, description: "File glob pattern to filter (e.g. '*.rb')" }
|
|
11
|
+
}.freeze
|
|
12
|
+
REQUIRES_CONFIRMATION = false
|
|
13
|
+
|
|
14
|
+
MAX_MATCHES = 100
|
|
15
|
+
MAX_LINE_LENGTH = 500
|
|
16
|
+
MAX_FILE_SIZE = 2_000_000
|
|
17
|
+
|
|
18
|
+
def execute(params)
|
|
19
|
+
return error("Missing required parameter: pattern") unless params[:pattern]
|
|
20
|
+
|
|
21
|
+
begin
|
|
22
|
+
regex = Regexp.new(params[:pattern])
|
|
23
|
+
rescue RegexpError => e
|
|
24
|
+
return error("Invalid regex pattern: #{e.message}")
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
search_path = params[:path] || "."
|
|
28
|
+
file_pattern = params[:file_pattern]
|
|
29
|
+
|
|
30
|
+
resolved = resolve_path(search_path)
|
|
31
|
+
return resolved if resolved.is_a?(Hash) && resolved[:error]
|
|
32
|
+
|
|
33
|
+
return error("Path not found: #{search_path}") unless File.exist?(resolved)
|
|
34
|
+
|
|
35
|
+
matches = []
|
|
36
|
+
glob = file_pattern ? File.join(resolved, "**", file_pattern) : File.join(resolved, "**", "*")
|
|
37
|
+
|
|
38
|
+
Dir.glob(glob).each do |file|
|
|
39
|
+
break if matches.size >= MAX_MATCHES
|
|
40
|
+
next unless File.file?(file)
|
|
41
|
+
next if excluded?(file)
|
|
42
|
+
next if binary?(file)
|
|
43
|
+
|
|
44
|
+
search_in_file(file, regex, matches)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
success(pattern: params[:pattern], matches: matches)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
private
|
|
51
|
+
|
|
52
|
+
def search_in_file(file, regex, matches)
|
|
53
|
+
File.open(file, "r:UTF-8") do |f|
|
|
54
|
+
f.each_line.with_index(1) do |line, line_number|
|
|
55
|
+
break if matches.size >= MAX_MATCHES
|
|
56
|
+
|
|
57
|
+
if line.match?(regex)
|
|
58
|
+
matches << {
|
|
59
|
+
file: relative_path(file),
|
|
60
|
+
line_number: line_number,
|
|
61
|
+
line: line.chomp.slice(0, MAX_LINE_LENGTH)
|
|
62
|
+
}
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
rescue ArgumentError, Encoding::InvalidByteSequenceError, Encoding::UndefinedConversionError
|
|
67
|
+
# Skip files with encoding issues
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def binary?(file)
|
|
71
|
+
return true if File.size(file) > MAX_FILE_SIZE
|
|
72
|
+
|
|
73
|
+
sample = File.read(file, 8192) || ""
|
|
74
|
+
sample.include?("\x00")
|
|
75
|
+
rescue Errno::EACCES, Errno::ENOENT, IOError
|
|
76
|
+
true
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
Rubyn::Tools::Registry.register("search_files", Rubyn::Tools::SearchFiles)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "fileutils"
|
|
4
|
+
require_relative "base_tool"
|
|
5
|
+
require_relative "registry"
|
|
6
|
+
|
|
7
|
+
module Rubyn
|
|
8
|
+
module Tools
|
|
9
|
+
class WriteFile < BaseTool
|
|
10
|
+
DESCRIPTION = "Write content to a file, creating or overwriting it"
|
|
11
|
+
PARAMETERS = {
|
|
12
|
+
path: { type: :string, description: "Path to the file to write", required: true },
|
|
13
|
+
content: { type: :string, description: "Content to write to the file", required: true }
|
|
14
|
+
}.freeze
|
|
15
|
+
REQUIRES_CONFIRMATION = true
|
|
16
|
+
|
|
17
|
+
def execute(params)
|
|
18
|
+
resolved = resolve_path(params[:path])
|
|
19
|
+
return resolved if resolved.is_a?(Hash) && resolved[:error]
|
|
20
|
+
|
|
21
|
+
FileUtils.mkdir_p(File.dirname(resolved))
|
|
22
|
+
bytes_written = File.write(resolved, params[:content])
|
|
23
|
+
|
|
24
|
+
success(path: params[:path], bytes_written: bytes_written)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
Registry.register("write_file", WriteFile)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
require "net/http"
|
|
5
|
+
require "fileutils"
|
|
6
|
+
|
|
7
|
+
module Rubyn
|
|
8
|
+
class VersionChecker
|
|
9
|
+
CACHE_FILE = File.join(Dir.home, ".rubyn", "version_cache.json")
|
|
10
|
+
CACHE_TTL = 86_400 # 24 hours
|
|
11
|
+
RUBYGEMS_URL = "https://rubygems.org/api/v1/versions/rubyn/latest.json"
|
|
12
|
+
|
|
13
|
+
class << self
|
|
14
|
+
def check
|
|
15
|
+
cached = read_cache
|
|
16
|
+
return cached if cached
|
|
17
|
+
|
|
18
|
+
latest = fetch_latest_version
|
|
19
|
+
return nil unless latest
|
|
20
|
+
|
|
21
|
+
write_cache(latest)
|
|
22
|
+
latest
|
|
23
|
+
rescue Net::HTTPError, SocketError, JSON::ParserError, Errno::ENOENT, Errno::EACCES
|
|
24
|
+
nil
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def update_available?
|
|
28
|
+
latest = check
|
|
29
|
+
return false unless latest && Gem::Version.correct?(latest)
|
|
30
|
+
|
|
31
|
+
Gem::Version.new(latest) > Gem::Version.new(Rubyn::VERSION)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def update_message
|
|
35
|
+
latest = check
|
|
36
|
+
return nil unless latest && Gem::Version.correct?(latest)
|
|
37
|
+
return nil unless Gem::Version.new(latest) > Gem::Version.new(Rubyn::VERSION)
|
|
38
|
+
|
|
39
|
+
"Rubyn #{latest} is available (you have #{Rubyn::VERSION}). Run `gem update rubyn` to upgrade."
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
|
|
44
|
+
def fetch_latest_version
|
|
45
|
+
uri = URI(RUBYGEMS_URL)
|
|
46
|
+
response = Net::HTTP.get_response(uri)
|
|
47
|
+
return nil unless response.is_a?(Net::HTTPSuccess)
|
|
48
|
+
|
|
49
|
+
data = JSON.parse(response.body)
|
|
50
|
+
data["version"]
|
|
51
|
+
rescue Net::HTTPError, SocketError, JSON::ParserError, Timeout::Error, Errno::ECONNREFUSED
|
|
52
|
+
nil
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def read_cache
|
|
56
|
+
return nil unless File.exist?(CACHE_FILE)
|
|
57
|
+
|
|
58
|
+
data = JSON.parse(File.read(CACHE_FILE))
|
|
59
|
+
return nil if Time.now.to_i - data["checked_at"].to_i > CACHE_TTL
|
|
60
|
+
|
|
61
|
+
data["version"]
|
|
62
|
+
rescue JSON::ParserError, Errno::ENOENT, Errno::EACCES
|
|
63
|
+
nil
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def write_cache(version)
|
|
67
|
+
FileUtils.mkdir_p(File.dirname(CACHE_FILE))
|
|
68
|
+
File.write(CACHE_FILE, JSON.generate(version: version, checked_at: Time.now.to_i))
|
|
69
|
+
rescue Errno::EACCES, Errno::ENOENT, Errno::ENOSPC
|
|
70
|
+
# Non-critical — skip if we can't write cache
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
data/lib/rubyn.rb
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
begin
|
|
4
|
+
require "dotenv/load"
|
|
5
|
+
rescue LoadError
|
|
6
|
+
# dotenv is optional — only needed for local development with .env files
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
require_relative "rubyn/version"
|
|
10
|
+
require_relative "rubyn/version_checker"
|
|
11
|
+
|
|
12
|
+
module Rubyn
|
|
13
|
+
class Error < StandardError; end
|
|
14
|
+
class AuthenticationError < Error; end
|
|
15
|
+
class ConfigurationError < Error; end
|
|
16
|
+
class APIError < Error; end
|
|
17
|
+
|
|
18
|
+
class Configuration
|
|
19
|
+
attr_accessor :api_url, :api_key
|
|
20
|
+
|
|
21
|
+
def initialize
|
|
22
|
+
@api_url = ENV.fetch("RUBYN_API_URL", "https://app.rubyn.ai")
|
|
23
|
+
@api_key = ENV.fetch("RUBYN_API_KEY", nil)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
class << self
|
|
28
|
+
def configuration
|
|
29
|
+
@configuration ||= Configuration.new
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def configure
|
|
33
|
+
yield(configuration)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def api_client
|
|
37
|
+
@api_client ||= Client::ApiClient.new
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def reset!
|
|
41
|
+
@configuration = nil
|
|
42
|
+
@api_client = nil
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
require_relative "rubyn/config/credentials"
|
|
48
|
+
require_relative "rubyn/config/settings"
|
|
49
|
+
require_relative "rubyn/config/project_config"
|
|
50
|
+
require_relative "rubyn/client/api_client"
|
|
51
|
+
require_relative "rubyn/context/project_scanner"
|
|
52
|
+
require_relative "rubyn/context/file_resolver"
|
|
53
|
+
require_relative "rubyn/context/context_builder"
|
|
54
|
+
require_relative "rubyn/context/codebase_indexer"
|
|
55
|
+
require_relative "rubyn/output/formatter"
|
|
56
|
+
require_relative "rubyn/output/diff_renderer"
|
|
57
|
+
require_relative "rubyn/output/spinner"
|
|
58
|
+
require_relative "rubyn/tools/registry"
|
|
59
|
+
require_relative "rubyn/tools/base_tool"
|
|
60
|
+
require_relative "rubyn/tools/executor"
|
|
61
|
+
require_relative "rubyn/tools/read_file"
|
|
62
|
+
require_relative "rubyn/tools/write_file"
|
|
63
|
+
require_relative "rubyn/tools/create_file"
|
|
64
|
+
require_relative "rubyn/tools/patch_file"
|
|
65
|
+
require_relative "rubyn/tools/delete_file"
|
|
66
|
+
require_relative "rubyn/tools/move_file"
|
|
67
|
+
require_relative "rubyn/tools/list_directory"
|
|
68
|
+
require_relative "rubyn/tools/find_files"
|
|
69
|
+
require_relative "rubyn/tools/search_files"
|
|
70
|
+
require_relative "rubyn/tools/find_references"
|
|
71
|
+
require_relative "rubyn/tools/run_command"
|
|
72
|
+
require_relative "rubyn/tools/run_tests"
|
|
73
|
+
require_relative "rubyn/tools/rails_routes"
|
|
74
|
+
require_relative "rubyn/tools/rails_generate"
|
|
75
|
+
require_relative "rubyn/tools/rails_migrate"
|
|
76
|
+
require_relative "rubyn/tools/bundle_add"
|
|
77
|
+
require_relative "rubyn/tools/git_status"
|
|
78
|
+
require_relative "rubyn/tools/git_diff"
|
|
79
|
+
require_relative "rubyn/tools/git_log"
|
|
80
|
+
require_relative "rubyn/tools/git_commit"
|
|
81
|
+
require_relative "rubyn/tools/git_create_branch"
|
|
82
|
+
require_relative "rubyn/commands/base"
|
|
83
|
+
require_relative "rubyn/commands/init"
|
|
84
|
+
require_relative "rubyn/commands/refactor"
|
|
85
|
+
require_relative "rubyn/commands/spec"
|
|
86
|
+
require_relative "rubyn/commands/review"
|
|
87
|
+
require_relative "rubyn/commands/agent"
|
|
88
|
+
require_relative "rubyn/commands/index"
|
|
89
|
+
require_relative "rubyn/commands/usage"
|
|
90
|
+
require_relative "rubyn/commands/config"
|
|
91
|
+
require_relative "rubyn/commands/dashboard"
|
|
92
|
+
require_relative "rubyn/cli"
|
|
93
|
+
|
|
94
|
+
# Load Rails engine when running inside a Rails app
|
|
95
|
+
require_relative "rubyn/engine/engine" if defined?(Rails::Engine)
|
data/sig/rubyn.rbs
ADDED