Module: RailsAiBridge::Registry
- Defined in:
- lib/rails_ai_bridge/registry.rb,
lib/rails_ai_bridge/registry/resolver.rb,
lib/rails_ai_bridge/registry/truncatable.rb,
lib/rails_ai_bridge/registry/pack_detector.rb,
lib/rails_ai_bridge/registry/pack_resolver.rb,
lib/rails_ai_bridge/registry/source_parser.rb,
lib/rails_ai_bridge/registry/tile_manifest.rb,
lib/rails_ai_bridge/registry/rake_presenter.rb,
lib/rails_ai_bridge/registry/resolver_cache.rb,
lib/rails_ai_bridge/registry/pack_definition.rb,
lib/rails_ai_bridge/registry/registry_manifest.rb,
lib/rails_ai_bridge/registry/frontmatter_parser.rb,
lib/rails_ai_bridge/registry/skill_source_resolver.rb
Overview
Registry resolution system for skill packs.
Provides priority-based loading of skill packs from git repositories, deprecation redirect handling, and framework auto-detection.
Defined Under Namespace
Modules: GitRunner, SourceParser, Truncatable Classes: AgentEntry, DefaultGitRunner, DeprecatedEntry, DetectedFramework, FrontmatterParser, LoadedPack, PackDefinition, PackDetector, PackResolver, RakePresenter, RegistryManifest, ResolvedSkill, Resolver, ResolverCache, SkillEntry, SkillSourceResolver, SkillSummary, TileManifest
Instance Attribute Summary collapse
- #agents ⇒ Hash{String => AgentEntry} readonly
-
#always_loaded ⇒ Boolean
readonly
Whether this pack is unconditionally loaded.
-
#base_path ⇒ String
readonly
Local filesystem path where the pack is located.
-
#content ⇒ String
readonly
Complete text content of the markdown file.
-
#default_stack ⇒ Array<String>
readonly
Pack names loaded when no framework is detected.
-
#depends_on ⇒ Array<String>
readonly
Names of packs this pack depends on.
- #deprecated_skills ⇒ Hash{String => DeprecatedEntry} readonly
-
#description ⇒ String?
readonly
Optional description.
-
#message ⇒ String
readonly
Human-readable deprecation message.
-
#moved_to ⇒ String
readonly
Name of the skill this has been moved to.
-
#name ⇒ String
readonly
Unique pack name, e.g.
-
#pack ⇒ String
readonly
Source pack name.
-
#packs ⇒ Hash{String => PackDefinition}
readonly
Map of pack name to definition.
-
#path ⇒ String
readonly
Relative path to the agent markdown file.
-
#priority ⇒ Integer
readonly
Priority level (lower value is higher priority).
-
#ref ⇒ String?
readonly
Optional git ref (branch, tag, or SHA) to pin the pack version; nil means use the default branch (HEAD).
-
#removed_in ⇒ String?
readonly
Version in which this alias will be removed.
- #skills ⇒ Hash{String => SkillEntry} readonly
-
#source ⇒ String
readonly
Pack source — local path, full git URL, or "owner/repo" shorthand.
-
#summary ⇒ String?
readonly
Optional human-readable pack description.
-
#tags ⇒ Array<String>
readonly
Optional classification tags.
-
#tile ⇒ String
readonly
Relative path to the pack's tile manifest, usually "directory.json".
-
#version ⇒ String
readonly
Manifest schema version.
Class Method Summary collapse
-
.build_resolver(config = RailsAiBridge.configuration.registry) ⇒ Resolver?
Builds (or returns a cached) Resolver from the current Config::Registry.
-
.invalidate_resolver_cache! ⇒ void
Discards the cached resolver so the next Registry.build_resolver call rebuilds from disk.
-
.resolver_cache ⇒ Object
private
Returns the module-level ResolverCache instance, creating it on first call.
Instance Attribute Details
#agents ⇒ Hash{String => AgentEntry} (readonly)
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 119 120 121 122 123 124 125 126 127 |
# File 'lib/rails_ai_bridge/registry/tile_manifest.rb', line 55 TileManifest = Data.define(:name, :version, :summary, :depends_on, :skills, :agents, :deprecated_skills) do # Builds a {TileManifest} from a parsed JSON hash. # # @param hash [Hash] parsed JSON object # @return [TileManifest] def self.from_json(hash) new( name: hash.fetch('name'), version: hash.fetch('version'), summary: hash['summary'], depends_on: hash.fetch('depends_on', []), skills: parse_skills(hash['skills'] || {}), agents: parse_agents(hash['agents'] || {}), deprecated_skills: parse_deprecated(hash['deprecated_skills'] || {}) ) rescue KeyError => error raise ArgumentError, "Tile manifest missing required field: #{error.key}" end # Loads and parses a tile manifest from a JSON file on disk. # # @param path [String] path to the tile JSON file # @return [TileManifest] # @raise [ArgumentError] if the file does not exist, cannot be read, or contains malformed JSON def self.from_file(path) from_json(JSON.parse(File.read(path))) rescue JSON::ParserError => error raise ArgumentError, "Tile manifest at '#{path}' contains invalid JSON: #{error.}" rescue SystemCallError => error raise ArgumentError, "Tile manifest at '#{path}' could not be read: #{error.}" end # @api private def self.parse_skills(skills_hash) skills_hash.transform_values do |skill_data| SkillEntry.new( path: skill_data.fetch('path'), description: skill_data['description'], tags: skill_data.fetch('tags', []) ) rescue KeyError => error raise ArgumentError, "Skill entry missing required field: #{error.key}" end end # @api private def self.parse_agents(agents_hash) agents_hash.transform_values do |agent_data| AgentEntry.new( path: agent_data.fetch('path'), description: agent_data['description'], depends_on: agent_data.fetch('depends_on', []) ) rescue KeyError => error raise ArgumentError, "Agent entry missing required field: #{error.key}" end end # @api private def self.parse_deprecated(deprecated_hash) deprecated_hash.transform_values do |entry_data| DeprecatedEntry.new( moved_to: entry_data.fetch('moved_to'), message: entry_data.fetch('message'), removed_in: entry_data['removed_in'] ) rescue KeyError => error raise ArgumentError, "Deprecated skill entry missing required field: #{error.key}" end end private_class_method :parse_skills, :parse_agents, :parse_deprecated end |
#always_loaded ⇒ Boolean (readonly)
Returns whether this pack is unconditionally loaded.
18 19 20 21 |
# File 'lib/rails_ai_bridge/registry/pack_definition.rb', line 18 PackDefinition = Data.define(:source, :tile, :always_loaded, :depends_on, :ref) do # @return [Boolean] def always_loaded? = always_loaded end |
#base_path ⇒ String (readonly)
Returns local filesystem path where the pack is located.
17 |
# File 'lib/rails_ai_bridge/registry/resolver.rb', line 17 LoadedPack = Data.define(:name, :tile, :base_path, :priority) |
#content ⇒ String (readonly)
Returns complete text content of the markdown file.
29 |
# File 'lib/rails_ai_bridge/registry/resolver.rb', line 29 ResolvedSkill = Data.define(:name, :pack, :path, :content) |
#default_stack ⇒ Array<String> (readonly)
Returns pack names loaded when no framework is detected.
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/rails_ai_bridge/registry/registry_manifest.rb', line 13 RegistryManifest = Data.define(:version, :packs, :default_stack) do # Builds a {RegistryManifest} from a parsed JSON hash. # # @param hash [Hash] parsed JSON object # @return [RegistryManifest] def self.from_json(hash) packs = (hash['packs'] || {}).transform_values do |pack_hash| PackDefinition.new( source: pack_hash.fetch('source'), tile: pack_hash.fetch('tile', 'directory.json'), always_loaded: pack_hash.fetch('always_loaded', false), depends_on: pack_hash.fetch('depends_on', []), ref: pack_hash.fetch('ref', nil) ) end new( version: hash.fetch('version'), packs: packs, default_stack: hash.fetch('default_stack', []) ) rescue KeyError => error raise ArgumentError, "Registry manifest missing required field: #{error.key}" end # Loads and parses a registry manifest from a JSON file on disk. # # @param path [String] absolute or relative path to the registry JSON file # @return [RegistryManifest] # @raise [ArgumentError] if the file does not exist, cannot be read, or contains malformed JSON def self.from_file(path) from_json(JSON.parse(File.read(path))) rescue JSON::ParserError => error raise ArgumentError, "Registry manifest at '#{path}' contains invalid JSON: #{error.}" rescue SystemCallError => error raise ArgumentError, "Registry manifest at '#{path}' could not be read: #{error.}" end end |
#depends_on ⇒ Array<String> (readonly)
Returns names of packs this pack depends on.
23 |
# File 'lib/rails_ai_bridge/registry/tile_manifest.rb', line 23 AgentEntry = Data.define(:path, :description, :depends_on) |
#deprecated_skills ⇒ Hash{String => DeprecatedEntry} (readonly)
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 119 120 121 122 123 124 125 126 127 |
# File 'lib/rails_ai_bridge/registry/tile_manifest.rb', line 55 TileManifest = Data.define(:name, :version, :summary, :depends_on, :skills, :agents, :deprecated_skills) do # Builds a {TileManifest} from a parsed JSON hash. # # @param hash [Hash] parsed JSON object # @return [TileManifest] def self.from_json(hash) new( name: hash.fetch('name'), version: hash.fetch('version'), summary: hash['summary'], depends_on: hash.fetch('depends_on', []), skills: parse_skills(hash['skills'] || {}), agents: parse_agents(hash['agents'] || {}), deprecated_skills: parse_deprecated(hash['deprecated_skills'] || {}) ) rescue KeyError => error raise ArgumentError, "Tile manifest missing required field: #{error.key}" end # Loads and parses a tile manifest from a JSON file on disk. # # @param path [String] path to the tile JSON file # @return [TileManifest] # @raise [ArgumentError] if the file does not exist, cannot be read, or contains malformed JSON def self.from_file(path) from_json(JSON.parse(File.read(path))) rescue JSON::ParserError => error raise ArgumentError, "Tile manifest at '#{path}' contains invalid JSON: #{error.}" rescue SystemCallError => error raise ArgumentError, "Tile manifest at '#{path}' could not be read: #{error.}" end # @api private def self.parse_skills(skills_hash) skills_hash.transform_values do |skill_data| SkillEntry.new( path: skill_data.fetch('path'), description: skill_data['description'], tags: skill_data.fetch('tags', []) ) rescue KeyError => error raise ArgumentError, "Skill entry missing required field: #{error.key}" end end # @api private def self.parse_agents(agents_hash) agents_hash.transform_values do |agent_data| AgentEntry.new( path: agent_data.fetch('path'), description: agent_data['description'], depends_on: agent_data.fetch('depends_on', []) ) rescue KeyError => error raise ArgumentError, "Agent entry missing required field: #{error.key}" end end # @api private def self.parse_deprecated(deprecated_hash) deprecated_hash.transform_values do |entry_data| DeprecatedEntry.new( moved_to: entry_data.fetch('moved_to'), message: entry_data.fetch('message'), removed_in: entry_data['removed_in'] ) rescue KeyError => error raise ArgumentError, "Deprecated skill entry missing required field: #{error.key}" end end private_class_method :parse_skills, :parse_agents, :parse_deprecated end |
#description ⇒ String? (readonly)
Returns optional description.
39 |
# File 'lib/rails_ai_bridge/registry/resolver.rb', line 39 SkillSummary = Data.define(:name, :pack, :description) |
#message ⇒ String (readonly)
Returns human-readable deprecation message.
33 34 35 36 37 |
# File 'lib/rails_ai_bridge/registry/tile_manifest.rb', line 33 DeprecatedEntry = Data.define(:moved_to, :message, :removed_in) do # @return [Boolean] # :reek:NilCheck def removed_in? = !removed_in.nil? end |
#moved_to ⇒ String (readonly)
Returns name of the skill this has been moved to.
33 34 35 36 37 |
# File 'lib/rails_ai_bridge/registry/tile_manifest.rb', line 33 DeprecatedEntry = Data.define(:moved_to, :message, :removed_in) do # @return [Boolean] # :reek:NilCheck def removed_in? = !removed_in.nil? end |
#name ⇒ String (readonly)
Returns unique pack name, e.g. "ruby-core-skills".
17 |
# File 'lib/rails_ai_bridge/registry/resolver.rb', line 17 LoadedPack = Data.define(:name, :tile, :base_path, :priority) |
#pack ⇒ String (readonly)
Returns source pack name.
29 |
# File 'lib/rails_ai_bridge/registry/resolver.rb', line 29 ResolvedSkill = Data.define(:name, :pack, :path, :content) |
#packs ⇒ Hash{String => PackDefinition} (readonly)
Returns map of pack name to definition.
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/rails_ai_bridge/registry/registry_manifest.rb', line 13 RegistryManifest = Data.define(:version, :packs, :default_stack) do # Builds a {RegistryManifest} from a parsed JSON hash. # # @param hash [Hash] parsed JSON object # @return [RegistryManifest] def self.from_json(hash) packs = (hash['packs'] || {}).transform_values do |pack_hash| PackDefinition.new( source: pack_hash.fetch('source'), tile: pack_hash.fetch('tile', 'directory.json'), always_loaded: pack_hash.fetch('always_loaded', false), depends_on: pack_hash.fetch('depends_on', []), ref: pack_hash.fetch('ref', nil) ) end new( version: hash.fetch('version'), packs: packs, default_stack: hash.fetch('default_stack', []) ) rescue KeyError => error raise ArgumentError, "Registry manifest missing required field: #{error.key}" end # Loads and parses a registry manifest from a JSON file on disk. # # @param path [String] absolute or relative path to the registry JSON file # @return [RegistryManifest] # @raise [ArgumentError] if the file does not exist, cannot be read, or contains malformed JSON def self.from_file(path) from_json(JSON.parse(File.read(path))) rescue JSON::ParserError => error raise ArgumentError, "Registry manifest at '#{path}' contains invalid JSON: #{error.}" rescue SystemCallError => error raise ArgumentError, "Registry manifest at '#{path}' could not be read: #{error.}" end end |
#path ⇒ String (readonly)
Returns relative path to the agent markdown file.
29 |
# File 'lib/rails_ai_bridge/registry/resolver.rb', line 29 ResolvedSkill = Data.define(:name, :pack, :path, :content) |
#priority ⇒ Integer (readonly)
Returns priority level (lower value is higher priority).
17 |
# File 'lib/rails_ai_bridge/registry/resolver.rb', line 17 LoadedPack = Data.define(:name, :tile, :base_path, :priority) |
#ref ⇒ String? (readonly)
Returns optional git ref (branch, tag, or SHA) to pin the pack version; nil means use the default branch (HEAD).
18 19 20 21 |
# File 'lib/rails_ai_bridge/registry/pack_definition.rb', line 18 PackDefinition = Data.define(:source, :tile, :always_loaded, :depends_on, :ref) do # @return [Boolean] def always_loaded? = always_loaded end |
#removed_in ⇒ String? (readonly)
Returns version in which this alias will be removed.
33 34 35 36 37 |
# File 'lib/rails_ai_bridge/registry/tile_manifest.rb', line 33 DeprecatedEntry = Data.define(:moved_to, :message, :removed_in) do # @return [Boolean] # :reek:NilCheck def removed_in? = !removed_in.nil? end |
#skills ⇒ Hash{String => SkillEntry} (readonly)
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 119 120 121 122 123 124 125 126 127 |
# File 'lib/rails_ai_bridge/registry/tile_manifest.rb', line 55 TileManifest = Data.define(:name, :version, :summary, :depends_on, :skills, :agents, :deprecated_skills) do # Builds a {TileManifest} from a parsed JSON hash. # # @param hash [Hash] parsed JSON object # @return [TileManifest] def self.from_json(hash) new( name: hash.fetch('name'), version: hash.fetch('version'), summary: hash['summary'], depends_on: hash.fetch('depends_on', []), skills: parse_skills(hash['skills'] || {}), agents: parse_agents(hash['agents'] || {}), deprecated_skills: parse_deprecated(hash['deprecated_skills'] || {}) ) rescue KeyError => error raise ArgumentError, "Tile manifest missing required field: #{error.key}" end # Loads and parses a tile manifest from a JSON file on disk. # # @param path [String] path to the tile JSON file # @return [TileManifest] # @raise [ArgumentError] if the file does not exist, cannot be read, or contains malformed JSON def self.from_file(path) from_json(JSON.parse(File.read(path))) rescue JSON::ParserError => error raise ArgumentError, "Tile manifest at '#{path}' contains invalid JSON: #{error.}" rescue SystemCallError => error raise ArgumentError, "Tile manifest at '#{path}' could not be read: #{error.}" end # @api private def self.parse_skills(skills_hash) skills_hash.transform_values do |skill_data| SkillEntry.new( path: skill_data.fetch('path'), description: skill_data['description'], tags: skill_data.fetch('tags', []) ) rescue KeyError => error raise ArgumentError, "Skill entry missing required field: #{error.key}" end end # @api private def self.parse_agents(agents_hash) agents_hash.transform_values do |agent_data| AgentEntry.new( path: agent_data.fetch('path'), description: agent_data['description'], depends_on: agent_data.fetch('depends_on', []) ) rescue KeyError => error raise ArgumentError, "Agent entry missing required field: #{error.key}" end end # @api private def self.parse_deprecated(deprecated_hash) deprecated_hash.transform_values do |entry_data| DeprecatedEntry.new( moved_to: entry_data.fetch('moved_to'), message: entry_data.fetch('message'), removed_in: entry_data['removed_in'] ) rescue KeyError => error raise ArgumentError, "Deprecated skill entry missing required field: #{error.key}" end end private_class_method :parse_skills, :parse_agents, :parse_deprecated end |
#source ⇒ String (readonly)
Returns pack source — local path, full git URL, or "owner/repo" shorthand.
18 19 20 21 |
# File 'lib/rails_ai_bridge/registry/pack_definition.rb', line 18 PackDefinition = Data.define(:source, :tile, :always_loaded, :depends_on, :ref) do # @return [Boolean] def always_loaded? = always_loaded end |
#summary ⇒ String? (readonly)
Returns optional human-readable pack description.
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 119 120 121 122 123 124 125 126 127 |
# File 'lib/rails_ai_bridge/registry/tile_manifest.rb', line 55 TileManifest = Data.define(:name, :version, :summary, :depends_on, :skills, :agents, :deprecated_skills) do # Builds a {TileManifest} from a parsed JSON hash. # # @param hash [Hash] parsed JSON object # @return [TileManifest] def self.from_json(hash) new( name: hash.fetch('name'), version: hash.fetch('version'), summary: hash['summary'], depends_on: hash.fetch('depends_on', []), skills: parse_skills(hash['skills'] || {}), agents: parse_agents(hash['agents'] || {}), deprecated_skills: parse_deprecated(hash['deprecated_skills'] || {}) ) rescue KeyError => error raise ArgumentError, "Tile manifest missing required field: #{error.key}" end # Loads and parses a tile manifest from a JSON file on disk. # # @param path [String] path to the tile JSON file # @return [TileManifest] # @raise [ArgumentError] if the file does not exist, cannot be read, or contains malformed JSON def self.from_file(path) from_json(JSON.parse(File.read(path))) rescue JSON::ParserError => error raise ArgumentError, "Tile manifest at '#{path}' contains invalid JSON: #{error.}" rescue SystemCallError => error raise ArgumentError, "Tile manifest at '#{path}' could not be read: #{error.}" end # @api private def self.parse_skills(skills_hash) skills_hash.transform_values do |skill_data| SkillEntry.new( path: skill_data.fetch('path'), description: skill_data['description'], tags: skill_data.fetch('tags', []) ) rescue KeyError => error raise ArgumentError, "Skill entry missing required field: #{error.key}" end end # @api private def self.parse_agents(agents_hash) agents_hash.transform_values do |agent_data| AgentEntry.new( path: agent_data.fetch('path'), description: agent_data['description'], depends_on: agent_data.fetch('depends_on', []) ) rescue KeyError => error raise ArgumentError, "Agent entry missing required field: #{error.key}" end end # @api private def self.parse_deprecated(deprecated_hash) deprecated_hash.transform_values do |entry_data| DeprecatedEntry.new( moved_to: entry_data.fetch('moved_to'), message: entry_data.fetch('message'), removed_in: entry_data['removed_in'] ) rescue KeyError => error raise ArgumentError, "Deprecated skill entry missing required field: #{error.key}" end end private_class_method :parse_skills, :parse_agents, :parse_deprecated end |
#tags ⇒ Array<String> (readonly)
Returns optional classification tags.
13 |
# File 'lib/rails_ai_bridge/registry/tile_manifest.rb', line 13 SkillEntry = Data.define(:path, :description, :tags) |
#tile ⇒ String (readonly)
Returns relative path to the pack's tile manifest, usually "directory.json".
17 |
# File 'lib/rails_ai_bridge/registry/resolver.rb', line 17 LoadedPack = Data.define(:name, :tile, :base_path, :priority) |
#version ⇒ String (readonly)
Returns manifest schema version.
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 119 120 121 122 123 124 125 126 127 |
# File 'lib/rails_ai_bridge/registry/tile_manifest.rb', line 55 TileManifest = Data.define(:name, :version, :summary, :depends_on, :skills, :agents, :deprecated_skills) do # Builds a {TileManifest} from a parsed JSON hash. # # @param hash [Hash] parsed JSON object # @return [TileManifest] def self.from_json(hash) new( name: hash.fetch('name'), version: hash.fetch('version'), summary: hash['summary'], depends_on: hash.fetch('depends_on', []), skills: parse_skills(hash['skills'] || {}), agents: parse_agents(hash['agents'] || {}), deprecated_skills: parse_deprecated(hash['deprecated_skills'] || {}) ) rescue KeyError => error raise ArgumentError, "Tile manifest missing required field: #{error.key}" end # Loads and parses a tile manifest from a JSON file on disk. # # @param path [String] path to the tile JSON file # @return [TileManifest] # @raise [ArgumentError] if the file does not exist, cannot be read, or contains malformed JSON def self.from_file(path) from_json(JSON.parse(File.read(path))) rescue JSON::ParserError => error raise ArgumentError, "Tile manifest at '#{path}' contains invalid JSON: #{error.}" rescue SystemCallError => error raise ArgumentError, "Tile manifest at '#{path}' could not be read: #{error.}" end # @api private def self.parse_skills(skills_hash) skills_hash.transform_values do |skill_data| SkillEntry.new( path: skill_data.fetch('path'), description: skill_data['description'], tags: skill_data.fetch('tags', []) ) rescue KeyError => error raise ArgumentError, "Skill entry missing required field: #{error.key}" end end # @api private def self.parse_agents(agents_hash) agents_hash.transform_values do |agent_data| AgentEntry.new( path: agent_data.fetch('path'), description: agent_data['description'], depends_on: agent_data.fetch('depends_on', []) ) rescue KeyError => error raise ArgumentError, "Agent entry missing required field: #{error.key}" end end # @api private def self.parse_deprecated(deprecated_hash) deprecated_hash.transform_values do |entry_data| DeprecatedEntry.new( moved_to: entry_data.fetch('moved_to'), message: entry_data.fetch('message'), removed_in: entry_data['removed_in'] ) rescue KeyError => error raise ArgumentError, "Deprecated skill entry missing required field: #{error.key}" end end private_class_method :parse_skills, :parse_agents, :parse_deprecated end |
Class Method Details
.build_resolver(config = RailsAiBridge.configuration.registry) ⇒ Resolver?
Builds (or returns a cached) Resolver from the current Config::Registry.
The first call for a given TTL window loads the manifest from disk, wires the SkillSourceResolver and PackResolver pipeline, and caches the result. Subsequent calls within the TTL window return the same resolver without I/O.
Returns +nil+ when the registry manifest file does not exist, allowing callers to surface a helpful setup message rather than raising. A nil result is never cached — the next call will retry.
80 81 82 |
# File 'lib/rails_ai_bridge/registry.rb', line 80 def self.build_resolver(config = RailsAiBridge.configuration.registry) resolver_cache.fetch(config) { build_resolver_uncached(config) } end |
.invalidate_resolver_cache! ⇒ void
This method returns an undefined value.
Discards the cached resolver so the next build_resolver call rebuilds from disk.
Call this after clearing the git cache or modifying the registry manifest at runtime.
64 65 66 |
# File 'lib/rails_ai_bridge/registry.rb', line 64 def self.invalidate_resolver_cache! @resolver_cache_mutex.synchronize { @resolver_cache&.invalidate! } end |
.resolver_cache ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns the module-level ResolverCache instance, creating it on first call.
53 54 55 56 57 |
# File 'lib/rails_ai_bridge/registry.rb', line 53 def self.resolver_cache @resolver_cache_mutex.synchronize do @resolver_cache ||= ResolverCache.new end end |