rails-ai-context 5.32.0 → 5.32.2
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/CHANGELOG.md +138 -0
- data/CONTEXT.md +10 -8
- data/CONTRIBUTING.md +2 -2
- data/README.md +14 -11
- data/SECURITY.md +4 -4
- data/docs/ARCHITECTURE.md +11 -10
- data/docs/CLI.md +33 -7
- data/docs/COMPATIBILITY.md +69 -32
- data/docs/CONFIGURATION.md +10 -8
- data/docs/CUSTOM_TOOLS.md +8 -8
- data/docs/FAQ.md +6 -5
- data/docs/GUIDE.md +154 -80
- data/docs/INTROSPECTORS.md +25 -17
- data/docs/QUICKSTART.md +14 -3
- data/docs/RECIPES.md +50 -40
- data/docs/SECURITY.md +23 -13
- data/docs/SETUP.md +23 -26
- data/docs/STANDALONE.md +7 -3
- data/docs/TOOLS.md +79 -45
- data/docs/TROUBLESHOOTING.md +12 -11
- data/exe/rails-ai-context +8 -4
- data/lib/generators/rails_ai_context/install/install_generator.rb +1 -1
- data/lib/rails_ai_context/configuration.rb +2 -2
- data/lib/rails_ai_context/database_yml.rb +52 -2
- data/lib/rails_ai_context/install/ai_tool.rb +11 -2
- data/lib/rails_ai_context/install/cleanup.rb +69 -23
- data/lib/rails_ai_context/install/program.rb +4 -1
- data/lib/rails_ai_context/install/selection_record.rb +20 -2
- data/lib/rails_ai_context/introspectors/listeners/schema_dsl_listener.rb +30 -9
- data/lib/rails_ai_context/introspectors/model_introspector.rb +1 -1
- data/lib/rails_ai_context/introspectors/pg_naming.rb +133 -0
- data/lib/rails_ai_context/introspectors/schema_conventions.rb +0 -6
- data/lib/rails_ai_context/introspectors/schema_introspector.rb +188 -51
- data/lib/rails_ai_context/introspectors/schema_reader.rb +98 -12
- data/lib/rails_ai_context/introspectors/structure_sql_reader.rb +56 -33
- data/lib/rails_ai_context/payload.rb +25 -2
- data/lib/rails_ai_context/serializers/opencode_rules_serializer.rb +2 -2
- data/lib/rails_ai_context/server.rb +2 -2
- data/lib/rails_ai_context/tasks/rails_ai_context.rake +12 -4
- data/lib/rails_ai_context/test_helper.rb +2 -0
- data/lib/rails_ai_context/tools/base_tool.rb +3 -1
- data/lib/rails_ai_context/tools/dependency_graph.rb +2 -2
- data/lib/rails_ai_context/tools/get_concern.rb +1 -1
- data/lib/rails_ai_context/tools/get_env.rb +1 -1
- data/lib/rails_ai_context/tools/get_gems.rb +2 -2
- data/lib/rails_ai_context/tools/get_model_details.rb +2 -0
- data/lib/rails_ai_context/tools/get_schema.rb +17 -14
- data/lib/rails_ai_context/tools/query.rb +107 -39
- data/lib/rails_ai_context/tools/search_code.rb +20 -16
- data/lib/rails_ai_context/version.rb +1 -1
- data/server.json +1 -1
- metadata +2 -1
data/docs/GUIDE.md
CHANGED
|
@@ -40,11 +40,11 @@
|
|
|
40
40
|
- [Generated Files](#generated-files)
|
|
41
41
|
- [All Commands](#all-commands)
|
|
42
42
|
- [CLI Tools](#cli-tools)
|
|
43
|
-
- [MCP Tools - Common Reference](#mcp-tools
|
|
43
|
+
- [MCP Tools - Common Reference](#mcp-tools---common-reference)
|
|
44
44
|
- [MCP Resources](#mcp-resources)
|
|
45
45
|
- [MCP Server Setup](#mcp-server-setup)
|
|
46
|
-
- [Configuration - All Options](#configuration
|
|
47
|
-
- [Introspectors - Full List](#introspectors
|
|
46
|
+
- [Configuration - All Options](#configuration---all-options)
|
|
47
|
+
- [Introspectors - Full List](#introspectors---full-list)
|
|
48
48
|
- [AI Assistant Setup](#ai-assistant-setup)
|
|
49
49
|
- [Stack Compatibility](#stack-compatibility)
|
|
50
50
|
- [Diagnostics](#diagnostics)
|
|
@@ -89,12 +89,49 @@ No Gemfile entry, no initializer, no files in your project besides config and co
|
|
|
89
89
|
|
|
90
90
|
### What the install generator does
|
|
91
91
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
92
|
+
`rails generate rails_ai_context:install` runs these steps in this order. Steps 1, 2, 3, 8 and 9 can ask a question.
|
|
93
|
+
|
|
94
|
+
1. **Asks which AI tools you use.** It prints this menu, then `Enter numbers separated by commas (e.g. 1,2) or 'a' for all:`
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
1. Claude Code -> CLAUDE.md + .claude/rules/
|
|
98
|
+
2. Cursor -> .cursor/rules/ + .cursorrules (legacy fallback)
|
|
99
|
+
3. GitHub Copilot -> .github/copilot-instructions.md + .github/instructions/
|
|
100
|
+
4. OpenCode -> AGENTS.md
|
|
101
|
+
5. Codex CLI -> AGENTS.md + .codex/config.toml
|
|
102
|
+
a. All of the above
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
There is no "none" choice. An empty answer, or one with no valid number in it, prints `No tools selected - defaulting to all.` and selects all five.
|
|
106
|
+
2. **Offers to clean up tools you dropped.** Only on a re-run, and only when the last recorded selection (the `config.ai_tools` line in the initializer, else `.rails-ai-context.yml`) has a tool you did not pick this time. It lists them and asks `Remove their generated files?` with `y` (all), `n` (keep, the default) or numbers like `1,2`. A yes removes only what the gem generated: the rule files it names inside the tool's rules directory (the directory goes too when nothing else is left in it), and the block between the `rails-ai-context` markers in a root file such as `CLAUDE.md`. A rule file you wrote by hand, your own lines around the markers, a root file with no markers and a symlink are left alone. It also keeps any file a remaining tool shares (`AGENTS.md`), and takes only the `rails-ai-context` entry out of the tool's MCP config.
|
|
107
|
+
3. **Asks what to write**, then `Enter number (default: 1):`
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
1. MCP config + context files (default)
|
|
111
|
+
2. Context files only (CLI mode, no MCP server)
|
|
112
|
+
3. MCP config only (leaves CLAUDE.md, AGENTS.md and rules untouched)
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Choices 1 and 3 set `tool_mode` to `:mcp`, choice 2 sets it to `:cli`. Choice 3 also sets `context_files` to `false`. Any other answer counts as 1.
|
|
116
|
+
4. **Writes the MCP config for each selected tool** (`.mcp.json`, `.cursor/mcp.json`, `.vscode/mcp.json`, `opencode.json`, `.codex/config.toml`). Skipped for choice 2. An existing file is merged: only the `rails-ai-context` entry is added or replaced.
|
|
117
|
+
5. **Creates or updates `config/initializers/rails_ai_context.rb`.** A new file gets your three answers as live lines (`config.ai_tools`, `config.tool_mode`, `config.context_files`) and every other option commented out at its default, wrapped in `if defined?(RailsAiContext) && RailsAiContext.respond_to?(:configure)`. In an existing file it rewrites those three lines, appends any config section the file lacks, adds the guard if it is missing, and leaves the rest alone.
|
|
118
|
+
6. **Writes `.rails-ai-context.yml`** with `ai_tools`, `tool_mode` and `context_files`. Other keys already in the file are kept.
|
|
119
|
+
7. **Adds lines to `.gitignore`**, if the file exists: `.ai-context.json` (not for choice 3) and `.codex/config.toml` (always, because it holds this machine's Ruby paths). A line that is already there is not added again.
|
|
120
|
+
8. **Asks about a pre-commit hook:** `Install a pre-commit hook that validates Rails references? (y/N)`. Only `y` installs it. The hook runs `rails 'ai:tool[validate]'` on the staged `.rb` and `.erb` files. No question is asked when the app has no `.git` directory or when the hook is already installed. When another `.git/hooks/pre-commit` exists it prints `Skipped pre-commit hook (existing hook found - add manually)` and moves on.
|
|
121
|
+
9. **Generates the context files** for the selected tools. Skipped for choice 3. If files that v5.0.0 stopped generating are still there (`.claude/rules/rails-ui-patterns.md`, `.claude/rules/rails-accessibility.md`, `.cursor/rules/rails-ui-patterns.mdc`, `.github/instructions/rails-ui-patterns.instructions.md`), it lists them first and asks `Delete them? [y/N]:`. Without a terminal, or under `--defaults`, it prints the `rm` command and does not ask.
|
|
122
|
+
10. **Prints a summary:** the files each selected tool got and the commands to run next.
|
|
123
|
+
|
|
124
|
+
Two flags change the prompts:
|
|
125
|
+
|
|
126
|
+
- `--defaults` answers every prompt with its default: all five tools, keep dropped tools' files, choice 1, no hook, keep legacy files. Piping an empty stdin does the same.
|
|
127
|
+
- `--mcp-only` skips the step 3 question and acts as choice 3. Steps 1, 2 and 8 still ask.
|
|
128
|
+
|
|
129
|
+
A team that wants no AI tool files in the repo can skip the generator. The gem needs none of its output: `rails 'ai:tool[NAME]'`, `rails ai:serve`, `rails ai:doctor` and the `rails-ai-context` binary all work on the defaults with no initializer, no `.rails-ai-context.yml` and no MCP config. `rails ai:context` is the one to leave alone in that setup, since it writes context files. To make that safe too, set `config.ai_tools = []` in an initializer: an empty list means no tool, so nothing is written and nothing is asked.
|
|
130
|
+
|
|
131
|
+
Two other entry points ask the same step 1 and step 3 questions:
|
|
132
|
+
|
|
133
|
+
- `rails-ai-context init` (standalone) asks both, then offers the step 2 and step 9 cleanups, writes `.rails-ai-context.yml`, the MCP configs and the `.gitignore` lines, and generates the context files. On an MCP-only run it skips the step 9 question, as the generator does. It never creates the initializer (in one that exists it updates `config.ai_tools`, `config.tool_mode` and `config.context_files`), never offers the pre-commit hook, and has `--mcp-only` but no `--defaults`.
|
|
134
|
+
- `rails ai:context` asks step 1 only when no tool selection is recorded, and step 3 only when no `tool_mode` is recorded. It then writes `.rails-ai-context.yml`, the MCP configs and the `.gitignore` lines before generating. It does not create the initializer or offer the hook.
|
|
98
135
|
|
|
99
136
|
---
|
|
100
137
|
|
|
@@ -123,7 +160,7 @@ rails ai:context:full
|
|
|
123
160
|
CONTEXT_MODE=full rails ai:context
|
|
124
161
|
```
|
|
125
162
|
|
|
126
|
-
- Dumps everything into
|
|
163
|
+
- Dumps everything into the root files CLAUDE.md, AGENTS.md and copilot-instructions.md (schema, all models, all routes, etc.). The split rule files and Cursor's files are the same in both modes
|
|
127
164
|
- Can produce thousands of lines for large apps
|
|
128
165
|
- **Best for:** small apps (<30 models) where the full dump fits in context
|
|
129
166
|
|
|
@@ -133,9 +170,6 @@ CONTEXT_MODE=full rails ai:context
|
|
|
133
170
|
# Full dump for Claude only, compact for everything else
|
|
134
171
|
CONTEXT_MODE=full rails ai:context:claude
|
|
135
172
|
|
|
136
|
-
# Full dump for Cursor only
|
|
137
|
-
CONTEXT_MODE=full rails ai:context:cursor
|
|
138
|
-
|
|
139
173
|
# Full dump for Copilot only
|
|
140
174
|
CONTEXT_MODE=full rails ai:context:copilot
|
|
141
175
|
```
|
|
@@ -144,7 +178,7 @@ CONTEXT_MODE=full rails ai:context:copilot
|
|
|
144
178
|
|
|
145
179
|
```ruby
|
|
146
180
|
# config/initializers/rails_ai_context.rb
|
|
147
|
-
if defined?(RailsAiContext)
|
|
181
|
+
if defined?(RailsAiContext) && RailsAiContext.respond_to?(:configure)
|
|
148
182
|
RailsAiContext.configure do |config|
|
|
149
183
|
config.context_mode = :full # or :compact (default)
|
|
150
184
|
end
|
|
@@ -229,7 +263,7 @@ unmarked file was generated with the app running.
|
|
|
229
263
|
| `rails ai:context:full` | full | all | Generate all files in full mode |
|
|
230
264
|
| `rails ai:context:claude` | compact | Claude | CLAUDE.md + .claude/rules/ |
|
|
231
265
|
| `rails ai:context:opencode` | compact | OpenCode | AGENTS.md + per-directory AGENTS.md |
|
|
232
|
-
| `rails ai:context:codex` | compact | Codex | AGENTS.md + .codex/config.toml |
|
|
266
|
+
| `rails ai:context:codex` | compact | Codex | AGENTS.md + per-directory AGENTS.md (same files as OpenCode; `.codex/config.toml` comes from the installer or `rails ai:context`) |
|
|
233
267
|
| `rails ai:context:cursor` | compact | Cursor | .cursor/rules/ |
|
|
234
268
|
| `rails ai:context:copilot` | compact | Copilot | copilot-instructions.md + .github/instructions/ |
|
|
235
269
|
| `rails ai:context:json` | - | JSON | .ai-context.json |
|
|
@@ -249,16 +283,18 @@ unmarked file was generated with the app running.
|
|
|
249
283
|
|
|
250
284
|
| Command | Transport | Description |
|
|
251
285
|
|---------|-----------|-------------|
|
|
252
|
-
| `rails ai:serve` | stdio | Start MCP server.
|
|
286
|
+
| `rails ai:serve` | stdio | Start MCP server. The generated MCP config files start the same server with `bundle exec rails-ai-context serve`. |
|
|
253
287
|
| `rails ai:serve_http` | HTTP | Start MCP server at `http://127.0.0.1:6029/mcp`. For remote clients. |
|
|
254
288
|
|
|
255
289
|
### Utilities
|
|
256
290
|
|
|
257
291
|
| Command | Description |
|
|
258
292
|
|---------|-------------|
|
|
259
|
-
| `rails ai:doctor` | Run
|
|
293
|
+
| `rails ai:doctor` | Run up to 25 diagnostic checks. Reports pass/warn/fail with fix suggestions. AI readiness score (0-100). `STRICT=1` exits 1 when a check fails. |
|
|
260
294
|
| `rails ai:watch` | Watch for file changes and auto-regenerate context files. Requires `listen` gem. |
|
|
261
295
|
| `rails ai:inspect` | Print introspection summary to stdout. Useful for debugging. |
|
|
296
|
+
| `rails ai:facts` | Print a short schema facts summary (tables, columns, indexes, associations, dependencies). |
|
|
297
|
+
| `rails 'ai:preset[NAME]'` | Run a multi-tool preset: `architecture`, `debugging` or `migration`. |
|
|
262
298
|
|
|
263
299
|
### Standalone CLI
|
|
264
300
|
|
|
@@ -275,14 +311,16 @@ rails-ai-context tool # List all available tools
|
|
|
275
311
|
rails-ai-context tool schema --table users --detail full # Run a tool
|
|
276
312
|
rails-ai-context tool schema --help # Per-tool help
|
|
277
313
|
rails-ai-context tool schema --json # JSON envelope output
|
|
278
|
-
rails-ai-context doctor # Run diagnostics
|
|
314
|
+
rails-ai-context doctor # Run diagnostics (--strict exits 1 on a failed check)
|
|
279
315
|
rails-ai-context watch # Watch for changes
|
|
280
316
|
rails-ai-context inspect # Print introspection JSON
|
|
317
|
+
rails-ai-context facts # Print schema facts summary
|
|
318
|
+
rails-ai-context preset architecture # Run a multi-tool preset
|
|
281
319
|
rails-ai-context version # Print version
|
|
282
320
|
rails-ai-context help # Show all commands
|
|
283
321
|
```
|
|
284
322
|
|
|
285
|
-
|
|
323
|
+
Run it from your Rails app root, or pass `--app-path PATH`. Booting needs `config/environment.rb`. When the app cannot boot, or with `--no-boot`, every command except `doctor` reads the source files instead.
|
|
286
324
|
|
|
287
325
|
**Config:** Standalone mode reads from `.rails-ai-context.yml` (created by `init`), and that is its only config source - the gem is not loaded while `config/initializers` runs. If no config file exists, defaults are used. With the gem in the Gemfile the two merge key by key ([Precedence](CONFIGURATION.md#precedence)).
|
|
288
326
|
|
|
@@ -345,7 +383,7 @@ Short names are resolved automatically:
|
|
|
345
383
|
The `tool_mode` config controls how tool references appear in generated context files:
|
|
346
384
|
|
|
347
385
|
```ruby
|
|
348
|
-
if defined?(RailsAiContext)
|
|
386
|
+
if defined?(RailsAiContext) && RailsAiContext.respond_to?(:configure)
|
|
349
387
|
RailsAiContext.configure do |config|
|
|
350
388
|
# :mcp (default) - MCP primary, CLI as fallback
|
|
351
389
|
# :cli - CLI only, no MCP server needed
|
|
@@ -377,7 +415,7 @@ Returns database schema: tables, columns, indexes, foreign keys.
|
|
|
377
415
|
|-------|------|-------------|
|
|
378
416
|
| `table` | string | Specific table name for full detail. Omit for listing. |
|
|
379
417
|
| `detail` | string | `summary` / `standard` (default) / `full` |
|
|
380
|
-
| `limit` | integer | Max tables to return. Default: 50 (summary),
|
|
418
|
+
| `limit` | integer | Max tables to return. Default: 50 (summary), 25 (standard), 10 (full). |
|
|
381
419
|
| `offset` | integer | Skip tables for pagination. Default: 0. |
|
|
382
420
|
| `format` | string | `markdown` (default) / `json`. JSON returns the same page of tables keyed by table name, or the single table's own data when `table` is given. |
|
|
383
421
|
|
|
@@ -385,7 +423,7 @@ Returns database schema: tables, columns, indexes, foreign keys.
|
|
|
385
423
|
|
|
386
424
|
```
|
|
387
425
|
rails_get_schema()
|
|
388
|
-
→ Standard detail, first
|
|
426
|
+
→ Standard detail, first 25 tables with column names and types
|
|
389
427
|
|
|
390
428
|
rails_get_schema(detail: "summary")
|
|
391
429
|
→ All tables with column and index counts (up to 50)
|
|
@@ -402,7 +440,7 @@ rails_get_schema(detail: "full", format: "json")
|
|
|
402
440
|
|
|
403
441
|
### rails_get_model_details
|
|
404
442
|
|
|
405
|
-
Returns model details: associations, validations, scopes, enums, callbacks, concerns. Source parsing uses Prism AST
|
|
443
|
+
Returns model details: associations, validations, scopes, enums, callbacks, concerns. Source parsing uses Prism AST. The model heading and each scope carry a confidence tag: `[VERIFIED]` (confirmed by the booted app, or static literal arguments), `[INFERRED]` (dynamic expressions) or `[STATIC]` (read from source without a boot).
|
|
406
444
|
|
|
407
445
|
**Parameters:**
|
|
408
446
|
|
|
@@ -442,7 +480,7 @@ Returns all routes: HTTP verbs, paths, controller actions, route names.
|
|
|
442
480
|
|-------|------|-------------|
|
|
443
481
|
| `controller` | string | Filter by controller name (e.g. `users`, `api/v1/posts`). Case-insensitive. |
|
|
444
482
|
| `detail` | string | `summary` / `standard` (default) / `full` |
|
|
445
|
-
| `limit` | integer | Max routes to return. Default:
|
|
483
|
+
| `limit` | integer | Max routes to return. Default: 150 (standard), 200 (full). |
|
|
446
484
|
| `offset` | integer | Skip routes for pagination. Default: 0. |
|
|
447
485
|
| `app_only` | boolean | Filter out internal Rails routes (Active Storage, Action Mailbox, Conductor, etc.). Default: true. |
|
|
448
486
|
|
|
@@ -458,8 +496,8 @@ rails_get_routes(detail: "summary")
|
|
|
458
496
|
rails_get_routes(controller: "users")
|
|
459
497
|
→ All routes for UsersController
|
|
460
498
|
|
|
461
|
-
rails_get_routes(controller: "
|
|
462
|
-
→
|
|
499
|
+
rails_get_routes(controller: "posts")
|
|
500
|
+
→ Also reaches a namespaced `api/v1/posts`: an exact name first, then the trailing path segments, never a substring
|
|
463
501
|
|
|
464
502
|
rails_get_routes(detail: "full", limit: 50)
|
|
465
503
|
→ Full table with route names, first 50 routes
|
|
@@ -537,13 +575,15 @@ Returns notable gems categorized by function.
|
|
|
537
575
|
|
|
538
576
|
| Param | Type | Description |
|
|
539
577
|
|-------|------|-------------|
|
|
540
|
-
| `category` | string | Filter by category: `auth`, `jobs`, `frontend`, `api`, `database`, `files`, `testing`, `deploy`, `all` (default). |
|
|
578
|
+
| `category` | string | Filter by category: `auth`, `jobs`, `frontend`, `api`, `database`, `files`, `testing`, `deploy`, `monitoring`, `admin`, `pagination`, `search`, `forms`, `server`, `notifications`, `validation`, `utilities`, `services`, `payments`, `all` (default). |
|
|
579
|
+
| `limit` | integer | Max gems to return. Default: 50. |
|
|
580
|
+
| `offset` | integer | Skip this many gems for pagination. Default: 0. |
|
|
541
581
|
|
|
542
582
|
**Returns:** Notable gems grouped by category with descriptions.
|
|
543
583
|
|
|
544
584
|
```
|
|
545
585
|
rails_get_gems()
|
|
546
|
-
→
|
|
586
|
+
→ Auth: devise `4.9.3`, Jobs: sidekiq `7.2.1`, ...
|
|
547
587
|
```
|
|
548
588
|
|
|
549
589
|
### rails_get_conventions
|
|
@@ -716,7 +756,7 @@ rails_search_code(pattern: "User", match_type: "class")
|
|
|
716
756
|
→ Only `class User` / `module User` definitions
|
|
717
757
|
```
|
|
718
758
|
|
|
719
|
-
**Security:** Uses `Open3.
|
|
759
|
+
**Security:** Uses `Open3.capture3` with array arguments (no shell injection). Validates file_type. Blocks path traversal. Respects `excluded_paths` and `sensitive_patterns` config on both backends, and the Ruby fallback reads the ignore files ripgrep reads and ranks them the way ripgrep does: `.rgignore` over `.ignore` over `.gitignore` (each scoped to its own directory) over `.git/info/exclude` over the global excludes file, the file type deciding before depth, which breaks ties only within one type; `.ignore` and `.rgignore` apply outside a git repository too, and a directory the rules ignore is never entered. As ripgrep does, the fallback also reads the ignore files of every directory above the app, the git ones only as far up as the nearest `.git` (a file for a worktree or submodule), so an app nested in a larger repository gets that repository's rules and a repository nested in the app stops the app's `.gitignore`. Patterns match case-sensitively, symlinks are not followed, and a file with a NUL byte in its first 64 KiB is skipped unread, all as in ripgrep, so the two return the same set.
|
|
720
760
|
|
|
721
761
|
### rails_analyze_feature
|
|
722
762
|
|
|
@@ -750,7 +790,7 @@ rails_analyze_feature(feature: "orders")
|
|
|
750
790
|
|
|
751
791
|
### rails_security_scan
|
|
752
792
|
|
|
753
|
-
Runs Brakeman static security analysis on the Rails app. Detects SQL injection, XSS, mass assignment, command injection, and other vulnerabilities.
|
|
793
|
+
Runs Brakeman static security analysis on the Rails app. Detects SQL injection, XSS, mass assignment, command injection, and other vulnerabilities. Uses the app's `brakeman` gem, or a `brakeman` gem installed for the same Ruby when the bundle has none. Returns installation instructions when neither is there.
|
|
754
794
|
|
|
755
795
|
**Parameters:**
|
|
756
796
|
|
|
@@ -785,7 +825,8 @@ Get ActiveSupport::Concern details: public methods, included modules, and which
|
|
|
785
825
|
| Param | Type | Description |
|
|
786
826
|
|-------|------|-------------|
|
|
787
827
|
| `name` | string | Concern module name (e.g. `Searchable`, `Authenticatable`). Omit to list all concerns. |
|
|
788
|
-
| `type` | string | Filter by concern type: `model`, `controller`, `all` (default). |
|
|
828
|
+
| `type` | string | Filter by concern type, the name the listing's section headings print: `model`, `controller`, `mailer`, the root a concern outside every concerns directory lives in (`service`, `lib`), `other`, or `all` (default). |
|
|
829
|
+
| `detail` | string | `summary` / `standard` (default) / `full`. Only read when `name` is given: `full` adds each method's source code, `summary` and `standard` both return method signatures. The listing is the same at every level. |
|
|
789
830
|
|
|
790
831
|
**Examples:**
|
|
791
832
|
|
|
@@ -844,6 +885,8 @@ Get Rails helper modules: method signatures, framework helpers in use, and which
|
|
|
844
885
|
|-------|------|-------------|
|
|
845
886
|
| `helper` | string | Helper module name (e.g. `ApplicationHelper`, `UsersHelper`). Omit to list all helpers. |
|
|
846
887
|
| `detail` | string | `summary` / `standard` (default) / `full`. summary: names + method counts. standard: names + method signatures. full: method signatures + view cross-references + framework helpers. |
|
|
888
|
+
| `limit` | integer | Max helpers to return. Default: 50. |
|
|
889
|
+
| `offset` | integer | Skip this many helpers for pagination. Default: 0. |
|
|
847
890
|
|
|
848
891
|
**Examples:**
|
|
849
892
|
|
|
@@ -862,7 +905,7 @@ rails_get_helper_methods(detail: "full")
|
|
|
862
905
|
|
|
863
906
|
### rails_get_service_pattern
|
|
864
907
|
|
|
865
|
-
Analyze service objects in app/services/: patterns, interfaces, dependencies, and side effects. Specify a service for full detail, or omit to detect the common pattern and list all services.
|
|
908
|
+
Analyze service objects in app/services/, app/interactions/ and app/interactors/: patterns, interfaces, dependencies, and side effects. Specify a service for full detail, or omit to detect the common pattern and list all services.
|
|
866
909
|
|
|
867
910
|
**Parameters:**
|
|
868
911
|
|
|
@@ -914,7 +957,7 @@ rails_get_job_pattern(detail: "full")
|
|
|
914
957
|
|
|
915
958
|
### rails_get_env
|
|
916
959
|
|
|
917
|
-
Discover environment variables, external service dependencies, and credentials keys used by the app. Scans
|
|
960
|
+
Discover environment variables, external service dependencies, and credentials keys used by the app. Scans .rb, .rake, ERB views and config YAML for ENV[], .env.example, Dockerfile, the env Kamal's config/deploy.yml sets (secret names; clear values, except one holding a URL or a key-like token, or under a secret-named variable, which shows as hidden, and one an ERB tag sets, which says so), config gem setting keys, Anyway::Config attributes with their env names, external HTTP calls, and credentials keys (never values).
|
|
918
961
|
|
|
919
962
|
**Parameters:**
|
|
920
963
|
|
|
@@ -1002,6 +1045,7 @@ Get cross-layer context in a single call - combines schema, model, controller, r
|
|
|
1002
1045
|
| `action` | string | Specific action name (e.g. `create`). Requires controller. Returns full action context. |
|
|
1003
1046
|
| `model` | string | Model name (e.g. `Post`). Returns schema, associations, validations, scopes, callbacks, tests. |
|
|
1004
1047
|
| `feature` | string | Feature keyword (e.g. `post`). Like analyze_feature but includes schema columns and scope bodies. |
|
|
1048
|
+
| `include` | array | Extra context to append in any mode: `stimulus`, `turbo`, `services`, `jobs`, `conventions`, `helpers`, `env`, `callbacks`. |
|
|
1005
1049
|
|
|
1006
1050
|
**Examples:**
|
|
1007
1051
|
|
|
@@ -1010,13 +1054,13 @@ rails_get_context(controller: "PostsController", action: "create")
|
|
|
1010
1054
|
→ Controller action source + model details + routes + views - everything for that action
|
|
1011
1055
|
|
|
1012
1056
|
rails_get_context(model: "User")
|
|
1013
|
-
→ Model details + schema columns +
|
|
1057
|
+
→ Model details + schema columns + the names of its tests
|
|
1014
1058
|
|
|
1015
1059
|
rails_get_context(feature: "orders")
|
|
1016
1060
|
→ Full-stack feature analysis including schema columns and scope bodies
|
|
1017
1061
|
```
|
|
1018
1062
|
|
|
1019
|
-
**Returns:** Combined context from multiple tools in a single response. For controller+action: controller source with filters, inferred model details, matching routes, and view templates. For model: model details with associations/validations/scopes, schema columns with types, and test file
|
|
1063
|
+
**Returns:** Combined context from multiple tools in a single response. For controller+action: controller source with filters, inferred model details, matching routes, and view templates. For model: model details with associations/validations/scopes, schema columns with types, and the names of the tests in its test file. For feature: delegates to full-stack feature analysis.
|
|
1020
1064
|
|
|
1021
1065
|
### Detail Level Summary
|
|
1022
1066
|
|
|
@@ -1025,10 +1069,10 @@ All tools that support `detail` use these three levels. Default limits vary by t
|
|
|
1025
1069
|
| Level | What it returns | Schema default limit | Best for |
|
|
1026
1070
|
|-------|----------------|---------------------|----------|
|
|
1027
1071
|
| `summary` | Names + counts | 50 | Getting the landscape, understanding what exists |
|
|
1028
|
-
| `standard` | Names + key details |
|
|
1072
|
+
| `standard` | Names + key details | 25 | Working context, column types, action names |
|
|
1029
1073
|
| `full` | Everything | 10 | Deep inspection, indexes, FKs, constraints |
|
|
1030
1074
|
|
|
1031
|
-
Other tools default to higher limits (e.g. models/controllers/stimulus: 50 for all levels, routes:
|
|
1075
|
+
Other tools default to higher limits (e.g. models/controllers/stimulus: 50 for all levels, routes: 150/200).
|
|
1032
1076
|
|
|
1033
1077
|
### Recommended Workflow
|
|
1034
1078
|
|
|
@@ -1067,7 +1111,7 @@ Live resources introspected fresh on every request - zero stale data:
|
|
|
1067
1111
|
| `rails-ai-context://controllers/{name}` | Controller details with actions, filters, strong params |
|
|
1068
1112
|
| `rails-ai-context://controllers/{name}/{action}` | Specific action source code and applicable filters |
|
|
1069
1113
|
| `rails-ai-context://views/{path}` | View template content (path traversal protected) |
|
|
1070
|
-
| `rails-ai-context://routes` | Live route map
|
|
1114
|
+
| `rails-ai-context://routes/{controller}` | Live route map, filtered by controller |
|
|
1071
1115
|
|
|
1072
1116
|
---
|
|
1073
1117
|
|
|
@@ -1094,7 +1138,7 @@ The install generator (or `rails-ai-context init`) creates per-tool MCP config f
|
|
|
1094
1138
|
| OpenCode | `opencode.json` | `mcp` | JSON |
|
|
1095
1139
|
| Codex CLI | `.codex/config.toml` | `[mcp_servers]` | TOML |
|
|
1096
1140
|
|
|
1097
|
-
Each file is merge-safe - only the `rails-ai-context` entry is managed, other servers are preserved.
|
|
1141
|
+
Each file is merge-safe - only the `rails-ai-context` entry is managed, other servers are preserved. When the gem is not in the app's `Gemfile.lock` (standalone install) the entry runs `rails-ai-context serve` with no `bundle exec`.
|
|
1098
1142
|
|
|
1099
1143
|
**Example: `.mcp.json` (Claude Code)**
|
|
1100
1144
|
```json
|
|
@@ -1102,7 +1146,7 @@ Each file is merge-safe - only the `rails-ai-context` entry is managed, other se
|
|
|
1102
1146
|
"mcpServers": {
|
|
1103
1147
|
"rails-ai-context": {
|
|
1104
1148
|
"command": "bundle",
|
|
1105
|
-
"args": ["exec", "rails", "
|
|
1149
|
+
"args": ["exec", "rails-ai-context", "serve"]
|
|
1106
1150
|
}
|
|
1107
1151
|
}
|
|
1108
1152
|
}
|
|
@@ -1112,7 +1156,7 @@ Each file is merge-safe - only the `rails-ai-context` entry is managed, other se
|
|
|
1112
1156
|
```toml
|
|
1113
1157
|
[mcp_servers.rails-ai-context]
|
|
1114
1158
|
command = "bundle"
|
|
1115
|
-
args = ["exec", "rails", "
|
|
1159
|
+
args = ["exec", "rails-ai-context", "serve"]
|
|
1116
1160
|
|
|
1117
1161
|
[mcp_servers.rails-ai-context.env]
|
|
1118
1162
|
PATH = "/home/user/.rbenv/shims:/usr/local/bin:/usr/bin"
|
|
@@ -1144,14 +1188,14 @@ Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS)
|
|
|
1144
1188
|
"mcpServers": {
|
|
1145
1189
|
"rails-ai-context": {
|
|
1146
1190
|
"command": "bundle",
|
|
1147
|
-
"args": ["exec", "rails", "
|
|
1191
|
+
"args": ["exec", "rails-ai-context", "serve"],
|
|
1148
1192
|
"cwd": "/path/to/your/rails/app"
|
|
1149
1193
|
}
|
|
1150
1194
|
}
|
|
1151
1195
|
}
|
|
1152
1196
|
```
|
|
1153
1197
|
|
|
1154
|
-
Or for standalone: replace `"command": "bundle"` / `"args": ["exec", "rails", "
|
|
1198
|
+
Or for standalone: replace `"command": "bundle"` / `"args": ["exec", "rails-ai-context", "serve"]` with `"command": "rails-ai-context"` / `"args": ["serve"]`.
|
|
1155
1199
|
|
|
1156
1200
|
### Cursor
|
|
1157
1201
|
|
|
@@ -1162,7 +1206,7 @@ Auto-discovered via `.cursor/mcp.json`. Or add manually in **Cursor Settings > M
|
|
|
1162
1206
|
"mcpServers": {
|
|
1163
1207
|
"rails-ai-context": {
|
|
1164
1208
|
"command": "bundle",
|
|
1165
|
-
"args": ["exec", "rails", "
|
|
1209
|
+
"args": ["exec", "rails-ai-context", "serve"],
|
|
1166
1210
|
"cwd": "/path/to/your/rails/app"
|
|
1167
1211
|
}
|
|
1168
1212
|
}
|
|
@@ -1184,7 +1228,7 @@ rails ai:serve_http
|
|
|
1184
1228
|
Or auto-mount inside your Rails app (no separate process):
|
|
1185
1229
|
|
|
1186
1230
|
```ruby
|
|
1187
|
-
if defined?(RailsAiContext)
|
|
1231
|
+
if defined?(RailsAiContext) && RailsAiContext.respond_to?(:configure)
|
|
1188
1232
|
RailsAiContext.configure do |config|
|
|
1189
1233
|
config.auto_mount = true
|
|
1190
1234
|
config.http_path = "/mcp" # default
|
|
@@ -1213,7 +1257,7 @@ This provides a native Rails controller (`RailsAiContext::McpController`) that d
|
|
|
1213
1257
|
|
|
1214
1258
|
```ruby
|
|
1215
1259
|
# config/initializers/rails_ai_context.rb
|
|
1216
|
-
if defined?(RailsAiContext)
|
|
1260
|
+
if defined?(RailsAiContext) && RailsAiContext.respond_to?(:configure)
|
|
1217
1261
|
RailsAiContext.configure do |config|
|
|
1218
1262
|
# --- Introspectors ---
|
|
1219
1263
|
|
|
@@ -1348,7 +1392,7 @@ end
|
|
|
1348
1392
|
| `tool_mode` | Symbol | `:mcp` | `:mcp` (MCP primary + CLI fallback) or `:cli` (CLI only, no MCP server needed) |
|
|
1349
1393
|
| `ai_tools` | Array | `nil` (all) | AI tools to generate context for: `%i[claude cursor copilot opencode codex]`. Selected during install. |
|
|
1350
1394
|
| `excluded_models` | Array | internal Rails models | Models to skip |
|
|
1351
|
-
| `excluded_paths` | Array | `node_modules tmp log vendor .git` | Paths excluded from code search |
|
|
1395
|
+
| `excluded_paths` | Array | `node_modules tmp log vendor .git doc docs` | Paths excluded from code search |
|
|
1352
1396
|
| `sensitive_patterns` | Array | `.env`, `.key`, `.pem`, credentials | File patterns blocked from search and read tools |
|
|
1353
1397
|
| `output_dir` | String | `nil` (Rails.root) | Where to write context files |
|
|
1354
1398
|
| `auto_mount` | Boolean | `false` | Auto-mount HTTP MCP endpoint |
|
|
@@ -1358,7 +1402,7 @@ end
|
|
|
1358
1402
|
| `live_reload` | Symbol/Boolean | `:auto` | `:auto`, `true`, or `false` - enable MCP live reload |
|
|
1359
1403
|
| `live_reload_debounce` | Float | `1.5` | Debounce interval in seconds for live reload |
|
|
1360
1404
|
| `server_name` | String | `"rails-ai-context"` | MCP server name |
|
|
1361
|
-
| `server_version` | String | gem version | MCP server version |
|
|
1405
|
+
| `server_version` | String | gem version | MCP server version. Read-only, there is no setter |
|
|
1362
1406
|
| `generate_root_files` | Boolean | `true` | Set `false` to generate split rules only: no CLAUDE.md, AGENTS.md, .cursorrules or copilot-instructions.md (`.ai-context.json` is still written) |
|
|
1363
1407
|
| `anti_hallucination_rules` | Boolean | `true` | Embed 6-rule Anti-Hallucination Protocol in generated context files - set `false` to skip |
|
|
1364
1408
|
| `hydration_enabled` | Boolean | `true` | Inject schema hints into controller/view tool responses |
|
|
@@ -1378,6 +1422,16 @@ end
|
|
|
1378
1422
|
| `excluded_middleware` | Array | standard Rails middleware | Default middleware hidden from config output |
|
|
1379
1423
|
| `search_extensions` | Array | `nil` | Narrows the Ruby fallback to these extensions. Unset, it searches every non-hidden, non-binary file, as ripgrep does |
|
|
1380
1424
|
| `concern_paths` | Array | `nil` (discovers `app/concerns` and `app/*/concerns`) | Where to look for concern source files. Setting it replaces discovery |
|
|
1425
|
+
| `context_files` | Boolean | `true` | Set `false` for an MCP-only install: no CLAUDE.md, AGENTS.md, rules files or `.ai-context.json` are written |
|
|
1426
|
+
| `frontend_paths` | Array | `nil` (auto-detected) | Frontend directories, e.g. `["app/frontend", "../web-client"]`. One outside the app root is read for manifests only |
|
|
1427
|
+
| `extra_app_paths` | Array | `[]` | More app-root-relative directories that hold Rails app code. Each one's `app/models`, `app/controllers` and `app/views` are scanned |
|
|
1428
|
+
| `query_timeout` | Integer | `5` | `rails_query` statement timeout in seconds |
|
|
1429
|
+
| `query_row_limit` | Integer | `100` | Max rows `rails_query` returns (1 to 1000) |
|
|
1430
|
+
| `query_redacted_columns` | Array | `password_digest`, `encrypted_password`, tokens, etc. | Column names whose values `rails_query` redacts |
|
|
1431
|
+
| `query_allowed_columns` | Array | `[]` | Column names to exempt from the built-in sensitive list |
|
|
1432
|
+
| `allow_query_in_production` | Boolean | `false` | Allow `rails_query` in production |
|
|
1433
|
+
| `log_lines` | Integer | `50` | Default number of lines `rails_read_logs` tails |
|
|
1434
|
+
| `instrumentation_include_arguments` | Boolean | `false` | Forward raw tool arguments in `ActiveSupport::Notifications` events |
|
|
1381
1435
|
|
|
1382
1436
|
### Root file generation
|
|
1383
1437
|
|
|
@@ -1388,14 +1442,14 @@ By default, `rails ai:context` generates root files (CLAUDE.md, AGENTS.md, etc.)
|
|
|
1388
1442
|
**Skip root files:** If you prefer to maintain root files yourself and only want split rules (`.claude/rules/`, `.cursor/rules/`, `.github/instructions/`):
|
|
1389
1443
|
|
|
1390
1444
|
```ruby
|
|
1391
|
-
if defined?(RailsAiContext)
|
|
1445
|
+
if defined?(RailsAiContext) && RailsAiContext.respond_to?(:configure)
|
|
1392
1446
|
RailsAiContext.configure do |config|
|
|
1393
1447
|
config.generate_root_files = false
|
|
1394
1448
|
end
|
|
1395
1449
|
end
|
|
1396
1450
|
```
|
|
1397
1451
|
|
|
1398
|
-
|
|
1452
|
+
The Claude Code, Cursor and Copilot rule sets each keep an app overview file (`rails-context.md`, `rails-project.mdc`, `rails-context.instructions.md`). The Claude Code one leaves out gems, architecture, services and jobs, which it expects in CLAUDE.md. OpenCode and Codex have no overview outside AGENTS.md: their split files hold only the model and controller listings.
|
|
1399
1453
|
|
|
1400
1454
|
---
|
|
1401
1455
|
|
|
@@ -1411,7 +1465,7 @@ Core Rails structure only. Use `config.preset = :standard` for a lighter footpri
|
|
|
1411
1465
|
| `models` | Associations, validations, scopes, enums, callbacks, concerns, instance methods, class methods. Source-level macros via Prism AST (single-pass, 8 listeners): `has_secure_password`, `encrypts`, `normalizes`, `delegate`, `serialize`, `store`, `generates_token_for`, `has_one_attached`, `has_many_attached`, `has_rich_text`, `broadcasts_to`. Every result tagged `[VERIFIED]` or `[INFERRED]`. |
|
|
1412
1466
|
| `routes` | All routes with HTTP verbs, paths, controller actions, route names, API namespaces, mounted engines. |
|
|
1413
1467
|
| `jobs` | ActiveJob classes with queue names. Mailers with action methods. Action Cable channels. |
|
|
1414
|
-
| `gems` |
|
|
1468
|
+
| `gems` | 127 notable gems categorized: auth, jobs, frontend, api, database, files, testing, deploy, monitoring, admin, pagination, search, forms, server, notifications, validation, utilities, services, payments. |
|
|
1415
1469
|
| `conventions` | Architecture patterns (MVC, service objects, STI, polymorphism, etc.), directory structure with file counts, config files, detected patterns. |
|
|
1416
1470
|
| `controllers` | Actions, filters (before/after/around with only/except), strong params methods, parent class, API controller detection, concerns. |
|
|
1417
1471
|
| `tests` | Test framework (rspec/minitest), factories/fixtures with locations and counts, system tests, CI config files, coverage tool, test helpers, VCR cassettes. |
|
|
@@ -1441,11 +1495,19 @@ Includes all standard introspectors plus:
|
|
|
1441
1495
|
| `action_mailbox` | Action Mailbox mailboxes with routing patterns. |
|
|
1442
1496
|
| `seeds` | db/seeds.rb analysis (Faker usage, environment conditionals), seed files in db/seeds/, models seeded. |
|
|
1443
1497
|
| `middleware` | Custom Rack middleware in app/middleware/ and lib/middleware/ with detected patterns (auth, rate limiting, tenant isolation, logging), what the app's config inserts, moves or removes, and the full middleware stack. |
|
|
1444
|
-
| `engines` | Mounted Rails engines from routes.rb with paths and descriptions for 23
|
|
1498
|
+
| `engines` | Mounted Rails engines from routes.rb with paths and descriptions for 23 known engines (Sidekiq::Web, Flipper::UI, PgHero, ActiveAdmin, etc.). |
|
|
1445
1499
|
| `env_config` | Per-environment config files (`config/environments/*.rb`): notable toggles (`force_ssl`, `eager_load`, caching, log level, queue adapter, mailer delivery) with URI credentials redacted, assigned config keys, plus the keys `config/application.rb` sets for every environment and the keys each `config_for` YAML file gives. |
|
|
1446
1500
|
| `multi_database` | Multiple databases, replicas, sharding config, model-specific `connects_to` declarations. database.yml parsing fallback. |
|
|
1447
1501
|
| `frontend_frameworks` | Frontend JS framework detection (React/Vue/Svelte/Angular), mounting strategy (Inertia/react-rails), TypeScript config, state management, package manager. |
|
|
1448
1502
|
| `database_stats` | PostgreSQL approximate row counts via `pg_stat_user_tables`. Gracefully skips on non-PostgreSQL adapters. |
|
|
1503
|
+
| `initializers` | The `Rails.application.initializers` graph (name, owner, `before:`/`after:` edges) and a per-file summary of `config/initializers/*.rb`. |
|
|
1504
|
+
| `autoload` | Zeitwerk autoloaders with collapsed and ignored dirs, `autoload_paths`, `eager_load_paths`, custom inflections. |
|
|
1505
|
+
| `connection_pool` | Per-database adapter config: pool size, `checkout_timeout`, `reaping_frequency`, `prepared_statements`, replica flag, connection-handler roles. |
|
|
1506
|
+
| `active_support` | Concerns in `app/**/concerns/`, deprecators, MessageEncryptor/Verifier usage, notification subscriptions, on-load hooks, cache store options. |
|
|
1507
|
+
| `credentials` | Encrypted credentials files (default and per-environment), where the master key comes from, top-level key names only (never values). |
|
|
1508
|
+
| `security` | `force_ssl` and SSL options, host authorization, Content Security Policy and Permissions Policy directives, CSRF config, cookie session options. |
|
|
1509
|
+
| `observability` | Log subscribers, `ActiveSupport::Notifications` subscribers, `ServerTiming` middleware, log level and tags. |
|
|
1510
|
+
| `env` | Rails-related ENV vars split into set and unset (sensitive ones are redacted), plus the app's own `ENV["X"]` references. |
|
|
1449
1511
|
|
|
1450
1512
|
### Using the standard preset
|
|
1451
1513
|
|
|
@@ -1501,7 +1563,7 @@ config.introspectors = %i[schema models routes gems auth api]
|
|
|
1501
1563
|
"mcp": {
|
|
1502
1564
|
"rails-ai-context": {
|
|
1503
1565
|
"type": "local",
|
|
1504
|
-
"command": ["bundle", "exec", "rails", "
|
|
1566
|
+
"command": ["bundle", "exec", "rails-ai-context", "serve"]
|
|
1505
1567
|
}
|
|
1506
1568
|
}
|
|
1507
1569
|
}
|
|
@@ -1563,21 +1625,21 @@ OpenCode uses **per-directory lazy-loading**: when the agent reads a file, it wa
|
|
|
1563
1625
|
| Setup | Coverage | Notes |
|
|
1564
1626
|
|-------|----------|-------|
|
|
1565
1627
|
| Rails full-stack (ERB + Hotwire) | 40/40 | All introspectors relevant |
|
|
1566
|
-
| Rails + Inertia.js (React/Vue) |
|
|
1567
|
-
| Rails API + React/Next.js SPA |
|
|
1568
|
-
| Rails API + mobile app |
|
|
1569
|
-
| Rails engine (mountable gem) |
|
|
1628
|
+
| Rails + Inertia.js (React/Vue) | Backend ones | Views/Turbo partially useful, backend fully covered |
|
|
1629
|
+
| Rails API + React/Next.js SPA | Backend ones | Schema, models, routes, API, auth, jobs - all covered |
|
|
1630
|
+
| Rails API + mobile app | Backend ones | Same as SPA - backend introspection is identical |
|
|
1631
|
+
| Rails engine (mountable gem) | Core ones | Core introspectors (schema, models, routes, gems) work |
|
|
1570
1632
|
|
|
1571
|
-
|
|
1633
|
+
All 40 introspectors run on every setup with the default `:full` preset. The gem keeps no per-setup count: frontend introspectors (views, Turbo, Stimulus, assets) degrade gracefully - they report nothing when those features aren't present.
|
|
1572
1634
|
|
|
1573
1635
|
**Tip for API-only apps:**
|
|
1574
1636
|
|
|
1575
1637
|
```ruby
|
|
1576
|
-
# Use standard preset (already
|
|
1638
|
+
# Use standard preset (it already has auth)
|
|
1577
1639
|
config.preset = :standard
|
|
1578
1640
|
|
|
1579
|
-
#
|
|
1580
|
-
config.introspectors += %i[
|
|
1641
|
+
# And add the API introspector, which standard leaves out
|
|
1642
|
+
config.introspectors += %i[api]
|
|
1581
1643
|
```
|
|
1582
1644
|
|
|
1583
1645
|
---
|
|
@@ -1588,23 +1650,35 @@ config.introspectors += %i[auth api]
|
|
|
1588
1650
|
rails ai:doctor
|
|
1589
1651
|
```
|
|
1590
1652
|
|
|
1591
|
-
Runs
|
|
1653
|
+
Runs up to 25 checks and reports an AI readiness score (0-100). A check that does not apply to the app prints no row:
|
|
1592
1654
|
|
|
1593
1655
|
| Check | What it verifies |
|
|
1594
1656
|
|-------|------------------|
|
|
1595
|
-
| Schema |
|
|
1596
|
-
|
|
|
1597
|
-
|
|
|
1598
|
-
|
|
|
1657
|
+
| Schema | A schema dump file exists |
|
|
1658
|
+
| Pending migrations | No migration is pending (fails when one is) |
|
|
1659
|
+
| Models | Model files detected |
|
|
1660
|
+
| Routes | `config/routes.rb` exists |
|
|
1661
|
+
| Gems | The lockfile exists |
|
|
1599
1662
|
| Controllers | Controller files detected |
|
|
1600
|
-
| Views |
|
|
1601
|
-
|
|
|
1602
|
-
| Tests | Test framework detected |
|
|
1663
|
+
| Views | Files exist under `app/views` |
|
|
1664
|
+
| Tests | A test suite is found |
|
|
1603
1665
|
| Migrations | Migration files exist |
|
|
1604
|
-
| Context files | Generated context files exist |
|
|
1605
|
-
|
|
|
1606
|
-
|
|
|
1666
|
+
| Context files | Generated context files exist and are newer than the code they describe. No row on an MCP-only install |
|
|
1667
|
+
| Initializer guard | Shown only when `config/initializers/rails_ai_context.rb` has no guard, or guards on `defined?(RailsAiContext)` alone |
|
|
1668
|
+
| MCP configs | Each selected tool's MCP config file exists and parses. Skipped in CLI-only mode |
|
|
1669
|
+
| Codex env snapshot | The `GEM_HOME` saved in `.codex/config.toml` still exists. Only when Codex is selected |
|
|
1670
|
+
| MCP server | MCP server can be built |
|
|
1671
|
+
| Introspector health | Every configured introspector returns data |
|
|
1672
|
+
| Preset coverage | The preset covers the features the app has |
|
|
1673
|
+
| ripgrep | `rg` binary installed (optional, falls back to Ruby) |
|
|
1674
|
+
| Prism parser | Prism is available for AST-based validation |
|
|
1675
|
+
| Brakeman | Brakeman is available for `rails_security_scan` (optional) |
|
|
1607
1676
|
| Live reload | `listen` gem installed (optional, enables MCP live reload) |
|
|
1677
|
+
| MCP stdio hygiene | On a standalone install, gem activation prints nothing on stdout |
|
|
1678
|
+
| Secrets in .gitignore | Sensitive files that exist are gitignored |
|
|
1679
|
+
| MCP auto_mount | `auto_mount` is not on in production |
|
|
1680
|
+
| Schema file size | The schema file is under 80% of `max_schema_file_size` |
|
|
1681
|
+
| View aggregation size | `app/views` templates total under 80% of `max_view_total_size` |
|
|
1608
1682
|
|
|
1609
1683
|
Each check reports **pass**, **warn**, or **fail** with fix suggestions.
|
|
1610
1684
|
|
|
@@ -1625,7 +1699,7 @@ Requires the `listen` gem:
|
|
|
1625
1699
|
gem "listen", group: :development
|
|
1626
1700
|
```
|
|
1627
1701
|
|
|
1628
|
-
Watches for changes in: `app/`, `config/`, `db/`, `lib/`, `rakelib/`, `test/`, `spec/`, and regenerates only the files that changed (diff-aware, skips unchanged files).
|
|
1702
|
+
Watches for changes in: `app/`, `config/`, `db/`, `lib/`, `rakelib/`, `test/`, `spec/`, plus the app directories of packs, in-repo engines and `extra_app_paths`, and regenerates only the files that changed (diff-aware, skips unchanged files).
|
|
1629
1703
|
|
|
1630
1704
|
---
|
|
1631
1705
|
|
|
@@ -1635,12 +1709,12 @@ When running the MCP server via `rails ai:serve`, **live reload** automatically
|
|
|
1635
1709
|
|
|
1636
1710
|
### How it works
|
|
1637
1711
|
|
|
1638
|
-
1. A background thread watches `app/`, `config/`, `db/`, `lib/`, `rakelib/`, `test/` and `spec/` for changes
|
|
1712
|
+
1. A background thread watches `app/`, `config/`, `db/`, `lib/`, `rakelib/`, `test/` and `spec/` (plus the app directories of packs, in-repo engines and `extra_app_paths`) for changes
|
|
1639
1713
|
2. On change (debounced 1.5s), it checks the file fingerprint to avoid false positives
|
|
1640
1714
|
3. If files truly changed, it:
|
|
1641
1715
|
- Clears all MCP tool caches
|
|
1642
1716
|
- Sends `notifications/resources/list_changed` to the AI client
|
|
1643
|
-
- Logs a summary of what changed (e.g., "Files changed: 2
|
|
1717
|
+
- Logs a summary of what changed (e.g., "Files changed: 2 models, 1 controller.")
|
|
1644
1718
|
|
|
1645
1719
|
### Setup
|
|
1646
1720
|
|
|
@@ -1656,9 +1730,9 @@ Live reload is **enabled by default** when the `listen` gem is available. No con
|
|
|
1656
1730
|
### Configuration
|
|
1657
1731
|
|
|
1658
1732
|
```ruby
|
|
1659
|
-
if defined?(RailsAiContext)
|
|
1733
|
+
if defined?(RailsAiContext) && RailsAiContext.respond_to?(:configure)
|
|
1660
1734
|
RailsAiContext.configure do |config|
|
|
1661
|
-
# :auto (default) - enable if `listen` gem is available, skip
|
|
1735
|
+
# :auto (default) - enable if `listen` gem is available, otherwise skip with one line on stderr
|
|
1662
1736
|
# true - enable, raise if `listen` gem is missing
|
|
1663
1737
|
# false - disable entirely
|
|
1664
1738
|
config.live_reload = :auto
|
|
@@ -1696,12 +1770,12 @@ Works in:
|
|
|
1696
1770
|
## Security
|
|
1697
1771
|
|
|
1698
1772
|
- All MCP tools are **read-only** - they never modify your application or database
|
|
1699
|
-
- Code search uses `Open3.
|
|
1773
|
+
- Code search uses `Open3.capture3` with array arguments - **no shell injection**
|
|
1700
1774
|
- File paths are validated against **path traversal** attacks
|
|
1701
1775
|
- Credentials and secret values are **never exposed** - only key names are introspected
|
|
1702
1776
|
- The gem makes **no outbound network requests**
|
|
1703
1777
|
- File type validation prevents arbitrary file access in code search
|
|
1704
|
-
-
|
|
1778
|
+
- Search output is capped at `max_search_results` lines (default 200) to prevent resource exhaustion
|
|
1705
1779
|
|
|
1706
1780
|
---
|
|
1707
1781
|
|
|
@@ -1735,7 +1809,7 @@ config.max_tool_response_chars = 60_000
|
|
|
1735
1809
|
|
|
1736
1810
|
### Models not detected
|
|
1737
1811
|
|
|
1738
|
-
- Models must
|
|
1812
|
+
- Models must descend from `ActiveRecord::Base`, through `ApplicationRecord` or any other base class. Without a boot they must also sit in a model directory (`app/models/`, or a pack's or engine's)
|
|
1739
1813
|
- Excluded models: `ApplicationRecord`, `ActiveStorage::*`, `ActionText::*`, `ActionMailbox::*`
|
|
1740
1814
|
- Add custom exclusions: `config.excluded_models += %w[InternalModel]`
|
|
1741
1815
|
|