Class: RailsAiContext::Tools::Validate

Inherits:
BaseTool
  • Object
show all
Defined in:
lib/rails_ai_context/tools/validate.rb

Constant Summary collapse

VALID_LEVELS =

── Main entry point ─────────────────────────────────────────────

%w[syntax rails].freeze
ASSET_HELPER_PREFIXES =

── CHECK 2: Route helpers (AST) ─────────────────────────────────

%w[image asset font stylesheet javascript audio video file compute_asset auto_discovery_link favicon].freeze
DEVISE_HELPER_NAMES =
%w[session registration password confirmation unlock omniauth_callback user_session user_registration user_password user_confirmation user_unlock].freeze
MEMORY_LOAD_METHODS =

── CHECK: Memory-loading anti-pattern ───────────────────────────

%w[map filter_map flat_map select reject collect reduce inject each_with_object].freeze

Constants inherited from BaseTool

BaseTool::SESSION_CONTEXT, BaseTool::SHARED_CACHE

Class Method Summary collapse

Methods inherited from BaseTool

abstract!, abstract?, cache_key, cached_context, config, extract_method_source_from_file, extract_method_source_from_string, find_closest_match, fuzzy_find_key, inherited, not_found_response, paginate, rails_app, registered_tools, reset_all_caches!, reset_cache!, session_queries, session_record, session_reset!, set_call_params, text_response

Class Method Details

.call(files:, level: "syntax", server_context: nil) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/rails_ai_context/tools/validate.rb', line 42

def self.call(files:, level: "syntax", server_context: nil)
  return text_response("No files provided. Pass file paths relative to Rails root (e.g. files:[\"app/models/cook.rb\"]).") if files.nil? || files.empty?
  return text_response("Too many files (#{files.size}). Maximum is #{max_files} per call.") if files.size > max_files
  return text_response("Unknown level: '#{level}'. Valid values: #{VALID_LEVELS.join(', ')}") unless VALID_LEVELS.include?(level)

  results = []
  passed = 0
  total = 0

  files.each do |file|
    if file.nil? || file.strip.empty?
      results << "- (empty) \u2014 skipped (empty filename)"
      next
    end

    full_path = Rails.root.join(file)

    unless File.exist?(full_path)
      suggestion = find_file_suggestion(file)
      hint = suggestion ? " Did you mean '#{suggestion}'?" : ""
      results << "\u2717 #{file} \u2014 file not found.#{hint}"
      total += 1
      next
    end

    begin
      real = File.realpath(full_path)
      unless real.start_with?(File.realpath(Rails.root))
        results << "\u2717 #{file} \u2014 path not allowed (outside Rails root)"
        total += 1
        next
      end
    rescue Errno::ENOENT
      results << "\u2717 #{file} \u2014 file not found"
      total += 1
      next
    end

    total += 1

    ok, msg, warnings = if file.end_with?(".rb")
      validate_ruby(full_path)
    elsif file.end_with?(".html.erb") || file.end_with?(".erb")
      validate_erb(full_path)
    elsif file.end_with?(".js")
      validate_javascript(full_path)
    else
      results << "- #{file} \u2014 skipped (unsupported file type)"
      total -= 1
      next
    end

    if ok
      results << "\u2713 #{file} \u2014 syntax OK"
      passed += 1
    else
      results << "\u2717 #{file} \u2014 #{msg}"
    end

    (warnings || []).each { |w| results << "  \u26A0 #{w}" }

    if level == "rails" && ok
      rails_warnings = check_rails_semantics(file, full_path)
      rails_warnings.each { |w| results << "  \u26A0 #{w}" }
    end
  end

  # Run Brakeman security scan on validated files (if installed and level:"rails")
  if level == "rails"
    brakeman_warnings = check_brakeman_security(files)
    brakeman_warnings.each { |w| results << "  \u26A0 #{w}" }
  end

  output = results.join("\n")
  output += "\n\n#{passed}/#{total} files passed"
  text_response(output)
end

.max_filesObject



16
17
18
# File 'lib/rails_ai_context/tools/validate.rb', line 16

def self.max_files
  RailsAiContext.configuration.max_validate_files
end