rails-ai-context 4.3.2 → 4.3.3

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.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +72 -53
  3. data/CLAUDE.md +1 -1
  4. data/README.md +268 -197
  5. data/demo-trace.gif +0 -0
  6. data/demo-trace.tape +21 -0
  7. data/demo.gif +0 -0
  8. data/demo.tape +33 -0
  9. data/docs/GUIDE.md +9 -9
  10. data/lib/generators/rails_ai_context/install/install_generator.rb +2 -1
  11. data/lib/rails_ai_context/configuration.rb +1 -1
  12. data/lib/rails_ai_context/doctor.rb +4 -2
  13. data/lib/rails_ai_context/fingerprinter.rb +2 -1
  14. data/lib/rails_ai_context/introspectors/accessibility_introspector.rb +2 -1
  15. data/lib/rails_ai_context/introspectors/action_mailbox_introspector.rb +2 -1
  16. data/lib/rails_ai_context/introspectors/action_text_introspector.rb +2 -1
  17. data/lib/rails_ai_context/introspectors/active_storage_introspector.rb +6 -3
  18. data/lib/rails_ai_context/introspectors/api_introspector.rb +8 -4
  19. data/lib/rails_ai_context/introspectors/asset_pipeline_introspector.rb +6 -3
  20. data/lib/rails_ai_context/introspectors/auth_introspector.rb +14 -7
  21. data/lib/rails_ai_context/introspectors/config_introspector.rb +12 -6
  22. data/lib/rails_ai_context/introspectors/controller_introspector.rb +20 -10
  23. data/lib/rails_ai_context/introspectors/convention_detector.rb +2 -1
  24. data/lib/rails_ai_context/introspectors/design_token_introspector.rb +8 -4
  25. data/lib/rails_ai_context/introspectors/devops_introspector.rb +6 -3
  26. data/lib/rails_ai_context/introspectors/engine_introspector.rb +4 -2
  27. data/lib/rails_ai_context/introspectors/frontend_framework_introspector.rb +2 -1
  28. data/lib/rails_ai_context/introspectors/i18n_introspector.rb +2 -1
  29. data/lib/rails_ai_context/introspectors/job_introspector.rb +8 -4
  30. data/lib/rails_ai_context/introspectors/middleware_introspector.rb +4 -2
  31. data/lib/rails_ai_context/introspectors/migration_introspector.rb +2 -1
  32. data/lib/rails_ai_context/introspectors/model_introspector.rb +20 -10
  33. data/lib/rails_ai_context/introspectors/multi_database_introspector.rb +12 -6
  34. data/lib/rails_ai_context/introspectors/performance_introspector.rb +6 -3
  35. data/lib/rails_ai_context/introspectors/route_introspector.rb +4 -2
  36. data/lib/rails_ai_context/introspectors/schema_introspector.rb +14 -7
  37. data/lib/rails_ai_context/introspectors/seeds_introspector.rb +2 -1
  38. data/lib/rails_ai_context/introspectors/stimulus_introspector.rb +8 -4
  39. data/lib/rails_ai_context/introspectors/test_introspector.rb +8 -4
  40. data/lib/rails_ai_context/introspectors/turbo_introspector.rb +22 -11
  41. data/lib/rails_ai_context/introspectors/view_introspector.rb +8 -4
  42. data/lib/rails_ai_context/introspectors/view_template_introspector.rb +10 -5
  43. data/lib/rails_ai_context/tasks/rails_ai_context.rake +8 -4
  44. data/lib/rails_ai_context/tools/analyze_feature.rb +66 -19
  45. data/lib/rails_ai_context/tools/diagnose.rb +4 -2
  46. data/lib/rails_ai_context/tools/get_callbacks.rb +4 -2
  47. data/lib/rails_ai_context/tools/get_concern.rb +12 -6
  48. data/lib/rails_ai_context/tools/get_controllers.rb +10 -5
  49. data/lib/rails_ai_context/tools/get_conventions.rb +4 -2
  50. data/lib/rails_ai_context/tools/get_design_system.rb +2 -1
  51. data/lib/rails_ai_context/tools/get_env.rb +8 -4
  52. data/lib/rails_ai_context/tools/get_helper_methods.rb +6 -3
  53. data/lib/rails_ai_context/tools/get_job_pattern.rb +2 -1
  54. data/lib/rails_ai_context/tools/get_model_details.rb +10 -5
  55. data/lib/rails_ai_context/tools/get_partial_interface.rb +14 -7
  56. data/lib/rails_ai_context/tools/get_schema.rb +2 -1
  57. data/lib/rails_ai_context/tools/get_service_pattern.rb +2 -1
  58. data/lib/rails_ai_context/tools/get_stimulus.rb +2 -1
  59. data/lib/rails_ai_context/tools/get_test_info.rb +4 -2
  60. data/lib/rails_ai_context/tools/get_turbo_map.rb +22 -11
  61. data/lib/rails_ai_context/tools/get_view.rb +6 -3
  62. data/lib/rails_ai_context/tools/migration_advisor.rb +2 -1
  63. data/lib/rails_ai_context/tools/onboard.rb +2 -1
  64. data/lib/rails_ai_context/tools/performance_check.rb +2 -1
  65. data/lib/rails_ai_context/tools/runtime_info.rb +10 -5
  66. data/lib/rails_ai_context/tools/search_code.rb +8 -4
  67. data/lib/rails_ai_context/tools/search_docs.rb +2 -1
  68. data/lib/rails_ai_context/tools/session_context.rb +2 -1
  69. data/lib/rails_ai_context/tools/validate.rb +16 -8
  70. data/lib/rails_ai_context/version.rb +1 -1
  71. metadata +5 -1
data/README.md CHANGED
@@ -1,114 +1,161 @@
1
+ <div align="center">
2
+
1
3
  # rails-ai-context
2
4
 
3
- ### Your AI is guessing. This gem makes it know.
5
+ **Your AI is guessing your Rails app. Every guess costs you time.**
6
+
7
+
8
+ <a href="https://claude.ai/claude-code"><img src="https://img.shields.io/badge/Claude_Code-ee8b4a?style=for-the-badge&logo=anthropic&logoColor=white" alt="Claude Code"></a>
9
+ <a href="https://cursor.com"><img src="https://img.shields.io/badge/Cursor-000000?style=for-the-badge&logo=cursor&logoColor=white" alt="Cursor"></a>
10
+ <a href="https://github.com/features/copilot"><img src="https://img.shields.io/badge/GitHub_Copilot-000000?style=for-the-badge&logo=githubcopilot&logoColor=white" alt="GitHub Copilot"></a>
11
+ <a href="https://opencode.ai"><img src="https://img.shields.io/badge/OpenCode-4285F4?style=for-the-badge&logoColor=white" alt="OpenCode"></a>
12
+ <a href="#-cli--works-everywhere"><img src="https://img.shields.io/badge/Any_Terminal-4EAA25?style=for-the-badge&logo=gnubash&logoColor=white" alt="Any Terminal"></a>
13
+
14
+
4
15
 
5
16
  [![Gem Version](https://img.shields.io/gem/v/rails-ai-context?color=brightgreen)](https://rubygems.org/gems/rails-ai-context)
6
17
  [![Downloads](https://img.shields.io/gem/dt/rails-ai-context?color=blue)](https://rubygems.org/gems/rails-ai-context)
7
18
  [![CI](https://github.com/crisnahine/rails-ai-context/actions/workflows/ci.yml/badge.svg)](https://github.com/crisnahine/rails-ai-context/actions)
8
19
  [![MCP Registry](https://img.shields.io/badge/MCP_Registry-listed-green)](https://registry.modelcontextprotocol.io)
9
- [![Ruby](https://img.shields.io/badge/Ruby-3.2%20%7C%203.3%20%7C%203.4-red)](https://github.com/crisnahine/rails-ai-context)
10
- [![Rails](https://img.shields.io/badge/Rails-7.1%20%7C%207.2%20%7C%208.0-red)](https://github.com/crisnahine/rails-ai-context)
11
- [![Tests](https://img.shields.io/badge/Tests-1170%20passing-brightgreen)](https://github.com/crisnahine/rails-ai-context/actions)
20
+ [![Ruby](https://img.shields.io/badge/Ruby-3.2%20%7C%203.3%20%7C%203.4-CC342D)](https://github.com/crisnahine/rails-ai-context)
21
+ [![Rails](https://img.shields.io/badge/Rails-7.1%20%7C%207.2%20%7C%208.0-CC0000)](https://github.com/crisnahine/rails-ai-context)
22
+ [![Tests](https://img.shields.io/badge/Tests-1529%20passing-brightgreen)](https://github.com/crisnahine/rails-ai-context/actions)
12
23
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
13
24
 
14
- **Works with:** Claude Code &bull; Cursor &bull; GitHub Copilot &bull; OpenCode &bull; Any terminal
25
+ </div>
26
+
27
+
28
+
29
+ ## The problem
15
30
 
16
- > Built by a Rails developer with 10+ years of production experience. AI assisted — the same way it assists me shipping features at work. I designed the architecture, made every decision, reviewed every line, and wrote 1170 tests. This gem exists because I understand Rails deeply enough to know exactly what AI agents get wrong and what context they need to get it right.
31
+ You've seen it. Your AI:
32
+
33
+ - **Writes a migration for a column that already exists** — didn't check the schema
34
+ - **Creates a method that duplicates one in a concern** — didn't know it was there
35
+ - **Uses the wrong association name** — `user.posts` when it's `user.articles`
36
+ - **Generates tests that don't match your patterns** — factories when you use fixtures, or the reverse
37
+ - **Adds a gem you already have** — or calls an API from one you don't
38
+ - **Reads 2,000 lines of schema.rb** to answer a question about one table
39
+ - **Misses `before_action` filters from parent controllers** — then wonders why auth fails
40
+
41
+ You catch it. You fix it. You re-prompt. It breaks something else.
42
+
43
+ **That loop is the actual cost of AI coding — not the tokens, the corrections.**
44
+
45
+ <br>
46
+
47
+ ## Two commands. Problem gone.
17
48
 
18
49
  ```bash
19
50
  gem "rails-ai-context", group: :development
20
51
  rails generate rails_ai_context:install
21
52
  ```
22
53
 
23
- That's it. Your AI now has 39 tools that understand your entire Rails app — via MCP server or CLI. Zero config.
54
+ <div align="center">
24
55
 
25
- > **[Full Guide →](docs/GUIDE.md)** — every command, every parameter, every configuration option.
56
+ ![Install demo](demo.gif)
26
57
 
27
- ---
58
+ </div>
28
59
 
29
- ## Two ways to use it
60
+ Now your AI doesn't guess it **asks your app directly.** 39 tools that query your schema, models, routes, controllers, views, and conventions on demand. It gets the right answer the first time.
30
61
 
31
- ### MCP Server — AI calls tools directly
62
+ <br>
32
63
 
33
- ```
34
- rails ai:serve
35
- ```
64
+ ## See the difference
36
65
 
37
- Your AI agent calls tools via the MCP protocol. Auto-discovered via `.mcp.json` — no manual config.
66
+ <div align="center">
38
67
 
39
- ```
40
- → rails_search_code(pattern: "can_cook?", match_type: "trace")
41
- → rails_get_schema(table: "users")
42
- → rails_analyze_feature(feature: "billing")
43
- ```
68
+ ![Trace demo](demo-trace.gif)
69
+
70
+ </div>
71
+
72
+ One call returns: definition + source code + every caller grouped by type + tests. **Replaces 4-5 sequential file reads.**
73
+
74
+ <br>
75
+
76
+ ## Measured token savings
77
+
78
+ Real numbers from a production Rails app:
79
+
80
+ | Task | Without | With | Saved |
81
+ |:-----|--------:|-----:|------:|
82
+ | Get one table's columns | 1,492 tokens | 335 tokens | **77%** |
83
+ | Trace a method across codebase | 10,556 tokens | 256 tokens | **97%** |
84
+ | Understand a model | 1,754 tokens | 588 tokens | **66%** |
85
+ | Map Stimulus controllers | 9,886 tokens | 620 tokens | **94%** |
86
+ | Routes for one controller | 373 tokens | 121 tokens | **68%** |
87
+
88
+ <details>
89
+ <summary><strong>How to reproduce these numbers yourself</strong></summary>
44
90
 
45
- ### CLI — works everywhere, no server needed
91
+ <br>
46
92
 
47
93
  ```bash
48
- rails 'ai:tool[search_code]' pattern="can_cook?" match_type=trace
49
- rails 'ai:tool[schema]' table=users
50
- rails 'ai:tool[analyze_feature]' feature=billing
51
- ```
94
+ # Schema: full file vs one table
95
+ wc -c db/schema.rb
96
+ rails 'ai:tool[schema]' table=users | wc -c
52
97
 
53
- Same 39 tools. Same output. AI agents run these as shell commands. **Works in any terminal, any AI tool, any workflow.** No MCP client required.
98
+ # Trace: all files AI reads vs one call
99
+ rails 'ai:tool[search_code]' pattern=your_method match_type=trace | wc -c
54
100
 
55
- ---
101
+ # Model: raw file + schema vs structured output
102
+ wc -c app/models/user.rb db/schema.rb
103
+ rails 'ai:tool[model_details]' model=User | wc -c
104
+ ```
56
105
 
57
- ## What AI gets wrong without this
106
+ Divide bytes by 4 for rough token count. Bigger apps save more — tool output stays focused while raw files grow.
58
107
 
59
- Your AI agent right now:
108
+ </details>
60
109
 
61
- - **Reads all 2,000 lines of schema.rb** to find one column type
62
- - **Misses encrypted columns** — doesn't know `gemini_api_key` is encrypted
63
- - **Shows 25 Devise methods** as if they're your code
64
- - **Doesn't see inherited filters** — misses `authenticate_user!` from ApplicationController
65
- - **Uses underscores in Stimulus HTML** — `data-cook_status` instead of `data-cook-status`
66
- - **Breaks Turbo Stream wiring** — broadcasts to channels nobody subscribes to
67
- - **Guesses your UI patterns** — invents new button styles instead of matching yours
110
+ <br>
68
111
 
69
- **Every wrong guess = a wasted iteration.** You fix it, re-run, it breaks something else.
112
+ ## Two ways to use it
70
113
 
71
- ---
114
+ <table>
115
+ <tr>
116
+ <td width="50%">
72
117
 
73
- ## What AI knows with this
118
+ ### MCP Server
74
119
 
75
- One call. Full picture.
120
+ AI calls tools directly via the protocol. Auto-discovered through `.mcp.json`.
76
121
 
77
122
  ```
78
- rails 'ai:tool[search_code]' pattern="can_cook?" match_type=trace
123
+ rails ai:serve
79
124
  ```
80
125
 
81
126
  ```
82
- # Trace: can_cook?
83
-
84
- ## Definition
85
- app/models/concerns/plan_limitable.rb:8
86
- def can_cook?
87
- p = effective_plan
88
- return true if p.unlimited_cooks?
89
- (cooks_this_month || 0) < p.cooks_per_month
90
- end
91
-
92
- ## Calls internally
93
- - unlimited_cooks?
94
-
95
- ## Called from (8 sites)
96
- ### app/controllers/cooks_controller.rb (Controller)
97
- 24: unless current_user.can_cook?
98
- ### app/views/cooks/new.html.erb (View)
99
- 7: <% unless current_user.can_cook? %>
100
- ### test/models/concerns/plan_limitable_test.rb (Test)
101
- 24: assert @user.can_cook?
102
- 29: assert_not @user.can_cook?
127
+ rails_search_code(pattern: "can_cook?", match_type: "trace")
128
+ → rails_get_schema(table: "users")
129
+ rails_analyze_feature(feature: "billing")
103
130
  ```
104
131
 
105
- Definition + source code + every caller grouped by type + what it calls internally. **One call replaces 6 file reads.**
132
+ </td>
133
+ <td width="50%">
106
134
 
107
- ---
135
+ ### CLI
136
+
137
+ Same 39 tools, no server needed. Works in any terminal, any AI tool.
138
+
139
+ ```bash
140
+ rails 'ai:tool[search_code]' pattern="can_cook?" match_type=trace
141
+ rails 'ai:tool[schema]' table=users
142
+ rails 'ai:tool[analyze_feature]' feature=billing
143
+ ```
144
+
145
+ </td>
146
+ </tr>
147
+ </table>
148
+
149
+ > **[Full Guide →](docs/GUIDE.md)** — every command, every parameter, every configuration option.
150
+
151
+ <br>
108
152
 
109
153
  ## Real-world examples
110
154
 
111
- ### "Add a subscription field to users"
155
+ <details>
156
+ <summary><strong>"Add a subscription field to users"</strong></summary>
157
+
158
+ <br>
112
159
 
113
160
  ```bash
114
161
  # Step 1: Check what exists
@@ -124,9 +171,14 @@ rails 'ai:tool[analyze_feature]' feature=subscription
124
171
  # → models + controllers + routes + services + jobs + views + tests in one shot
125
172
  ```
126
173
 
127
- AI now writes a correct migration, model change, and controller update on the **first attempt**.
174
+ AI writes a correct migration, model change, and controller update on the **first attempt**.
175
+
176
+ </details>
128
177
 
129
- ### "Fix the broken cook creation flow"
178
+ <details>
179
+ <summary><strong>"Fix the broken cook creation flow"</strong></summary>
180
+
181
+ <br>
130
182
 
131
183
  ```bash
132
184
  # Trace what happens
@@ -142,7 +194,12 @@ rails 'ai:tool[validate]' files=app/controllers/cooks_controller.rb level=rails
142
194
  # → syntax + semantics + Brakeman security scan
143
195
  ```
144
196
 
145
- ### "Build a new dashboard view"
197
+ </details>
198
+
199
+ <details>
200
+ <summary><strong>"Build a new dashboard view"</strong></summary>
201
+
202
+ <br>
146
203
 
147
204
  ```bash
148
205
  # Get the design system
@@ -158,78 +215,122 @@ rails 'ai:tool[stimulus]' controller=chart
158
215
  # → correct HTML with dashes (not underscores) + reverse view lookup
159
216
  ```
160
217
 
161
- ---
218
+ </details>
162
219
 
163
- ## Measured token savings
220
+ <br>
164
221
 
165
- Tested on a real Rails 8 app (5 models, 19 controllers, 95 routes):
222
+ ## 39 Tools
166
223
 
167
- | Task | Without gem | With gem | Saved |
168
- |------|-------------|----------|-------|
169
- | Trace a method across the codebase | ~9,080 tokens (read 5 files) | ~198 tokens (1 tool call) | **98%** |
170
- | Understand a feature (schema + model + controller) | ~5,200 tokens (read 3 files) | ~1,500 tokens (2 tool calls) | **71%** |
171
- | Check all table columns | ~2,573 tokens (read schema.rb) | ~908 tokens (1 tool call) | **65%** |
224
+ Every tool is **read-only** and returns structured, token-efficient context.
172
225
 
173
- > Savings scale with app size. A 50-model app reads more files per task — tool calls stay the same size.
226
+ <details>
227
+ <summary><strong>Search & Trace</strong></summary>
174
228
 
175
- ---
229
+ | Tool | What it does |
230
+ |:-----|:------------|
231
+ | `search_code` | Trace: definition + source + callers + tests. Also: definition, call, class filters |
232
+ | `get_edit_context` | Method-aware code extraction with class context |
176
233
 
177
- ## 39 Tools
234
+ </details>
235
+
236
+ <details>
237
+ <summary><strong>Understand</strong></summary>
238
+
239
+ | Tool | What it does |
240
+ |:-----|:------------|
241
+ | `analyze_feature` | Full-stack: models + controllers + routes + services + jobs + views + tests |
242
+ | `get_context` | Composite: schema + model + controller + routes + views in one call |
243
+ | `onboard` | Narrative app walkthrough (quick/standard/full) |
178
244
 
179
- Every tool is **read-only** and returns structured, token-efficient data.
180
-
181
- | Tool | MCP | CLI | What it does |
182
- |------|-----|-----|-------------|
183
- | **Search & Trace** | | | |
184
- | `search_code` | `rails_search_code(pattern:"X", match_type:"trace")` | `rails 'ai:tool[search_code]'` | Trace: definition + source + callers + test coverage. Also: definition, call, class filters |
185
- | `get_edit_context` | `rails_get_edit_context(file:"X", near:"Y")` | `rails 'ai:tool[edit_context]'` | Method-aware code extraction with class context |
186
- | **Understand** | | | |
187
- | `analyze_feature` | `rails_analyze_feature(feature:"X")` | `rails 'ai:tool[analyze_feature]'` | Full-stack: models + controllers + routes + services + jobs + views + tests |
188
- | `get_context` | `rails_get_context(model:"X")` | `rails 'ai:tool[context]'` | Composite: schema + model + controller + routes + views in one call |
189
- | **Schema & Models** | | | |
190
- | `get_schema` | `rails_get_schema(table:"X")` | `rails 'ai:tool[schema]'` | Columns with indexed/unique/encrypted/default hints |
191
- | `get_model_details` | `rails_get_model_details(model:"X")` | `rails 'ai:tool[model_details]'` | Associations, validations, scopes, enums, macros, delegations |
192
- | `get_callbacks` | `rails_get_callbacks(model:"X")` | `rails 'ai:tool[callbacks]'` | Callbacks in Rails execution order with source |
193
- | `get_concern` | `rails_get_concern(name:"X")` | `rails 'ai:tool[concern]'` | Concern methods + source + which models include it |
194
- | **Controllers & Routes** | | | |
195
- | `get_controllers` | `rails_get_controllers(controller:"X")` | `rails 'ai:tool[controllers]'` | Actions + inherited filters + render map + strong params |
196
- | `get_routes` | `rails_get_routes(controller:"X")` | `rails 'ai:tool[routes]'` | Code-ready helpers (`cook_path(@record)`) + required params |
197
- | **Views & Frontend** | | | |
198
- | `get_view` | `rails_get_view(controller:"X")` | `rails 'ai:tool[view]'` | Templates with ivars, Turbo wiring, Stimulus refs, partial locals |
199
- | `get_stimulus` | `rails_get_stimulus(controller:"X")` | `rails 'ai:tool[stimulus]'` | HTML data-attributes (dashes!) + targets + values + actions |
200
- | `get_design_system` | `rails_get_design_system` | `rails 'ai:tool[design_system]'` | Copy-paste HTML/ERB patterns for your actual components |
201
- | `get_partial_interface` | `rails_get_partial_interface(partial:"X")` | `rails 'ai:tool[partial_interface]'` | What locals to pass + what methods are called on them |
202
- | `get_turbo_map` | `rails_get_turbo_map` | `rails 'ai:tool[turbo_map]'` | Broadcast → subscription wiring + mismatch warnings |
203
- | **Testing** | | | |
204
- | `get_test_info` | `rails_get_test_info(model:"X")` | `rails 'ai:tool[test_info]'` | Fixtures + relationships + test template matching your patterns |
205
- | `validate` | `rails_validate(files:[...])` | `rails 'ai:tool[validate]'` | Syntax + semantic + Brakeman security in one call |
206
- | `security_scan` | `rails_security_scan` | `rails 'ai:tool[security_scan]'` | Brakeman static analysis — SQL injection, XSS, mass assignment |
207
- | **App Config** | | | |
208
- | `get_conventions` | `rails_get_conventions` | `rails 'ai:tool[conventions]'` | Auth checks, flash messages, create action template, test patterns |
209
- | `get_config` | `rails_get_config` | `rails 'ai:tool[config]'` | Database, auth framework, assets, cache, queue, Action Cable |
210
- | `get_gems` | `rails_get_gems` | `rails 'ai:tool[gems]'` | Notable gems with versions, categories, config file locations |
211
- | `get_env` | `rails_get_env` | `rails 'ai:tool[env]'` | Environment variables + credentials keys (not values) |
212
- | `get_helper_methods` | `rails_get_helper_methods` | `rails 'ai:tool[helper_methods]'` | App + framework helpers with view cross-references |
213
- | **Services & Jobs** | | | |
214
- | `get_service_pattern` | `rails_get_service_pattern` | `rails 'ai:tool[service_pattern]'` | Interface, dependencies, side effects, callers |
215
- | `get_job_pattern` | `rails_get_job_pattern` | `rails 'ai:tool[job_pattern]'` | Queue, retries, guard clauses, broadcasts, schedules |
216
- | **Components & Quality** | | | |
217
- | `get_component_catalog` | `rails_get_component_catalog` | `rails 'ai:tool[component_catalog]'` | ViewComponent/Phlex: props, slots, previews, sidecar assets, usage |
218
- | `performance_check` | `rails_performance_check` | `rails 'ai:tool[performance_check]'` | N+1 risks, missing indexes, counter_cache, eager load candidates |
219
- | `dependency_graph` | `rails_dependency_graph` | `rails 'ai:tool[dependency_graph]'` | Model/service dependency graph in Mermaid or text format |
220
- | `migration_advisor` | `rails_migration_advisor` | `rails 'ai:tool[migration_advisor]'` | Migration code generation with reversibility + affected models |
221
- | **Frontend** | | | |
222
- | `get_frontend_stack` | `rails_get_frontend_stack` | `rails 'ai:tool[frontend_stack]'` | React/Vue/Svelte/Angular, Inertia, TypeScript, package manager |
223
- | **Data & Debugging** | | | |
224
- | `search_docs` | `rails_search_docs(topic:"X")` | `rails 'ai:tool[search_docs]'` | Bundled topic index with weighted keyword search, on-demand GitHub fetch |
225
- | `query` | `rails_query(sql:"X")` | `rails 'ai:tool[query]'` | Safe read-only SQL queries with timeout, row limit, column redaction |
226
- | `read_logs` | `rails_read_logs(level:"X")` | `rails 'ai:tool[read_logs]'` | Reverse file tail with level filtering and sensitive data redaction |
245
+ </details>
246
+
247
+ <details>
248
+ <summary><strong>Schema & Models</strong></summary>
249
+
250
+ | Tool | What it does |
251
+ |:-----|:------------|
252
+ | `get_schema` | Columns with indexed/unique/encrypted/default hints |
253
+ | `get_model_details` | Associations, validations, scopes, enums, macros, delegations |
254
+ | `get_callbacks` | Callbacks in Rails execution order with source |
255
+ | `get_concern` | Concern methods + source + which models include it |
256
+
257
+ </details>
258
+
259
+ <details>
260
+ <summary><strong>Controllers & Routes</strong></summary>
261
+
262
+ | Tool | What it does |
263
+ |:-----|:------------|
264
+ | `get_controllers` | Actions + inherited filters + render map + strong params |
265
+ | `get_routes` | Code-ready helpers (`cook_path(@record)`) + required params |
266
+
267
+ </details>
268
+
269
+ <details>
270
+ <summary><strong>Views & Frontend</strong></summary>
271
+
272
+ | Tool | What it does |
273
+ |:-----|:------------|
274
+ | `get_view` | Templates with ivars, Turbo wiring, Stimulus refs, partial locals |
275
+ | `get_stimulus` | HTML data-attributes (dashes!) + targets + values + actions |
276
+ | `get_design_system` | Copy-paste HTML/ERB patterns for your actual components |
277
+ | `get_partial_interface` | What locals to pass + what methods are called on them |
278
+ | `get_turbo_map` | Broadcast subscription wiring + mismatch warnings |
279
+ | `get_frontend_stack` | React/Vue/Svelte/Angular, Hotwire, TypeScript, package manager |
280
+
281
+ </details>
282
+
283
+ <details>
284
+ <summary><strong>Testing & Quality</strong></summary>
285
+
286
+ | Tool | What it does |
287
+ |:-----|:------------|
288
+ | `get_test_info` | Fixtures + relationships + test template matching your patterns |
289
+ | `generate_test` | Test scaffolding matching your project's patterns |
290
+ | `validate` | Syntax + semantic + Brakeman security in one call |
291
+ | `security_scan` | Brakeman static analysis SQL injection, XSS, mass assignment |
292
+ | `performance_check` | N+1 risks, missing indexes, counter_cache, eager load candidates |
293
+
294
+ </details>
295
+
296
+ <details>
297
+ <summary><strong>App Config & Services</strong></summary>
298
+
299
+ | Tool | What it does |
300
+ |:-----|:------------|
301
+ | `get_conventions` | Auth checks, flash messages, create action template, test patterns |
302
+ | `get_config` | Database, auth framework, assets, cache, queue, Action Cable |
303
+ | `get_gems` | Notable gems with versions, categories, config file locations |
304
+ | `get_env` | Environment variables + credentials keys (not values) |
305
+ | `get_helper_methods` | App + framework helpers with view cross-references |
306
+ | `get_service_pattern` | Interface, dependencies, side effects, callers |
307
+ | `get_job_pattern` | Queue, retries, guard clauses, broadcasts, schedules |
308
+ | `get_component_catalog` | ViewComponent/Phlex: props, slots, previews, sidecar assets |
309
+
310
+ </details>
311
+
312
+ <details>
313
+ <summary><strong>Data & Debugging</strong></summary>
314
+
315
+ | Tool | What it does |
316
+ |:-----|:------------|
317
+ | `dependency_graph` | Model/service dependency graph in Mermaid or text format |
318
+ | `migration_advisor` | Migration code generation with reversibility + affected models |
319
+ | `search_docs` | Bundled topic index with weighted keyword search |
320
+ | `query` | Safe read-only SQL with timeout, row limit, column redaction |
321
+ | `read_logs` | Reverse file tail with level filtering and sensitive data redaction |
322
+ | `diagnose` | One-call error diagnosis with classification + context + git + logs |
323
+ | `review_changes` | PR/commit review with per-file context + warnings |
324
+ | `runtime_info` | Live DB pool, table sizes, pending migrations, cache stats, queue depth |
325
+ | `session_context` | Session-aware context tracking across tool calls |
326
+
327
+ </details>
227
328
 
228
329
  > **[Full parameter docs →](docs/GUIDE.md)**
229
330
 
230
- ---
331
+ <br>
231
332
 
232
- ## How It Works
333
+ ## How it works
233
334
 
234
335
  ```
235
336
  ┌─────────────────────────────────────────────────────────┐
@@ -252,119 +353,89 @@ Every tool is **read-only** and returns structured, token-efficient data.
252
353
  └──────────────────┘ └────────────┘ └────────────────────┘
253
354
  ```
254
355
 
255
- ---
356
+ <br>
256
357
 
257
358
  ## Install
258
359
 
259
360
  ```bash
260
- # Add to Gemfile
261
361
  gem "rails-ai-context", group: :development
262
-
263
- # Install — picks your AI tools, asks MCP or CLI mode, generates context
264
362
  rails generate rails_ai_context:install
265
-
266
- # Or generate context directly
267
- rails ai:context
268
363
  ```
269
364
 
270
- The install generator asks:
271
- 1. Which AI tools you use (Claude, Cursor, Copilot, OpenCode)
272
- 2. Whether you want MCP server support or CLI-only mode
273
-
274
- MCP auto-discovery: `.mcp.json` is detected automatically by Claude Code and Cursor. No manual config.
365
+ The installer asks which AI tools you use and whether you want MCP or CLI mode. That's it.
275
366
 
276
- > **[Full Guide →](docs/GUIDE.md)** every command, parameter, and configuration option.
367
+ `.mcp.json` is auto-detected by Claude Code and Cursor no manual config.
277
368
 
278
- ---
369
+ <br>
279
370
 
280
371
  ## Commands
281
372
 
282
373
  | Command | What it does |
283
- |---------|-------------|
374
+ |:--------|:------------|
284
375
  | `rails ai:context` | Generate context files for your AI tools |
285
- | `rails 'ai:tool[NAME]'` | Run any of the 39 tools from the CLI |
286
- | `rails ai:tool` | List all available tools with short names |
376
+ | `rails 'ai:tool[NAME]'` | Run any of the 39 tools from CLI |
377
+ | `rails ai:tool` | List all available tools |
287
378
  | `rails ai:serve` | Start MCP server (stdio) |
288
379
  | `rails ai:doctor` | Diagnostics + AI readiness score |
289
380
  | `rails ai:watch` | Auto-regenerate on file changes |
290
- | `rails ai:inspect` | Print introspection summary |
291
381
 
292
- ---
382
+ <br>
293
383
 
294
384
  ## Configuration
295
385
 
296
386
  ```ruby
297
387
  # config/initializers/rails_ai_context.rb
298
388
  RailsAiContext.configure do |config|
299
- # AI tools to generate context for (selected during install)
300
- # config.ai_tools = %i[claude cursor]
301
-
302
- # Tool mode: :mcp (default, MCP + CLI fallback) or :cli (CLI only)
303
- # config.tool_mode = :mcp
304
-
305
- # Presets: :full (32 introspectors, default) or :standard (14 core)
306
- # config.preset = :full
307
-
308
- # Exclude models from introspection
309
- # config.excluded_models += %w[AdminUser]
310
-
311
- # Skip specific tools
312
- # config.skip_tools = %w[rails_security_scan]
389
+ config.ai_tools = %i[claude cursor] # Which AI tools to generate for
390
+ config.tool_mode = :mcp # :mcp (default) or :cli
391
+ config.preset = :full # :full (33 introspectors) or :standard (19)
313
392
  end
314
393
  ```
315
394
 
316
395
  <details>
317
396
  <summary><strong>All configuration options</strong></summary>
318
397
 
398
+ <br>
399
+
319
400
  | Option | Default | Description |
320
- |--------|---------|-------------|
321
- | **Presets & Introspectors** | | |
322
- | `preset` | `:full` | Introspector preset (`:full` or `:standard`) |
323
- | `introspectors` | 32 (full) | Array of introspector symbols |
324
- | **Context Generation** | | |
325
- | `context_mode` | `:compact` | `:compact` (≤150 lines) or `:full` (dump everything) |
326
- | `claude_max_lines` | `150` | Max lines for CLAUDE.md in compact mode |
327
- | `generate_root_files` | `true` | Generate root files (CLAUDE.md, etc.) — set `false` for split rules only |
328
- | `ai_tools` | `nil` (all) | AI tools to generate context for: `%i[claude cursor copilot opencode]` |
329
- | `tool_mode` | `:mcp` | `:mcp` (MCP primary + CLI fallback) or `:cli` (CLI only, no MCP server) |
330
- | **MCP Server** | | |
401
+ |:-------|:--------|:------------|
402
+ | `preset` | `:full` | `:full` (33 introspectors) or `:standard` (19) |
403
+ | `context_mode` | `:compact` | `:compact` (150 lines) or `:full` |
404
+ | `generate_root_files` | `true` | Set `false` for split rules only |
331
405
  | `cache_ttl` | `60` | Cache TTL in seconds |
332
- | `max_tool_response_chars` | `200_000` | Safety cap for MCP tool responses |
333
- | `live_reload` | `:auto` | `:auto`, `true`, or `false` — MCP live reload |
334
- | `auto_mount` | `false` | Auto-mount HTTP MCP endpoint |
335
- | **File Size Limits** | | |
336
- | `max_file_size` | `5_000_000` | Per-file read limit (bytes) |
337
- | `max_search_results` | `200` | Max search results per call |
338
- | `max_validate_files` | `50` | Max files per validate call |
339
- | **Extensibility** | | |
406
+ | `max_tool_response_chars` | `200_000` | Safety cap for tool responses |
407
+ | `live_reload` | `:auto` | `:auto`, `true`, or `false` |
340
408
  | `custom_tools` | `[]` | Additional MCP tool classes |
341
- | `skip_tools` | `[]` | Built-in tool names to exclude |
409
+ | `skip_tools` | `[]` | Built-in tools to exclude |
410
+ | `excluded_models` | `[]` | Models to skip during introspection |
411
+
342
412
  </details>
343
413
 
344
- ---
414
+ <br>
345
415
 
346
416
  ## Requirements
347
417
 
348
- - Ruby >= 3.2, Rails >= 7.1
349
- - Optional: `brakeman` for security scanning, `listen` for watch mode, `ripgrep` for fast search
418
+ - **Ruby** >= 3.2 &nbsp;&nbsp; **Rails** >= 7.1
419
+ - **Optional:** `brakeman` for security scanning, `listen` for watch mode, `ripgrep` for fast search
420
+
421
+ <br>
350
422
 
351
423
  ---
352
424
 
353
- ## Contributing
425
+ <div align="center">
354
426
 
355
- ```bash
356
- git clone https://github.com/crisnahine/rails-ai-context.git
357
- cd rails-ai-context && bundle install
358
- bundle exec rspec # 983 examples
359
- bundle exec rubocop # Lint
360
- ```
427
+ ## About
428
+
429
+ Built by a Rails developer with 10+ years of production experience.<br>
430
+ 1529 tests. 39 tools. 33 introspectors. Zero config.<br>
431
+ MIT licensed. [Contributions welcome.](CONTRIBUTING.md)
361
432
 
362
- Bug reports and pull requests welcome at [github.com/crisnahine/rails-ai-context](https://github.com/crisnahine/rails-ai-context).
433
+ <br>
363
434
 
364
- ## Sponsorship
435
+ If this gem saves you time, consider [sponsoring the project](https://github.com/sponsors/crisnahine).
365
436
 
366
- If rails-ai-context saves you time, consider [becoming a sponsor](https://github.com/sponsors/crisnahine).
437
+ <br>
367
438
 
368
- ## License
439
+ [![MIT License](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
369
440
 
370
- [MIT](LICENSE)
441
+ </div>
data/demo-trace.gif ADDED
Binary file
data/demo-trace.tape ADDED
@@ -0,0 +1,21 @@
1
+ # VHS demo tape — search_code trace
2
+ Output demo-trace.gif
3
+
4
+ Set Shell zsh
5
+ Set FontSize 13
6
+ Set Width 950
7
+ Set Height 600
8
+ Set Padding 12
9
+ Set Theme "Catppuccin Mocha"
10
+ Set TypingSpeed 30ms
11
+
12
+ Type "cd /Users/crisjosephnahine/Documents/Projects/daily-content-chef"
13
+ Enter
14
+ Sleep 800ms
15
+
16
+ Type "rails 'ai:tool[search_code]' pattern=can_cook match_type=trace"
17
+ Sleep 400ms
18
+ Enter
19
+ Sleep 5s
20
+
21
+ Sleep 3s
data/demo.gif ADDED
Binary file