Module: RailsAiBridge::Registry::SourceParser

Defined in:
lib/rails_ai_bridge/registry/source_parser.rb

Overview

Parses a raw pack source string and returns a typed ParsedSource value object.

Single responsibility: classify a source string into one of three formats and produce the canonical URL needed to resolve it. Raises RailsAiBridge::Registry::SkillSourceResolver::ResolutionError for unrecognized formats so callers get a clear error message naming all valid forms.

Supported formats:

  • Local path — starts with +/+, +./+, or +../+. Returned as-is; no git needed.
  • Full git URL — starts with +https://+ or +git@+ (SSH). Plain +http://+ is rejected to prevent unencrypted transmission of credentials and pack content. Used directly as the clone URL.
  • GitHub shorthand — exactly +owner/repo+. Expanded to +https://github.com/owner/repo.git+.

Examples:

Local absolute path

SourceParser.parse('/my/skills') #=> #<ParsedSource type=:local_path resolved_url="/my/skills">

Full URL

SourceParser.parse('https://github.com/org/repo.git') #=> #<ParsedSource type=:git_url ...>

GitHub shorthand

SourceParser.parse('igmarin/ruby-core-skills') #=> #<ParsedSource type=:github_shorthand ...>

Defined Under Namespace

Classes: ParsedSource

Constant Summary collapse

INVALID_SOURCE_MESSAGE =
<<~MSG
  Invalid source format: %<source>s

  Valid formats:
    Local path    /absolute/path  OR  ./relative  OR  ../relative
    HTTPS URL     https://github.com/owner/repo.git
    SSH URL       git@github.com:owner/repo.git
    GitHub short  owner/repo  (expanded to https://github.com/owner/repo.git)

  Note: plain http:// URLs are not supported — use https:// or git@ (SSH) instead.
MSG

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Attribute Details

#resolved_urlString (readonly)

Returns canonical URL/path suitable for git clone or direct use.

Returns:

  • (String)

    canonical URL/path suitable for git clone or direct use



31
# File 'lib/rails_ai_bridge/registry/source_parser.rb', line 31

ParsedSource = Data.define(:type, :resolved_url)

#typeSymbol (readonly)

Returns +:local_path+, +:git_url+, or +:github_shorthand+.

Returns:

  • (Symbol)

    +:local_path+, +:git_url+, or +:github_shorthand+



31
# File 'lib/rails_ai_bridge/registry/source_parser.rb', line 31

ParsedSource = Data.define(:type, :resolved_url)

Class Method Details

.parse(source) ⇒ ParsedSource

Parameters:

  • source (String)

    raw source string from the registry manifest

Returns:

Raises:



48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/rails_ai_bridge/registry/source_parser.rb', line 48

def self.parse(source)
  if source.nil? || source.strip.empty?
    raise SkillSourceResolver::ResolutionError,
          format(INVALID_SOURCE_MESSAGE, source: source.inspect)
  end

  return parse_local(source)     if local_path?(source)
  return parse_git_url(source)   if git_url?(source)
  return parse_shorthand(source) if github_shorthand?(source)

  raise SkillSourceResolver::ResolutionError, format(INVALID_SOURCE_MESSAGE, source: source)
end