actionmcp 0.82.0 → 0.83.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 +4 -4
 - data/lib/action_mcp/gateway.rb +16 -3
 - data/lib/action_mcp/resource_template.rb +45 -33
 - data/lib/action_mcp/tool.rb +6 -6
 - data/lib/action_mcp/tools_registry.rb +7 -2
 - data/lib/action_mcp/version.rb +1 -1
 - data/lib/tasks/action_mcp_tasks.rake +22 -0
 - metadata +5 -19
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 34a7a67e4f2e58c82a8a06bb11adf328747ed61a38e4c06598b21657556b8779
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 0a81e9eaec25dc3906a9476fff4c9458da889fd201cb644b46ba1074ea46d5ad
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 76e455eefa6f0fb9c055d4a799ba38f09993c7562746733c05e15e8bc256df112e24788989dce2dbe0bfa290b77eedc54f89a480422a6805050bde18fbb51d2f
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 8c2fb33e02738de33451097b92c743acf053bdd759be14380fd62a098153b59a925aa8b7f490908457835d9cdb5de903a07e6d1bfe0b741aebe6f28ce64185b5
         
     | 
    
        data/lib/action_mcp/gateway.rb
    CHANGED
    
    | 
         @@ -4,6 +4,11 @@ module ActionMCP 
     | 
|
| 
       4 
4 
     | 
    
         
             
              class UnauthorizedError < StandardError; end
         
     | 
| 
       5 
5 
     | 
    
         | 
| 
       6 
6 
     | 
    
         
             
              class Gateway
         
     | 
| 
      
 7 
     | 
    
         
            +
                # Whitelist of allowed identity attribute names to prevent method shadowing
         
     | 
| 
      
 8 
     | 
    
         
            +
                # and unauthorized attribute assignment. Extend this list if you use custom
         
     | 
| 
      
 9 
     | 
    
         
            +
                # identifier names in your GatewayIdentifier implementations.
         
     | 
| 
      
 10 
     | 
    
         
            +
                ALLOWED_IDENTITY_KEYS = %w[user api_key jwt bearer token account session].freeze
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
       7 
12 
     | 
    
         
             
                class << self
         
     | 
| 
       8 
13 
     | 
    
         
             
                  # pluck in one or many GatewayIdentifier classes
         
     | 
| 
       9 
14 
     | 
    
         
             
                  def identified_by(*klasses)
         
     | 
| 
         @@ -69,13 +74,21 @@ module ActionMCP 
     | 
|
| 
       69 
74 
     | 
    
         | 
| 
       70 
75 
     | 
    
         
             
                def assign_identities(identities)
         
     | 
| 
       71 
76 
     | 
    
         
             
                  identities.each do |name, value|
         
     | 
| 
      
 77 
     | 
    
         
            +
                    name_str = name.to_s
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                    # Validate identity key against whitelist to prevent method shadowing
         
     | 
| 
      
 80 
     | 
    
         
            +
                    unless ALLOWED_IDENTITY_KEYS.include?(name_str)
         
     | 
| 
      
 81 
     | 
    
         
            +
                      raise ArgumentError, "Invalid identity key: '#{name_str}'. " \
         
     | 
| 
      
 82 
     | 
    
         
            +
                                           "Allowed keys: #{ALLOWED_IDENTITY_KEYS.join(', ')}"
         
     | 
| 
      
 83 
     | 
    
         
            +
                    end
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
       72 
85 
     | 
    
         
             
                    # define accessor on the fly
         
     | 
| 
       73 
86 
     | 
    
         
             
                    self.class.attr_reader name unless respond_to?(name)
         
     | 
| 
       74 
     | 
    
         
            -
                    instance_variable_set("@#{ 
     | 
| 
      
 87 
     | 
    
         
            +
                    instance_variable_set("@#{name_str}", value)
         
     | 
| 
       75 
88 
     | 
    
         | 
| 
       76 
89 
     | 
    
         
             
                    # also set current context if you have one
         
     | 
| 
       77 
     | 
    
         
            -
                    ActionMCP::Current.public_send("#{ 
     | 
| 
       78 
     | 
    
         
            -
                      ActionMCP::Current.respond_to?("#{ 
     | 
| 
      
 90 
     | 
    
         
            +
                    ActionMCP::Current.public_send("#{name_str}=", value) if
         
     | 
| 
      
 91 
     | 
    
         
            +
                      ActionMCP::Current.respond_to?("#{name_str}=")
         
     | 
| 
       79 
92 
     | 
    
         
             
                  end
         
     | 
| 
       80 
93 
     | 
    
         
             
                  ActionMCP::Current.gateway = self if
         
     | 
| 
       81 
94 
     | 
    
         
             
                    ActionMCP::Current.respond_to?(:gateway=)
         
     | 
| 
         @@ -48,6 +48,11 @@ module ActionMCP 
     | 
|
| 
       48 
48 
     | 
    
         
             
                    @required_parameters ||= []
         
     | 
| 
       49 
49 
     | 
    
         
             
                  end
         
     | 
| 
       50 
50 
     | 
    
         | 
| 
      
 51 
     | 
    
         
            +
                  # Cache compiled regex patterns for URI matching to avoid recompilation
         
     | 
| 
      
 52 
     | 
    
         
            +
                  def uri_regex_cache
         
     | 
| 
      
 53 
     | 
    
         
            +
                    @uri_regex_cache ||= {}
         
     | 
| 
      
 54 
     | 
    
         
            +
                  end
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
       51 
56 
     | 
    
         
             
                  def parameter(name, description:, required: false, **options)
         
     | 
| 
       52 
57 
     | 
    
         
             
                    @parameters ||= {}
         
     | 
| 
       53 
58 
     | 
    
         
             
                    @parameters[name] = { description: description, required: required, **options }
         
     | 
| 
         @@ -139,48 +144,55 @@ module ActionMCP 
     | 
|
| 
       139 
144 
     | 
    
         | 
| 
       140 
145 
     | 
    
         
             
                  # Extract parameters from a URI using the template pattern
         
     | 
| 
       141 
146 
     | 
    
         
             
                  def extract_params_from_uri(uri_string)
         
     | 
| 
       142 
     | 
    
         
            -
                    #  
     | 
| 
       143 
     | 
    
         
            -
                     
     | 
| 
       144 
     | 
    
         
            -
                    current_pos = 0
         
     | 
| 
       145 
     | 
    
         
            -
                    param_names = []
         
     | 
| 
       146 
     | 
    
         
            -
             
     | 
| 
       147 
     | 
    
         
            -
                    # Find all template parameters like {param_name}
         
     | 
| 
       148 
     | 
    
         
            -
                    @uri_template.scan(/\{([^}]+)\}/) do |param_name|
         
     | 
| 
       149 
     | 
    
         
            -
                      param_names << param_name[0]
         
     | 
| 
       150 
     | 
    
         
            -
             
     | 
| 
       151 
     | 
    
         
            -
                      # Get the position of this parameter in the template
         
     | 
| 
       152 
     | 
    
         
            -
                      param_start = @uri_template.index("{#{param_name[0]}}", current_pos)
         
     | 
| 
       153 
     | 
    
         
            -
             
     | 
| 
       154 
     | 
    
         
            -
                      # Add the text before the parameter (escaped)
         
     | 
| 
       155 
     | 
    
         
            -
                      if param_start > current_pos
         
     | 
| 
       156 
     | 
    
         
            -
                        prefix = Regexp.escape(@uri_template[current_pos...param_start])
         
     | 
| 
       157 
     | 
    
         
            -
                        regex_parts << prefix
         
     | 
| 
       158 
     | 
    
         
            -
                      end
         
     | 
| 
      
 147 
     | 
    
         
            +
                    # Check cache for compiled regex and param names
         
     | 
| 
      
 148 
     | 
    
         
            +
                    cache_entry = uri_regex_cache[@uri_template]
         
     | 
| 
       159 
149 
     | 
    
         | 
| 
       160 
     | 
    
         
            -
             
     | 
| 
       161 
     | 
    
         
            -
                       
     | 
| 
      
 150 
     | 
    
         
            +
                    unless cache_entry
         
     | 
| 
      
 151 
     | 
    
         
            +
                      # Convert template parameters to named capture groups
         
     | 
| 
      
 152 
     | 
    
         
            +
                      regex_parts = []
         
     | 
| 
      
 153 
     | 
    
         
            +
                      current_pos = 0
         
     | 
| 
      
 154 
     | 
    
         
            +
                      param_names = []
         
     | 
| 
       162 
155 
     | 
    
         | 
| 
       163 
     | 
    
         
            -
                      #  
     | 
| 
       164 
     | 
    
         
            -
                       
     | 
| 
       165 
     | 
    
         
            -
             
     | 
| 
      
 156 
     | 
    
         
            +
                      # Find all template parameters like {param_name}
         
     | 
| 
      
 157 
     | 
    
         
            +
                      @uri_template.scan(/\{([^}]+)\}/) do |param_name|
         
     | 
| 
      
 158 
     | 
    
         
            +
                        param_names << param_name[0]
         
     | 
| 
       166 
159 
     | 
    
         | 
| 
       167 
     | 
    
         
            -
             
     | 
| 
       168 
     | 
    
         
            -
             
     | 
| 
       169 
     | 
    
         
            -
             
     | 
| 
       170 
     | 
    
         
            -
             
     | 
| 
       171 
     | 
    
         
            -
             
     | 
| 
      
 160 
     | 
    
         
            +
                        # Get the position of this parameter in the template
         
     | 
| 
      
 161 
     | 
    
         
            +
                        param_start = @uri_template.index("{#{param_name[0]}}", current_pos)
         
     | 
| 
      
 162 
     | 
    
         
            +
             
     | 
| 
      
 163 
     | 
    
         
            +
                        # Add the text before the parameter (escaped)
         
     | 
| 
      
 164 
     | 
    
         
            +
                        if param_start > current_pos
         
     | 
| 
      
 165 
     | 
    
         
            +
                          prefix = Regexp.escape(@uri_template[current_pos...param_start])
         
     | 
| 
      
 166 
     | 
    
         
            +
                          regex_parts << prefix
         
     | 
| 
      
 167 
     | 
    
         
            +
                        end
         
     | 
| 
       172 
168 
     | 
    
         | 
| 
       173 
     | 
    
         
            -
             
     | 
| 
       174 
     | 
    
         
            -
             
     | 
| 
       175 
     | 
    
         
            -
             
     | 
| 
      
 169 
     | 
    
         
            +
                        # Add the named capture group
         
     | 
| 
      
 170 
     | 
    
         
            +
                        regex_parts << "(?<#{param_name[0]}>[^/]+)"
         
     | 
| 
      
 171 
     | 
    
         
            +
             
     | 
| 
      
 172 
     | 
    
         
            +
                        # Update current position
         
     | 
| 
      
 173 
     | 
    
         
            +
                        current_pos = param_start + param_name[0].length + 2 # +2 for { and }
         
     | 
| 
      
 174 
     | 
    
         
            +
                      end
         
     | 
| 
      
 175 
     | 
    
         
            +
             
     | 
| 
      
 176 
     | 
    
         
            +
                      # Add any remaining text after the last parameter
         
     | 
| 
      
 177 
     | 
    
         
            +
                      if current_pos < @uri_template.length
         
     | 
| 
      
 178 
     | 
    
         
            +
                        suffix = Regexp.escape(@uri_template[current_pos..])
         
     | 
| 
      
 179 
     | 
    
         
            +
                        regex_parts << suffix
         
     | 
| 
      
 180 
     | 
    
         
            +
                      end
         
     | 
| 
      
 181 
     | 
    
         
            +
             
     | 
| 
      
 182 
     | 
    
         
            +
                      # Build the final regex and cache it
         
     | 
| 
      
 183 
     | 
    
         
            +
                      regex_pattern = regex_parts.join
         
     | 
| 
      
 184 
     | 
    
         
            +
                      regex = Regexp.new("^#{regex_pattern}$")
         
     | 
| 
      
 185 
     | 
    
         
            +
                      cache_entry = { regex: regex, param_names: param_names }
         
     | 
| 
      
 186 
     | 
    
         
            +
                      uri_regex_cache[@uri_template] = cache_entry
         
     | 
| 
      
 187 
     | 
    
         
            +
                    end
         
     | 
| 
       176 
188 
     | 
    
         | 
| 
       177 
     | 
    
         
            -
                    # Try to match the URI
         
     | 
| 
       178 
     | 
    
         
            -
                    match_data = regex.match(uri_string)
         
     | 
| 
      
 189 
     | 
    
         
            +
                    # Try to match the URI using cached regex
         
     | 
| 
      
 190 
     | 
    
         
            +
                    match_data = cache_entry[:regex].match(uri_string)
         
     | 
| 
       179 
191 
     | 
    
         
             
                    return nil unless match_data
         
     | 
| 
       180 
192 
     | 
    
         | 
| 
       181 
193 
     | 
    
         
             
                    # Extract named captures as parameters
         
     | 
| 
       182 
194 
     | 
    
         
             
                    params = {}
         
     | 
| 
       183 
     | 
    
         
            -
                    param_names.each do |name|
         
     | 
| 
      
 195 
     | 
    
         
            +
                    cache_entry[:param_names].each do |name|
         
     | 
| 
       184 
196 
     | 
    
         
             
                      params[name.to_sym] = match_data[name] if match_data[name]
         
     | 
| 
       185 
197 
     | 
    
         
             
                    end
         
     | 
| 
       186 
198 
     | 
    
         | 
    
        data/lib/action_mcp/tool.rb
    CHANGED
    
    | 
         @@ -240,9 +240,9 @@ module ActionMCP 
     | 
|
| 
       240 
240 
     | 
    
         
             
                  prop_definition.merge!(opts) if opts.any?
         
     | 
| 
       241 
241 
     | 
    
         | 
| 
       242 
242 
     | 
    
         
             
                  self._schema_properties = _schema_properties.merge(prop_name.to_s => prop_definition)
         
     | 
| 
       243 
     | 
    
         
            -
                   
     | 
| 
       244 
     | 
    
         
            -
             
     | 
| 
       245 
     | 
    
         
            -
                   
     | 
| 
      
 243 
     | 
    
         
            +
                  new_required = _required_properties.dup
         
     | 
| 
      
 244 
     | 
    
         
            +
                  new_required << prop_name.to_s if required
         
     | 
| 
      
 245 
     | 
    
         
            +
                  self._required_properties = new_required
         
     | 
| 
       246 
246 
     | 
    
         | 
| 
       247 
247 
     | 
    
         
             
                  # Map the JSON Schema type to an ActiveModel attribute type.
         
     | 
| 
       248 
248 
     | 
    
         
             
                  attribute prop_name, map_json_type_to_active_model_type(type), default: default
         
     | 
| 
         @@ -271,9 +271,9 @@ module ActionMCP 
     | 
|
| 
       271 
271 
     | 
    
         
             
                  collection_definition[:description] = description if description && !description.empty?
         
     | 
| 
       272 
272 
     | 
    
         | 
| 
       273 
273 
     | 
    
         
             
                  self._schema_properties = _schema_properties.merge(prop_name.to_s => collection_definition)
         
     | 
| 
       274 
     | 
    
         
            -
                   
     | 
| 
       275 
     | 
    
         
            -
             
     | 
| 
       276 
     | 
    
         
            -
                   
     | 
| 
      
 274 
     | 
    
         
            +
                  new_required = _required_properties.dup
         
     | 
| 
      
 275 
     | 
    
         
            +
                  new_required << prop_name.to_s if required
         
     | 
| 
      
 276 
     | 
    
         
            +
                  self._required_properties = new_required
         
     | 
| 
       277 
277 
     | 
    
         | 
| 
       278 
278 
     | 
    
         
             
                  # Map the type - for number arrays, use our custom type instance
         
     | 
| 
       279 
279 
     | 
    
         
             
                  mapped_type = if type == "number"
         
     | 
| 
         @@ -26,8 +26,13 @@ module ActionMCP 
     | 
|
| 
       26 
26 
     | 
    
         
             
                    # Handle parameter validation errors
         
     | 
| 
       27 
27 
     | 
    
         
             
                    error_response(:invalid_params, message: e.message)
         
     | 
| 
       28 
28 
     | 
    
         
             
                  rescue StandardError => e
         
     | 
| 
       29 
     | 
    
         
            -
                    #  
     | 
| 
       30 
     | 
    
         
            -
                     
     | 
| 
      
 29 
     | 
    
         
            +
                    # Hide error details in production to prevent information disclosure
         
     | 
| 
      
 30 
     | 
    
         
            +
                    message = if Rails.env.production?
         
     | 
| 
      
 31 
     | 
    
         
            +
                      "Tool execution failed"
         
     | 
| 
      
 32 
     | 
    
         
            +
                    else
         
     | 
| 
      
 33 
     | 
    
         
            +
                      "Tool execution failed: #{e.message}"
         
     | 
| 
      
 34 
     | 
    
         
            +
                    end
         
     | 
| 
      
 35 
     | 
    
         
            +
                    error_response(:invalid_params, message: message)
         
     | 
| 
       31 
36 
     | 
    
         
             
                  end
         
     | 
| 
       32 
37 
     | 
    
         | 
| 
       33 
38 
     | 
    
         
             
                  def item_klass
         
     | 
    
        data/lib/action_mcp/version.rb
    CHANGED
    
    
| 
         @@ -49,6 +49,28 @@ namespace :action_mcp do 
     | 
|
| 
       49 
49 
     | 
    
         
             
                puts "\n"
         
     | 
| 
       50 
50 
     | 
    
         
             
              end
         
     | 
| 
       51 
51 
     | 
    
         | 
| 
      
 52 
     | 
    
         
            +
              # bin/rails action_mcp:list_profiles
         
     | 
| 
      
 53 
     | 
    
         
            +
              desc "List all available profiles"
         
     | 
| 
      
 54 
     | 
    
         
            +
              task list_profiles: :environment do
         
     | 
| 
      
 55 
     | 
    
         
            +
                # Ensure Rails eager loads all classes
         
     | 
| 
      
 56 
     | 
    
         
            +
                Rails.application.eager_load!
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                puts "\e[35mACTION MCP PROFILES\e[0m"  # Purple
         
     | 
| 
      
 59 
     | 
    
         
            +
                puts "\e[35m-------------------\e[0m"   # Purple
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                profiles = ActionMCP.configuration.profiles
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                if profiles.any?
         
     | 
| 
      
 64 
     | 
    
         
            +
                  profiles.each_key do |profile_name|
         
     | 
| 
      
 65 
     | 
    
         
            +
                    puts "\e[35m#{profile_name}\e[0m"
         
     | 
| 
      
 66 
     | 
    
         
            +
                  end
         
     | 
| 
      
 67 
     | 
    
         
            +
                else
         
     | 
| 
      
 68 
     | 
    
         
            +
                  puts "  No profiles configured"
         
     | 
| 
      
 69 
     | 
    
         
            +
                end
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                puts "\n"
         
     | 
| 
      
 72 
     | 
    
         
            +
              end
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
       52 
74 
     | 
    
         
             
              # bin/rails action_mcp:show_profile[profile_name]
         
     | 
| 
       53 
75 
     | 
    
         
             
              desc "Show configuration for a specific profile"
         
     | 
| 
       54 
76 
     | 
    
         
             
              task :show_profile, [ :profile_name ] => :environment do |_t, args|
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: actionmcp
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 0. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.83.1
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Abdelkader Boudih
         
     | 
| 
         @@ -15,14 +15,14 @@ dependencies: 
     | 
|
| 
       15 
15 
     | 
    
         
             
                requirements:
         
     | 
| 
       16 
16 
     | 
    
         
             
                - - ">="
         
     | 
| 
       17 
17 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       18 
     | 
    
         
            -
                    version: 8.0. 
     | 
| 
      
 18 
     | 
    
         
            +
                    version: 8.0.4
         
     | 
| 
       19 
19 
     | 
    
         
             
              type: :runtime
         
     | 
| 
       20 
20 
     | 
    
         
             
              prerelease: false
         
     | 
| 
       21 
21 
     | 
    
         
             
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
       22 
22 
     | 
    
         
             
                requirements:
         
     | 
| 
       23 
23 
     | 
    
         
             
                - - ">="
         
     | 
| 
       24 
24 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       25 
     | 
    
         
            -
                    version: 8.0. 
     | 
| 
      
 25 
     | 
    
         
            +
                    version: 8.0.4
         
     | 
| 
       26 
26 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       27 
27 
     | 
    
         
             
              name: concurrent-ruby
         
     | 
| 
       28 
28 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
         @@ -71,14 +71,14 @@ dependencies: 
     | 
|
| 
       71 
71 
     | 
    
         
             
                requirements:
         
     | 
| 
       72 
72 
     | 
    
         
             
                - - ">="
         
     | 
| 
       73 
73 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       74 
     | 
    
         
            -
                    version: 8.0. 
     | 
| 
      
 74 
     | 
    
         
            +
                    version: 8.0.4
         
     | 
| 
       75 
75 
     | 
    
         
             
              type: :runtime
         
     | 
| 
       76 
76 
     | 
    
         
             
              prerelease: false
         
     | 
| 
       77 
77 
     | 
    
         
             
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
       78 
78 
     | 
    
         
             
                requirements:
         
     | 
| 
       79 
79 
     | 
    
         
             
                - - ">="
         
     | 
| 
       80 
80 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       81 
     | 
    
         
            -
                    version: 8.0. 
     | 
| 
      
 81 
     | 
    
         
            +
                    version: 8.0.4
         
     | 
| 
       82 
82 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       83 
83 
     | 
    
         
             
              name: zeitwerk
         
     | 
| 
       84 
84 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
         @@ -93,20 +93,6 @@ dependencies: 
     | 
|
| 
       93 
93 
     | 
    
         
             
                - - "~>"
         
     | 
| 
       94 
94 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       95 
95 
     | 
    
         
             
                    version: '2.6'
         
     | 
| 
       96 
     | 
    
         
            -
            - !ruby/object:Gem::Dependency
         
     | 
| 
       97 
     | 
    
         
            -
              name: ostruct
         
     | 
| 
       98 
     | 
    
         
            -
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
       99 
     | 
    
         
            -
                requirements:
         
     | 
| 
       100 
     | 
    
         
            -
                - - ">="
         
     | 
| 
       101 
     | 
    
         
            -
                  - !ruby/object:Gem::Version
         
     | 
| 
       102 
     | 
    
         
            -
                    version: '0'
         
     | 
| 
       103 
     | 
    
         
            -
              type: :runtime
         
     | 
| 
       104 
     | 
    
         
            -
              prerelease: false
         
     | 
| 
       105 
     | 
    
         
            -
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
       106 
     | 
    
         
            -
                requirements:
         
     | 
| 
       107 
     | 
    
         
            -
                - - ">="
         
     | 
| 
       108 
     | 
    
         
            -
                  - !ruby/object:Gem::Version
         
     | 
| 
       109 
     | 
    
         
            -
                    version: '0'
         
     | 
| 
       110 
96 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       111 
97 
     | 
    
         
             
              name: json_schemer
         
     | 
| 
       112 
98 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     |