Claude Code Plugins

Community-maintained marketplace

Feedback

Write standalone .rbs signature files to describe Ruby code. Use when creating type definitions for gems, libraries, or existing codebases without modifying Ruby source.

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name rbs-files
description Write standalone .rbs signature files to describe Ruby code. Use when creating type definitions for gems, libraries, or existing codebases without modifying Ruby source.

Standalone RBS Files

Write type signatures in separate .rbs files in a sig/ directory. Ruby source files remain unchanged.

Quick Start

# sig/person.rbs
class Person
  attr_reader name: String
  attr_reader age: Integer?

  def initialize: (String name, ?Integer? age) -> void
  def greet: () -> String
end

File Structure

project/
├── lib/
│   └── person.rb          # Ruby implementation
├── sig/
│   ├── person.rbs         # Type signatures
│   ├── _private/          # Hidden from library users
│   │   └── internal.rbs
│   └── manifest.yaml      # Stdlib dependencies
└── Steepfile

Class and Module Declarations

# Basic class
class User
end

# With superclass
class Admin < User
end

# With type parameters
class Container[T]
end

# Module
module Logging
end

# Module with self-type constraint
module Enumerable[Elem] : _Each[Elem]
end

Method Definitions

class Calculator
  # Instance method
  def add: (Integer, Integer) -> Integer

  # Singleton (class) method
  def self.create: () -> Calculator

  # Module function (both singleton and private instance)
  def self?.sqrt: (Numeric) -> Float

  # Visibility
  private def internal: () -> void
end

Method Type Syntax

# Required positional
def foo: (String, Integer) -> void

# Optional positional (? prefix)
def foo: (String, ?Integer) -> void

# Rest positional
def foo: (*String) -> void

# Required keyword
def foo: (name: String) -> void

# Optional keyword
def foo: (?name: String) -> void

# Keyword rest
def foo: (**String) -> void

# Block (required)
def foo: () { (String) -> Integer } -> void

# Block (optional, ? before brace)
def foo: () ?{ (String) -> Integer } -> void

# Complex signature
def foo: (
  String,                    # Required positional
  ?Integer,                  # Optional positional
  *Symbol,                   # Rest positional
  name: String,              # Required keyword
  ?age: Integer,             # Optional keyword
  **untyped                  # Keyword rest
) { (String) -> void } -> Array[String]

Method Overloading

class Array[Elem]
  # Multiple signatures with |
  def *: (String) -> String
       | (Integer) -> Array[Elem]

  # Extending existing method with ...
  def fetch: (Integer) -> Elem
           | ...
end

Attributes

class User
  # Reader (generates getter + @name ivar)
  attr_reader name: String

  # Writer (generates setter + @email ivar)
  attr_writer email: String

  # Accessor (generates both)
  attr_accessor age: Integer

  # Custom ivar name
  attr_reader display_name (@raw_name): String

  # No ivar (computed property)
  attr_reader full_name (): String

  # Singleton attribute
  attr_reader self.instance: User
end

Instance and Class Variables

class Counter
  @count: Integer                    # Instance variable
  self.@instances: Array[Counter]    # Class instance variable
  @@total: Integer                   # Class variable
end

Constants

class Config
  VERSION: String
  MAX_SIZE: Integer
  VALID_STATES: Array[Symbol]
end

# Global variable
$LOAD_PATH: Array[String]

Interfaces

Define duck types that classes can implement:

interface _Readable
  def read: (?Integer) -> String?
  def eof?: () -> bool
end

interface _Writable
  def write: (String) -> Integer
end

class MyIO
  include _Readable
  include _Writable
end

Type Aliases

# Simple alias
type json_value = String | Integer | Float | bool | nil | Array[json_value] | Hash[String, json_value]

# Generic alias
type result[T] = [true, T] | [false, String]

# Scoped to class
class MyApp
  type callback = ^(String) -> void
end

Generics

# Basic generic class
class Box[T]
  def initialize: (T) -> void
  def get: () -> T
end

# Variance annotations
class ReadOnly[out T]        # Covariant
  def get: () -> T
end

class WriteOnly[in T]        # Contravariant
  def set: (T) -> void
end

# Unchecked variance (for mutable collections)
class Array[unchecked out T]
end

# Upper bound
class Sorter[T < Comparable]
  def sort: (Array[T]) -> Array[T]
end

# Default type
class Cache[T = String]
end

# Method-level generics
class Util
  def self.identity: [T] (T) -> T
  def self.map: [T, U] (Array[T]) { (T) -> U } -> Array[U]
end

Mixins

class User
  include Comparable
  include Enumerable[String]
  extend ClassMethods
  prepend Instrumentation
end

Use Directive

Import types to avoid fully-qualified names:

use RBS::TypeName
use RBS::AST::*

class MyParser
  def parse: (TypeName) -> untyped
end

manifest.yaml

Declare stdlib dependencies for gems:

# sig/manifest.yaml
dependencies:
  - name: json
  - name: pathname
  - name: set

Validate Signatures

# Check RBS syntax and consistency
bundle exec rbs validate

# Test signatures against runtime
RBS_TEST_TARGET='MyApp::*' bundle exec ruby -r rbs/test/setup test/my_test.rb