Install
$ agentstack add skill-stevegeek-claude-ruby-plugins-literal ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
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) - viaModule#===(instance check) - Ranges (
1..10) - viaRange#===(cover check) - Regexps (
/foo/) - viaRegexp#===(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
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, orcase/when. Literal's whole API is built on===. - Tests use a small custom
test do ... endDSL (see the gem'stest/); not RSpec or Minitest'sdef 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_Typematcher with examplesreferences/properties.md-prop,prop?, kinds, defaults, coercion, predicates, writers, introspectionreferences/struct-and-data.md-Literal::StructvsLiteral::Data, when to pick whichreferences/value-and-delegator.md-Literal::ValueandLiteral::Delegatorfor value objectsreferences/enum.md-Literal::Enummembers, indexes, coercion, orderingreferences/flags.md-Literal::Flags8/16/32/64bitfieldsreferences/collections.md-Literal::Array,Set,Hash,Tuplegeneric collectionsreferences/result.md-Literal::Result,Success,Failure,handle,try,and_thenreferences/serialization.md-SerializationContextand the built-in serializersreferences/runtime-checks.md-Literal.check,Literal.subtype?, type errors,Brandreferences/rails.md- Rails / ActiveModel / ActiveRecord integrationreferences/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
- Source: stevegeek/claude-ruby-plugins
- License: Unlicense
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.