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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 994a7f4531e3c387086796826815f5b4489107ec50b47d8bd86e46fa208d59ee
4
- data.tar.gz: 11dd7dae7425c70d1bff80a43a183b66b4a0863fffa72d2d227093f5d1928b30
3
+ metadata.gz: f762c8f111cca6b60293f4d3eb26ef68aeb9e1d0c97048b46dcf221ebf7d6069
4
+ data.tar.gz: 01b9e656715c47aa0a3e67cfb75fb6ac1a5fd7d6444b4ac96837c6202a093487
5
5
  SHA512:
6
- metadata.gz: 733527414a221eb42d66510eeeeead2d46ec69482998bd79c2b913c87cf34b37ec23160b0a44b22a07689aae7ae1f3bef37094e836c2a2a18b992d7d3620f294
7
- data.tar.gz: 1c4dfeb48b4a521631ae339de511dfe62ce2119c19fc8b50bfcee6fa3e8112632652f053e6040b4aa46bbf7ef47db352a90e41ff8dcc882631cb308c1638fa34
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.1.0] - Unreleased
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:context_for[claude]` | Generate for a specific format |
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 # Regenerate context files"
75
- say " rails ai:serve # Start MCP server (stdio)"
76
- say " rails ai:inspect # Print introspection summary"
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
- next unless filename
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsAiContext
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
@@ -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 = "Turn any Rails app into an AI-ready codebaseone gem install."
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"] = spec.homepage
25
- spec.metadata["source_code_uri"] = spec.homepage
26
- spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/CHANGELOG.md"
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.1.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: 2026-03-18 00:00:00.000000000 Z
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.3.7
220
- signing_key:
228
+ rubygems_version: 3.6.9
221
229
  specification_version: 4
222
- summary: Turn any Rails app into an AI-ready codebase one gem install.
230
+ summary: Auto-expose Rails app structure to AI via MCP (Model Context Protocol) —
231
+ zero config.
223
232
  test_files: []