RubySage is a Rails engine that builds a structured, file-level index of your codebase — kept fresh by git fingerprints — and hands it to Claude Code, Cursor, or Codex in a 3K-token retrieval call instead of a 200K-token orientation. Same answers, a fraction of the bill.
Every Claude Code or Cursor session on a Rails app burns 50–200K input tokens just orienting itself. Reading models. Grepping routes. Re-deriving conventions. Across a team of five, that’s millions of tokens a day spent re-learning the same codebase before anyone writes a line.
The codebase has not changed that much. Most files are byte-identical to yesterday. What changed is knowable — git already fingerprints every file in the repo. The expensive work of mapping the app should happen once, not on every new chat.
CLAUDE.md / .cursorrules / AGENTS.md are useful for taste and conventions. They are also static prose someone wrote on a Tuesday — and they drift the moment you rename a service, split a controller, or swap a gem.
RubySage indexes the actual code. Every public class. Every route. Every service object. Per-file summaries that come from reading the file, not from a human guessing six months ago.
A rake task walks your codebase and produces per-file artifacts — summaries, public symbols, route mappings. Stored in your app's database. Secret values redacted. Files unchanged since the last scan are skipped via digest cache, so incremental runs are cheap.
When someone asks a question, RubySage retrieves the most relevant artifacts using keyword + symbol matching, boosted by the current page context. Not vector-only — Rails apps have strong lexical signals (model names, route paths) that BM25 nails.
Relevant artifacts go into a prompt with the question. The LLM answers, citing the specific files and classes it used. Anthropic prompt caching is on by day 1 — subsequent questions within ~5 minutes cost roughly 10× less.
# config/initializers/ruby_sage.rb
RubySage.configure do |config|
config.provider = :anthropic
config.model = "claude-sonnet-4-6"
config.api_key = ENV.fetch("ANTHROPIC_API_KEY", nil)
config.auth_check = ->(c) { c.current_user&.admin? }
endRubySage’s retrieval layer is a Ruby method and a JSON endpoint. Wire it into Claude Code, Cursor, Codex, or whatever agent you use. Instead of dumping the whole codebase into context, the agent pulls the 5–15 files the question actually needs — with summaries, public symbols, and route mappings prebaked.
# From inside your agent — Ruby
result = RubySage.context_for("how does subscription billing work?")
result[:artifacts] # => relevant Artifact records
result[:citations] # => [{path:, kind:, score:, snippet:}, ...]
result[:scan_id] # => Scan id used# From anywhere else — HTTP
curl -X POST https://your-app.com/ruby_sage/internal/retrieve \
-H "Content-Type: application/json" \
-d '{"query":"subscription billing"}'rake ruby_sage:onboard writes docs/ONBOARDING.md for humans and docs/AGENT_PRIMER.mdfor AI agents — under 600 words, fits any agent’s context prefix. Better than a hand-written CLAUDE.md because it actually reflects current code.
rake ruby_sage:scan:plan writes a manifest. Tell Claude Code or Cursor to read INSTRUCTIONS.md. Your existing subscription pays for the summaries — zero API spend, no new key to manage.
All figures USD, Anthropic Sonnet pricing. Your mileage will vary by codebase size and question patterns.
| Operation | Frequency | Cost |
|---|---|---|
| Initial full scan (200-file Rails app) | Once | $0.10 – $0.50 |
| Daily incremental scan (50 changed files) | Per day | $0.05 – $0.20 |
| Question, with prompt-cache hit | Per question | $0.01 – $0.05 |
| Question, cache miss | First of session | $0.10 – $0.30 |
Pre-bake scans in CI, ship artifacts to prod with rake ruby_sage:import_artifacts. Production runs zero LLM summarization. The expensive part lives in your CI runner.
Add the gem, generate the install, run your first scan. RubySage ships with the migrations and the rake tasks — no separate service, no extra infrastructure.
# Gemfile
gem "ruby_sage"
# Shell
bundle install
rails generate ruby_sage:install
rails db:migrate
bundle exec rake ruby_sage:scanThat’s it. The index is in your database, the retrieval API is live at /ruby_sage/internal/retrieve, and your team gets an optional chat widget if you drop oneruby_sage_widget line into your layout.
<%# app/views/layouts/application.html.erb — optional %>
<body>
<%= yield %>
<%= ruby_sage_widget %>
</body>