Class: Riffer::Skills::Frontmatter

Inherits:
Object
  • Object
show all
Defined in:
lib/riffer/skills/frontmatter.rb,
sig/generated/riffer/skills/frontmatter.rbs

Overview

Immutable value object holding parsed SKILL.md YAML frontmatter. Required fields: name and description; the optional disable-model-invocation flag is recognized, and any other unrecognized top-level keys are merged into metadata.

Constant Summary collapse

NAME_PATTERN =

: Regexp

Returns:

  • (Regexp)
/\A[a-z0-9]+(-[a-z0-9]+)*\z/
MAX_NAME_LENGTH =

: Integer

Returns:

  • (Integer)
64
MAX_DESCRIPTION_LENGTH =

: Integer

Returns:

  • (Integer)
1024

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name:, description:, disable_model_invocation: false, metadata: {}) ⇒ Frontmatter

Raises Riffer::ArgumentError if name or description is invalid. disable_model_invocation is treated as set only when literally true.

: (name: String, description: String, ?disable_model_invocation: bool, ?metadata: Hash[Symbol, untyped]) -> void

Parameters:

  • name: (String)
  • description: (String)
  • disable_model_invocation: (Boolean) (defaults to: false)
  • metadata: (Hash[Symbol, untyped]) (defaults to: {})


70
71
72
73
74
75
76
77
# File 'lib/riffer/skills/frontmatter.rb', line 70

def initialize(name:, description:, disable_model_invocation: false, metadata: {})
  validate_name!(name)
  validate_description!(description)
  @name = name.freeze
  @description = description.freeze
  @disable_model_invocation = (disable_model_invocation == true)
  @metadata = .freeze
end

Instance Attribute Details

#descriptionString (readonly)

The skill description (1-1024 chars).

Returns:

  • (String)


19
20
21
# File 'lib/riffer/skills/frontmatter.rb', line 19

def description
  @description
end

#disable_model_invocationBoolean (readonly)

Whether the skill opts out of model-driven activation. Hidden from the catalog and rejected at model activation; still reachable via programmatic activation.

Returns:

  • (Boolean)


24
25
26
# File 'lib/riffer/skills/frontmatter.rb', line 24

def disable_model_invocation
  @disable_model_invocation
end

#metadataHash[Symbol, untyped] (readonly)

Metadata from the spec's metadata field plus any unrecognized top-level keys.

Returns:

  • (Hash[Symbol, untyped])


28
29
30
# File 'lib/riffer/skills/frontmatter.rb', line 28

def 
  @metadata
end

#nameString (readonly)

The skill name (1-64 chars, lowercase alphanumeric and hyphens).

Returns:

  • (String)


16
17
18
# File 'lib/riffer/skills/frontmatter.rb', line 16

def name
  @name
end

Class Method Details

.parse(raw) ⇒ [ Riffer::Skills::Frontmatter, String ]

Parses a raw SKILL.md string into a [Frontmatter, body] pair — public so custom backends needn't reimplement parsing. Raises Riffer::ArgumentError if the frontmatter is invalid.

: (String) -> [Riffer::Skills::Frontmatter, String]

Parameters:

  • (String)

Returns:



35
36
37
38
39
# File 'lib/riffer/skills/frontmatter.rb', line 35

def self.parse(raw)
  yaml, body = split_frontmatter(raw)
  raise Riffer::ArgumentError, "missing YAML frontmatter (expected --- delimiters)" if yaml.empty?
  [new(name: yaml.delete(:name), description: yaml.delete(:description), disable_model_invocation: yaml.delete(:"disable-model-invocation"), metadata: yaml), body]
end

.parse_frontmatter(raw) ⇒ Riffer::Skills::Frontmatter

Parses only the frontmatter from a raw SKILL.md string, ignoring the body. Raises Riffer::ArgumentError if the frontmatter is invalid.

: (String) -> Riffer::Skills::Frontmatter

Parameters:

  • (String)

Returns:



45
46
47
48
49
# File 'lib/riffer/skills/frontmatter.rb', line 45

def self.parse_frontmatter(raw)
  yaml, _ = split_frontmatter(raw)
  raise Riffer::ArgumentError, "missing YAML frontmatter (expected --- delimiters)" if yaml.empty?
  new(name: yaml.delete(:name), description: yaml.delete(:description), disable_model_invocation: yaml.delete(:"disable-model-invocation"), metadata: yaml)
end

Instance Method Details

#validate_description!(description) ⇒ void

This method returns an undefined value.

-- : (untyped) -> void

Parameters:

  • (Object)


91
92
93
94
# File 'lib/riffer/skills/frontmatter.rb', line 91

def validate_description!(description)
  raise Riffer::ArgumentError, "description must be a String" unless description.is_a?(String)
  raise Riffer::ArgumentError, "description must be 1-#{MAX_DESCRIPTION_LENGTH} characters" if description.empty? || description.length > MAX_DESCRIPTION_LENGTH
end

#validate_name!(name) ⇒ void

This method returns an undefined value.

-- : (untyped) -> void

Parameters:

  • (Object)


83
84
85
86
87
# File 'lib/riffer/skills/frontmatter.rb', line 83

def validate_name!(name)
  raise Riffer::ArgumentError, "name must be a String" unless name.is_a?(String)
  raise Riffer::ArgumentError, "name must be 1-#{MAX_NAME_LENGTH} characters" if name.empty? || name.length > MAX_NAME_LENGTH
  raise Riffer::ArgumentError, "name must match #{NAME_PATTERN.source}" unless NAME_PATTERN.match?(name)
end