Introducing gem-skill: Teaching Your AI About Your Gems
There are three layers to what an LLM knows during a coding session.
The first is training knowledge — everything the model absorbed from the web before its cutoff date. For popular libraries like Rails or Faraday, this is solid ground. The model has read hundreds of Stack Overflow threads, blog posts, and READMEs about them. It knows the API. It knows the common mistakes. It can write idiomatic code without being told anything.
The second is context — what you put in front of the model in this conversation. System prompts, file contents, pasted documentation, your current CLAUDE.md. This is the stuff the model didn’t know before you started talking. It’s reliable, but it costs tokens, and it evaporates when the session ends.
The third layer is skills — structured knowledge injected at session start, pre-built so it doesn’t have to be reconstructed every time. Skills sit between training and context. They’re not raw training data (they’re curated and specific), and they’re not ephemeral context (they persist across sessions as files). A skill is a markdown document that describes, in exactly the terms an AI needs, how to work with a specific domain or tool.
The SKILL.md convention has gained enough traction that most modern AI coding tools know to look for and load skill files automatically. The gap that remains: nobody was generating those skills for Ruby gems.
That’s what gem-skill does.
The Problem: Gems Fall Through the Cracks
LLM training is a snapshot. Even models with recent cutoffs have uneven coverage of the Ruby ecosystem. Popular gems get decent representation. Less popular ones get almost none. Your own gems get zero.
And even for well-represented gems, training data doesn’t capture the current version. A model trained in late 2024 knows the Faraday 2.x API. If your project uses 2.12.x and that version introduced a breaking change or a new adapter pattern, the model is guessing.
Every time a new conversation starts, the model re-encounters your gems cold. If it’s a gem it knows well, you’re fine. If it’s an obscure gem, or a recent version of a less-popular one, or anything you wrote yourself, the model starts asking questions or — worse — starts confidently writing code that doesn’t match your actual API.
The standard fix is to paste documentation into the context window. This works, but it’s manual, it burns tokens, and you do it again the next session, and the one after that.
What a Skill Actually Is
A skill, in the context of Claude Code and similar tools, is a SKILL.md file that describes how to work with something. Not a tutorial. Not a README rehash. A compact, structured brief: what this thing does, how to install it, the core API you’ll actually use, the patterns that come up repeatedly, and the gotchas that will waste your afternoon if you don’t know about them.
The format is markdown. The content is pre-digested. The model reads it at session start and doesn’t have to infer any of it from first principles.
gem-skill generates exactly this for Ruby gems. It reads the gem’s documentation — README, CHANGELOG, whatever is available — runs it through an LLM, and produces a SKILL.md that covers:
- What the gem does and when to reach for it
- Installation — the Gemfile line and any post-install steps
- Core API — the classes and methods you’ll actually use, with working code examples
- Common patterns — the three to five things everyone ends up doing with this gem
- Gotchas — version-specific behavior, surprising defaults, thread safety, encoding traps
- Configuration — initializer patterns and environment variables
- Testing — how to test code that uses the gem
One generation, stored. Used forever.
The Cache
gem-skill maintains a global cache at ~/.gem/skills:
~/.gem/skills/
└── debug_me/
├── 1.2.3/
│ ├── SKILL.md
│ └── metadata.json
└── 1.3.0/
├── SKILL.md
└── metadata.json
Each version of each gem gets its own directory. The metadata records which model generated it and when. Two projects that pin different versions of the same gem each get the right skill — the underlying content is generated once and shared.
Projects opt in by symlinking from .claude/skills/:
your-project/.claude/skills/
└── debug_me/ → ~/.gem/skills/debug_me/1.3.0/
Claude Code sees the symlink, reads the skill, and arrives at your first conversation already knowing how debug_me works.
Installation
gem install gem-skill
gem skill setup
gem skill setup registers gem-skill as a Bundler plugin. Run it once per machine. After that, bundle skill works in any project.
Usage
Global cache management
# Generate a skill for an installed gem
gem skill install debug_me
# Install skills for several gems at once (runs concurrently)
gem skill install debug_me faraday zeitwerk
# Force regeneration
gem skill install debug_me --force
# Use a specific model
gem skill install debug_me --model claude-sonnet-4-6
# See everything in the cache
gem skill list
# Remove a cached version
gem skill purge debug_me 1.2.3
If the gem isn’t installed locally, gem skill install installs it first.
Generating skills as you install gems
gem install faraday debug_me --with-skill
Skills are generated concurrently after all gems finish installing. One command, nothing extra to remember.
Project-aware: driven by Gemfile.lock
Run this from your project root after bundle install:
# Generate and link skills for all direct dependencies
bundle skill install
# Re-sync after bundle update (skips already-cached versions)
bundle skill refresh
# See what's linked in this project
bundle skill list
bundle skill install reads your Gemfile.lock, generates skills for every direct dependency, and creates the symlinks in .claude/skills/. On the next Claude Code session, those skills load automatically.
Why This Matters for Your Own Gems
The most compelling case isn’t the old popular gems. They were part of the LLM’s training data. The problem is the new versions, the new capability, the breaking changes, the recently discovered security flaws. That is not in the model’s training data.
Every new gem or new gem version is either poorly represented in training data or not there at all. In every AI conversation I’ve been re-explaining the API, or watching the model make reasonable-sounding mistakes. gem-skill helps mitigate that. It generates the skill once for a new gem or gem version into a global cache. From that global cache it probides a way to symlink the SKILL.md file to every project that uses the gem, done.
For teams sharing a private gem: generate the skill, commit it to your skill cache or check it into the project’s .claude/skills/ directly, and every developer, human or not, gets the same accurate briefing from day one.
Configuration
Two environment variables:
| Variable | Default | Description |
|---|---|---|
GEMSKILL_DIR |
~/.gem/skills |
Root for the skill cache |
GEMSKILL_MODEL |
gpt-5.5 |
LLM used for generation |
# Use Claude for generation instead
export GEMSKILL_MODEL="claude-sonnet-4-6"
# Point the cache at a shared drive
export GEMSKILL_DIR="/Volumes/shared/gem-skills"
The --model flag on any command overrides GEMSKILL_MODEL for that invocation.
Getting Started
gem install gem-skill
gem skill setup
cd your-ruby-project
bundle skill install
That’s the full workflow. The next time you open a Claude Code session in that project, your gems are already briefed.
Source and documentation: github.com/MadBomber/gem-skill