rails-ai-context 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.ruby-version +1 -0
- data/CHANGELOG.md +15 -1
- data/CONTRIBUTING.md +76 -0
- data/README.md +19 -1
- data/lib/generators/rails_ai_context/install/install_generator.rb +11 -3
- data/lib/rails_ai_context/serializers/context_file_serializer.rb +4 -1
- data/lib/rails_ai_context/tasks/rails_ai_context.rake +33 -3
- data/lib/rails_ai_context/version.rb +1 -1
- data/rails-ai-context.gemspec +15 -4
- metadata +16 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f762c8f111cca6b60293f4d3eb26ef68aeb9e1d0c97048b46dcf221ebf7d6069
|
|
4
|
+
data.tar.gz: 01b9e656715c47aa0a3e67cfb75fb6ac1a5fd7d6444b4ac96837c6202a093487
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a5daa689b56aeee3225f0bfa983580adeabbc195c2184b669f5a3689d1cd2760d115afefcc2c925e14eefafea2b28729893b260f141acd00f5e89a6bcb4fc665
|
|
7
|
+
data.tar.gz: 7fba10086525e15044867dc4c1b5c5a44fd8eaf5f66c08ffbbd6468dfb1f2831d5b03231ec3e0ca02e2fec2a30a4558cd5567262642edf92c750a4bd8286fdc4
|
data/.ruby-version
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.4.9
|
data/CHANGELOG.md
CHANGED
|
@@ -5,7 +5,21 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
-
## [0.
|
|
8
|
+
## [0.2.0] - 2026-03-18
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Named rake tasks (`ai:context:claude`, `ai:context:cursor`, etc.) that work without quoting in zsh
|
|
13
|
+
- AI assistant summary table printed after `ai:context` and `ai:inspect`
|
|
14
|
+
- `ENV["FORMAT"]` fallback for `ai:context_for` task
|
|
15
|
+
- Format validation in `ContextFileSerializer` — unknown formats now raise `ArgumentError` with valid options
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- `rails ai:context_for[claude]` failing in zsh due to bracket glob interpretation
|
|
20
|
+
- Double introspection in `ai:context` and `ai:context_for` tasks (removed unused `RailsAiContext.introspect` calls)
|
|
21
|
+
|
|
22
|
+
## [0.1.0] - 2026-03-18
|
|
9
23
|
|
|
10
24
|
### Added
|
|
11
25
|
|
data/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Contributing to rails-ai-context
|
|
2
|
+
|
|
3
|
+
Thanks for your interest in contributing! This guide covers everything you need to get started.
|
|
4
|
+
|
|
5
|
+
## Development Setup
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
git clone https://github.com/crisnahine/rails-ai-context.git
|
|
9
|
+
cd rails-ai-context
|
|
10
|
+
bundle install
|
|
11
|
+
bundle exec rspec
|
|
12
|
+
bundle exec rubocop --parallel
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
The test suite uses [Combustion](https://github.com/pat/combustion) to boot a minimal Rails app in `spec/internal/`. No external database required — tests run against an in-memory SQLite database.
|
|
16
|
+
|
|
17
|
+
## Project Structure
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
lib/rails_ai_context/
|
|
21
|
+
├── introspectors/ # One class per data source (schema, models, routes, etc.)
|
|
22
|
+
├── tools/ # MCP tool definitions (one per introspector)
|
|
23
|
+
├── serializers/ # Output formatters (markdown, JSON, context files)
|
|
24
|
+
├── server.rb # MCP server setup (stdio + HTTP)
|
|
25
|
+
├── engine.rb # Rails Engine for auto-integration
|
|
26
|
+
└── configuration.rb # User-facing config options
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Adding a New Introspector
|
|
30
|
+
|
|
31
|
+
1. Create `lib/rails_ai_context/introspectors/your_introspector.rb`
|
|
32
|
+
2. Implement `#initialize(app)` and `#call` → returns a Hash (never raises)
|
|
33
|
+
3. Register it in `lib/rails_ai_context/introspector.rb` (the `INTROSPECTOR_MAP`)
|
|
34
|
+
4. Add the key to `Configuration#introspectors` default list
|
|
35
|
+
5. Write specs in `spec/lib/rails_ai_context/your_introspector_spec.rb`
|
|
36
|
+
|
|
37
|
+
## Adding a New MCP Tool
|
|
38
|
+
|
|
39
|
+
1. Create `lib/rails_ai_context/tools/your_tool.rb` inheriting from `BaseTool`
|
|
40
|
+
2. Define `tool_name`, `description`, `input_schema`, and `annotations`
|
|
41
|
+
3. Implement `def self.call(...)` returning `text_response(string)`
|
|
42
|
+
4. Register in `Server::TOOLS`
|
|
43
|
+
5. Add `require_relative` in `lib/rails_ai_context.rb`
|
|
44
|
+
6. Write specs in `spec/lib/rails_ai_context/tools/your_tool_spec.rb`
|
|
45
|
+
|
|
46
|
+
## Code Style
|
|
47
|
+
|
|
48
|
+
- Follow `rubocop-rails-omakase` style (run `bundle exec rubocop`)
|
|
49
|
+
- Ruby 3.2+ features welcome (pattern matching, etc.)
|
|
50
|
+
- Every introspector must return a Hash and never raise — wrap errors in `{ error: msg }`
|
|
51
|
+
- MCP tools return `MCP::Tool::Response` objects
|
|
52
|
+
- All tools must be prefixed with `rails_` and annotated as read-only
|
|
53
|
+
|
|
54
|
+
## Running Tests
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
bundle exec rspec # Full test suite
|
|
58
|
+
bundle exec rspec spec/lib/ # Just lib specs
|
|
59
|
+
bundle exec rubocop --parallel # Lint check
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Pull Request Process
|
|
63
|
+
|
|
64
|
+
1. Fork the repo and create your branch from `main`
|
|
65
|
+
2. Add tests for any new functionality
|
|
66
|
+
3. Ensure `bundle exec rspec` and `bundle exec rubocop` pass
|
|
67
|
+
4. Update CHANGELOG.md under an `## [Unreleased]` section
|
|
68
|
+
5. Open a PR with a clear title and description
|
|
69
|
+
|
|
70
|
+
## Reporting Bugs
|
|
71
|
+
|
|
72
|
+
Open an issue at https://github.com/crisnahine/rails-ai-context/issues with:
|
|
73
|
+
- Ruby and Rails versions
|
|
74
|
+
- Gem version
|
|
75
|
+
- Steps to reproduce
|
|
76
|
+
- Expected vs actual behavior
|
data/README.md
CHANGED
|
@@ -150,16 +150,34 @@ end
|
|
|
150
150
|
|
|
151
151
|
---
|
|
152
152
|
|
|
153
|
+
## Supported AI Assistants
|
|
154
|
+
|
|
155
|
+
| AI Assistant | Context File | Command |
|
|
156
|
+
|--------------|-------------|---------|
|
|
157
|
+
| Claude Code | `CLAUDE.md` | `rails ai:context:claude` |
|
|
158
|
+
| Cursor | `.cursorrules` | `rails ai:context:cursor` |
|
|
159
|
+
| Windsurf | `.windsurfrules` | `rails ai:context:windsurf` |
|
|
160
|
+
| GitHub Copilot | `.github/copilot-instructions.md` | `rails ai:context:copilot` |
|
|
161
|
+
| JSON (generic) | `.ai-context.json` | `rails ai:context:json` |
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
153
165
|
## Rake Tasks
|
|
154
166
|
|
|
155
167
|
| Command | Description |
|
|
156
168
|
|---------|-------------|
|
|
157
169
|
| `rails ai:context` | Generate all context files (CLAUDE.md, .cursorrules, etc.) |
|
|
158
|
-
| `rails ai:
|
|
170
|
+
| `rails ai:context:claude` | Generate CLAUDE.md only |
|
|
171
|
+
| `rails ai:context:cursor` | Generate .cursorrules only |
|
|
172
|
+
| `rails ai:context:windsurf` | Generate .windsurfrules only |
|
|
173
|
+
| `rails ai:context:copilot` | Generate .github/copilot-instructions.md only |
|
|
174
|
+
| `rails ai:context:json` | Generate .ai-context.json only |
|
|
159
175
|
| `rails ai:serve` | Start MCP server (stdio, for Claude Code) |
|
|
160
176
|
| `rails ai:serve_http` | Start MCP server (HTTP, for remote clients) |
|
|
161
177
|
| `rails ai:inspect` | Print introspection summary to stdout |
|
|
162
178
|
|
|
179
|
+
> **zsh users:** The bracket syntax `rails ai:context_for[claude]` requires quoting in zsh (`rails 'ai:context_for[claude]'`). The named tasks above (`rails ai:context:claude`) work without quoting in any shell.
|
|
180
|
+
|
|
163
181
|
---
|
|
164
182
|
|
|
165
183
|
## Works Without a Database
|
|
@@ -71,9 +71,17 @@ module RailsAiContext
|
|
|
71
71
|
say "=" * 50, :cyan
|
|
72
72
|
say ""
|
|
73
73
|
say "Quick start:", :yellow
|
|
74
|
-
say " rails ai:context
|
|
75
|
-
say " rails ai:
|
|
76
|
-
say " rails ai:
|
|
74
|
+
say " rails ai:context # Generate all context files"
|
|
75
|
+
say " rails ai:context:claude # Generate CLAUDE.md only"
|
|
76
|
+
say " rails ai:context:cursor # Generate .cursorrules only"
|
|
77
|
+
say " rails ai:serve # Start MCP server (stdio)"
|
|
78
|
+
say " rails ai:inspect # Print introspection summary"
|
|
79
|
+
say ""
|
|
80
|
+
say "Supported AI assistants:", :yellow
|
|
81
|
+
say " Claude Code → CLAUDE.md (rails ai:context:claude)"
|
|
82
|
+
say " Cursor → .cursorrules (rails ai:context:cursor)"
|
|
83
|
+
say " Windsurf → .windsurfrules (rails ai:context:windsurf)"
|
|
84
|
+
say " GitHub Copilot → .github/copilot-instructions.md (rails ai:context:copilot)"
|
|
77
85
|
say ""
|
|
78
86
|
say "For Claude Code, add to your claude_desktop_config.json:", :yellow
|
|
79
87
|
say ' { "mcpServers": { "rails": { "command": "rails", "args": ["ai:serve"], "cwd": "/path/to/your/app" } } }'
|
|
@@ -29,7 +29,10 @@ module RailsAiContext
|
|
|
29
29
|
|
|
30
30
|
formats.each do |fmt|
|
|
31
31
|
filename = FORMAT_MAP[fmt]
|
|
32
|
-
|
|
32
|
+
unless filename
|
|
33
|
+
valid = FORMAT_MAP.keys.map(&:to_s).join(", ")
|
|
34
|
+
raise ArgumentError, "Unknown format: #{fmt}. Valid formats: #{valid}"
|
|
35
|
+
end
|
|
33
36
|
|
|
34
37
|
filepath = File.join(output_dir, filename)
|
|
35
38
|
|
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
ASSISTANT_TABLE = <<~TABLE
|
|
4
|
+
AI Assistant Context File Command
|
|
5
|
+
-- -- --
|
|
6
|
+
Claude Code CLAUDE.md rails ai:context:claude
|
|
7
|
+
Cursor .cursorrules rails ai:context:cursor
|
|
8
|
+
Windsurf .windsurfrules rails ai:context:windsurf
|
|
9
|
+
GitHub Copilot .github/copilot-instructions.md rails ai:context:copilot
|
|
10
|
+
JSON (generic) .ai-context.json rails ai:context:json
|
|
11
|
+
TABLE
|
|
12
|
+
|
|
3
13
|
namespace :ai do
|
|
4
14
|
desc "Generate AI context files (CLAUDE.md, .cursorrules, .windsurfrules, .github/copilot-instructions.md)"
|
|
5
15
|
task context: :environment do
|
|
6
16
|
require "rails_ai_context"
|
|
7
17
|
|
|
8
18
|
puts "🔍 Introspecting #{Rails.application.class.module_parent_name}..."
|
|
9
|
-
context = RailsAiContext.introspect
|
|
10
19
|
|
|
11
20
|
puts "📝 Writing context files..."
|
|
12
21
|
files = RailsAiContext.generate_context(format: :all)
|
|
@@ -15,15 +24,16 @@ namespace :ai do
|
|
|
15
24
|
puts ""
|
|
16
25
|
puts "Done! Your AI assistants now understand your Rails app."
|
|
17
26
|
puts "Commit these files so your whole team benefits."
|
|
27
|
+
puts ""
|
|
28
|
+
puts ASSISTANT_TABLE
|
|
18
29
|
end
|
|
19
30
|
|
|
20
31
|
desc "Generate AI context in a specific format (claude, cursor, windsurf, copilot, json)"
|
|
21
32
|
task :context_for, [:format] => :environment do |_t, args|
|
|
22
33
|
require "rails_ai_context"
|
|
23
34
|
|
|
24
|
-
format = (args[:format] || "claude").to_sym
|
|
35
|
+
format = (args[:format] || ENV["FORMAT"] || "claude").to_sym
|
|
25
36
|
puts "🔍 Introspecting #{Rails.application.class.module_parent_name}..."
|
|
26
|
-
context = RailsAiContext.introspect
|
|
27
37
|
|
|
28
38
|
puts "📝 Writing #{format} context file..."
|
|
29
39
|
files = RailsAiContext.generate_context(format: format)
|
|
@@ -31,6 +41,24 @@ namespace :ai do
|
|
|
31
41
|
files.each { |f| puts " ✅ #{f}" }
|
|
32
42
|
end
|
|
33
43
|
|
|
44
|
+
namespace :context do
|
|
45
|
+
{ claude: "CLAUDE.md", cursor: ".cursorrules", windsurf: ".windsurfrules",
|
|
46
|
+
copilot: ".github/copilot-instructions.md", json: ".ai-context.json" }.each do |fmt, file|
|
|
47
|
+
desc "Generate #{file} context file"
|
|
48
|
+
task fmt => :environment do
|
|
49
|
+
require "rails_ai_context"
|
|
50
|
+
|
|
51
|
+
puts "🔍 Introspecting #{Rails.application.class.module_parent_name}..."
|
|
52
|
+
puts "📝 Writing #{file}..."
|
|
53
|
+
files = RailsAiContext.generate_context(format: fmt)
|
|
54
|
+
|
|
55
|
+
files.each { |f| puts " ✅ #{f}" }
|
|
56
|
+
puts ""
|
|
57
|
+
puts "Tip: Run `rails ai:context` to generate all formats at once."
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
34
62
|
desc "Start the MCP server (stdio transport, for Claude Code / Cursor)"
|
|
35
63
|
task serve: :environment do
|
|
36
64
|
require "rails_ai_context"
|
|
@@ -83,6 +111,8 @@ namespace :ai do
|
|
|
83
111
|
puts "🏛️ Architecture: #{arch.join(', ')}" if arch.any?
|
|
84
112
|
end
|
|
85
113
|
|
|
114
|
+
puts ""
|
|
115
|
+
puts ASSISTANT_TABLE
|
|
86
116
|
puts ""
|
|
87
117
|
puts "Run `rails ai:context` to generate context files."
|
|
88
118
|
end
|
data/rails-ai-context.gemspec
CHANGED
|
@@ -8,7 +8,7 @@ Gem::Specification.new do |spec|
|
|
|
8
8
|
spec.authors = ["crisnahine"]
|
|
9
9
|
spec.email = ["crisjosephnahine@gmail.com"]
|
|
10
10
|
|
|
11
|
-
spec.summary = "
|
|
11
|
+
spec.summary = "Auto-expose Rails app structure to AI via MCP (Model Context Protocol) — zero config."
|
|
12
12
|
spec.description = <<~DESC
|
|
13
13
|
rails-ai-context automatically introspects your Rails application and exposes
|
|
14
14
|
models, routes, schema, jobs, mailers, and conventions through the Model Context
|
|
@@ -21,11 +21,22 @@ Gem::Specification.new do |spec|
|
|
|
21
21
|
|
|
22
22
|
spec.required_ruby_version = ">= 3.2.0"
|
|
23
23
|
|
|
24
|
-
spec.metadata["homepage_uri"]
|
|
25
|
-
spec.metadata["source_code_uri"]
|
|
26
|
-
spec.metadata["changelog_uri"]
|
|
24
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
|
25
|
+
spec.metadata["source_code_uri"] = spec.homepage
|
|
26
|
+
spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/CHANGELOG.md"
|
|
27
|
+
spec.metadata["documentation_uri"] = "#{spec.homepage}#readme"
|
|
28
|
+
spec.metadata["bug_tracker_uri"] = "#{spec.homepage}/issues"
|
|
29
|
+
spec.metadata["funding_uri"] = "https://github.com/sponsors/crisnahine"
|
|
27
30
|
spec.metadata["rubygems_mfa_required"] = "true"
|
|
28
31
|
|
|
32
|
+
spec.post_install_message = <<~MSG
|
|
33
|
+
rails-ai-context installed! Quick start:
|
|
34
|
+
rails generate rails_ai_context:install
|
|
35
|
+
rails ai:context # generate all context files
|
|
36
|
+
rails ai:context:claude # generate CLAUDE.md only (zsh-friendly)
|
|
37
|
+
rails ai:serve # start MCP server for Claude Code / Cursor
|
|
38
|
+
MSG
|
|
39
|
+
|
|
29
40
|
spec.files = Dir.chdir(__dir__) do
|
|
30
41
|
`git ls-files -z`.split("\x0").reject do |f|
|
|
31
42
|
(File.expand_path(f) == __FILE__) ||
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rails-ai-context
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- crisnahine
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: exe
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: mcp
|
|
@@ -162,7 +161,9 @@ extra_rdoc_files: []
|
|
|
162
161
|
files:
|
|
163
162
|
- ".rspec"
|
|
164
163
|
- ".rubocop.yml"
|
|
164
|
+
- ".ruby-version"
|
|
165
165
|
- CHANGELOG.md
|
|
166
|
+
- CONTRIBUTING.md
|
|
166
167
|
- LICENSE
|
|
167
168
|
- README.md
|
|
168
169
|
- Rakefile
|
|
@@ -200,8 +201,16 @@ metadata:
|
|
|
200
201
|
homepage_uri: https://github.com/crisnahine/rails-ai-context
|
|
201
202
|
source_code_uri: https://github.com/crisnahine/rails-ai-context
|
|
202
203
|
changelog_uri: https://github.com/crisnahine/rails-ai-context/blob/main/CHANGELOG.md
|
|
204
|
+
documentation_uri: https://github.com/crisnahine/rails-ai-context#readme
|
|
205
|
+
bug_tracker_uri: https://github.com/crisnahine/rails-ai-context/issues
|
|
206
|
+
funding_uri: https://github.com/sponsors/crisnahine
|
|
203
207
|
rubygems_mfa_required: 'true'
|
|
204
|
-
post_install_message:
|
|
208
|
+
post_install_message: |
|
|
209
|
+
rails-ai-context installed! Quick start:
|
|
210
|
+
rails generate rails_ai_context:install
|
|
211
|
+
rails ai:context # generate all context files
|
|
212
|
+
rails ai:context:claude # generate CLAUDE.md only (zsh-friendly)
|
|
213
|
+
rails ai:serve # start MCP server for Claude Code / Cursor
|
|
205
214
|
rdoc_options: []
|
|
206
215
|
require_paths:
|
|
207
216
|
- lib
|
|
@@ -216,8 +225,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
216
225
|
- !ruby/object:Gem::Version
|
|
217
226
|
version: '0'
|
|
218
227
|
requirements: []
|
|
219
|
-
rubygems_version: 3.
|
|
220
|
-
signing_key:
|
|
228
|
+
rubygems_version: 3.6.9
|
|
221
229
|
specification_version: 4
|
|
222
|
-
summary:
|
|
230
|
+
summary: Auto-expose Rails app structure to AI via MCP (Model Context Protocol) —
|
|
231
|
+
zero config.
|
|
223
232
|
test_files: []
|