# Literal

> Comprehensive skill for the Literal Ruby gem (https://literal.fun) by Joel Drapper. Use when writing or reviewing Ruby code that uses Literal - typed properties via `prop`/`prop?`, runtime type matchers `_Array`/`_Union`/`_Map`/etc., structured objects (`Literal::Struct`, `Literal::Data`), value objects (`Literal::Value`, `Literal::Delegator`), enums (`Literal::Enum`), bitfield flags (`Literal::F…

- **Type:** Skill
- **Install:** `agentstack add skill-stevegeek-claude-ruby-plugins-literal`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [stevegeek](https://agentstack.voostack.com/s/stevegeek)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** Unlicense
- **Upstream author:** [stevegeek](https://github.com/stevegeek)
- **Source:** https://github.com/stevegeek/claude-ruby-plugins/tree/main/plugins/literal/skills/literal

## Install

```sh
agentstack add skill-stevegeek-claude-ruby-plugins-literal
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Literal

Literal is a runtime type system for Ruby. It checks types when objects are constructed and when methods are called - no separate type checker needed. The library also provides building blocks for structured objects (Struct/Data), value objects, enums, flags, generic collections, and result monads.

The gemspec summary captures it: *"Enums, properties, generics, structured objects and runtime type checking."*

- Repo: https://github.com/joeldrapper/literal
- Docs: https://literal.fun
- License: MIT, requires Ruby >= 3.1

## How to use this skill

This skill is organised around the major user-facing features. The top-level features are listed below. When the user is working on a specific feature, load the matching reference file from `references/` for full details. Don't load every reference up-front - they're meant to be consulted as needed.

## Core idea: types are anything that responds to `===`

In Literal, a "type" is just anything that returns true/false from `===`. That includes:

- Plain Ruby classes (`String`, `Integer`, `MyClass`) - via `Module#===` (instance check)
- Ranges (`1..10`) - via `Range#===` (cover check)
- Regexps (`/foo/`) - via `Regexp#===` (match check)
- Procs/lambdas - via `Proc#===` (call check)
- Literal's own type matchers from `Literal::Types` (all prefixed with `_`)
- Any object you define with `===`

This is why every Literal API that accepts a "type" can also accept a primitive class or range.

## Top-level features (and which reference to load)

| Feature | What it is | Reference |
|---|---|---|
| Type matchers (`_Array`, `_Union`, `_Map`, `_Nilable`, `_Constraint`, ...) | The `_*` methods from `Literal::Types` for building runtime types | `references/types.md` |
| `prop` / `prop?` | Typed properties on any class via `extend Literal::Properties` | `references/properties.md` |
| `Literal::Struct` | Mutable structured object with `prop` (writers + readers public by default) | `references/struct-and-data.md` |
| `Literal::Data` | Frozen, immutable structured object with `prop` (reader-only) | `references/struct-and-data.md` |
| `Literal::Value(...)` | Typed value-object wrapper around a single value (e.g. `UserID = Literal::Value(Integer)`) | `references/value-and-delegator.md` |
| `Literal::Delegator(...)` | Typed delegator wrapping a value with full method delegation | `references/value-and-delegator.md` |
| `Literal::Enum(type)` | Closed set of typed members with predicates, indexing, ordering | `references/enum.md` |
| `Literal::Flags8/16/32/64` | Compact bitfield with named flags (boolean attributes) | `references/flags.md` |
| `Literal::Array/Set/Hash/Tuple` generics | Type-checked collection wrappers (`Literal::Array(String)`) | `references/collections.md` |
| `Literal::Result(success_t, failure_t)` | Result monad with `Success`/`Failure`, `try`, `and_then`, `also`, `handle` | `references/result.md` |
| `Literal::SerializationContext` + serializers | JSON-style serialize/deserialize driven by Literal types | `references/serialization.md` |
| `Literal.check`, `Literal.subtype?`, error messages | Programmatic type checking and subtype predicates | `references/runtime-checks.md` |
| Rails integration | `ActiveModel::Type` wrappers for enums and flags, `ActiveRecord::Relation(Model)` matcher | `references/rails.md` |

## Quick example

```ruby
require "literal"

class User  { [] }
end

user = User.new(id: 1, name: "Alice", tags: [:admin])
# raises Literal::TypeError: id must be Integer, got "1"
User.new(id: "1", name: "Alice")
```

## Conventions Joel uses (from the project's AGENTS.md)

- Never use `is_a?` - prefer `===`, `in`, or `case`/`when`. Literal's whole API is built on `===`.
- Tests use a small custom `test do ... end` DSL (see the gem's `test/`); not RSpec or Minitest's `def test_*`.

## When NOT to use Literal

- You already have a Sorbet/RBS/Steep type system covering the codebase. Literal's runtime checks are duplicative there - though many people happily use both, since runtime checks catch what static checkers can't (e.g. unknown JSON shape).
- Hot inner loops where every method call goes through a type check. Literal is fast but not free; benchmark before adopting in tight loops.

## Reference index

- `references/types.md` - Every `_Type` matcher with examples
- `references/properties.md` - `prop`, `prop?`, kinds, defaults, coercion, predicates, writers, introspection
- `references/struct-and-data.md` - `Literal::Struct` vs `Literal::Data`, when to pick which
- `references/value-and-delegator.md` - `Literal::Value` and `Literal::Delegator` for value objects
- `references/enum.md` - `Literal::Enum` members, indexes, coercion, ordering
- `references/flags.md` - `Literal::Flags8/16/32/64` bitfields
- `references/collections.md` - `Literal::Array`, `Set`, `Hash`, `Tuple` generic collections
- `references/result.md` - `Literal::Result`, `Success`, `Failure`, `handle`, `try`, `and_then`
- `references/serialization.md` - `SerializationContext` and the built-in serializers
- `references/runtime-checks.md` - `Literal.check`, `Literal.subtype?`, type errors, `Brand`
- `references/rails.md` - Rails / ActiveModel / ActiveRecord integration
- `references/patterns.md` - Idioms and gotchas across the library

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [stevegeek](https://github.com/stevegeek)
- **Source:** [stevegeek/claude-ruby-plugins](https://github.com/stevegeek/claude-ruby-plugins)
- **License:** Unlicense

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-stevegeek-claude-ruby-plugins-literal
- Seller: https://agentstack.voostack.com/s/stevegeek
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
