rails-ai-context 0.15.4 → 0.15.6
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 +29 -0
- data/README.md +28 -5
- data/SECURITY.md +1 -1
- data/docs/GUIDE.md +211 -16
- data/lib/rails_ai_context/configuration.rb +55 -0
- data/lib/rails_ai_context/introspectors/controller_introspector.rb +4 -7
- data/lib/rails_ai_context/introspectors/model_introspector.rb +13 -4
- data/lib/rails_ai_context/introspectors/schema_introspector.rb +5 -3
- data/lib/rails_ai_context/introspectors/view_template_introspector.rb +4 -5
- data/lib/rails_ai_context/tools/get_config.rb +2 -16
- data/lib/rails_ai_context/tools/get_controllers.rb +11 -7
- data/lib/rails_ai_context/tools/get_edit_context.rb +9 -2
- data/lib/rails_ai_context/tools/get_gems.rb +3 -1
- data/lib/rails_ai_context/tools/get_model_details.rb +58 -8
- data/lib/rails_ai_context/tools/get_routes.rb +15 -18
- data/lib/rails_ai_context/tools/get_schema.rb +6 -9
- data/lib/rails_ai_context/tools/get_test_info.rb +16 -5
- data/lib/rails_ai_context/tools/get_view.rb +35 -4
- data/lib/rails_ai_context/tools/search_code.rb +20 -4
- data/lib/rails_ai_context/tools/validate.rb +36 -15
- data/lib/rails_ai_context/version.rb +1 -1
- data/server.json +2 -2
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0eb46f9da0fc24418021dbb2ca4a6850017ab555ac0bbe98b589777ef30593a2
|
|
4
|
+
data.tar.gz: 5b77c8e0b1c7832c17ea84fffdc96524060fc594e4691f11a84b5e010158f925
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 13a6f6e8e274cf47210b6cb94f160ba00e4cebe3349eb6c1e2612b4ec53561ab87d99690c9949c4eae389427bf7e80850b1c5a930283792bfa3294010303ec04
|
|
7
|
+
data.tar.gz: 5ae9e78447e0ec33496b608729be0088bf57f180a37f27690f7eaa0b6ca0a3c1a6637887a747d3de67bec808636a139be88e2b9ba72e71db0e07faa156541182
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,35 @@ 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.15.6] - 2026-03-22
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **7 new configurable options** — `excluded_controllers`, `excluded_route_prefixes`, `excluded_concerns`, `excluded_filters`, `excluded_middleware`, `search_extensions`, `concern_paths` for stack-specific customization.
|
|
13
|
+
- **Configurable file size limits** — `max_file_size`, `max_test_file_size`, `max_schema_file_size`, `max_view_total_size`, `max_view_file_size`, `max_search_results`, `max_validate_files` all exposed via `Configuration`.
|
|
14
|
+
- **Class methods in model detail** — `rails_get_model_details` now shows class methods section.
|
|
15
|
+
- **Custom validate methods** — `validate :method_name` calls extracted from source and shown in model detail.
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- **Schema defaults always visible** — Null and Default columns always shown (NOT NULL marked bold). Previous token-saving logic accidentally hid critical migration data.
|
|
20
|
+
- **Optional associations** — `belongs_to` with `optional: true` now shows `[optional]` flag.
|
|
21
|
+
- **Concern methods inline** — shows public methods from concern source files (e.g. `PlanLimitable — can_cook?, increment_cook_count!`).
|
|
22
|
+
- **MCP tool error messages** — all tools now show available values on error/not-found for AI self-correction.
|
|
23
|
+
|
|
24
|
+
## [0.15.5] - 2026-03-22
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
|
|
28
|
+
- **ERB validation** — now catches missing `<% end %>` by compiling ERB to Ruby then syntax-checking the result (was only checking ERB tag syntax).
|
|
29
|
+
- **Controller namespace format** — accepts both `Bonus::CrisesController` and `bonus/crises` (cross-tool consistency).
|
|
30
|
+
- **Layouts discoverable** — `controller:"layouts"` now works in view tool.
|
|
31
|
+
- **Validate error detail** — Ruby shows up to 5 error lines, JS shows 3 (was truncated to 1).
|
|
32
|
+
- **Invalid/empty regex** — early validation with clear error messages instead of silent fail.
|
|
33
|
+
- **Route count accuracy** — shows filtered count when `app_only:true`, not unfiltered total.
|
|
34
|
+
- **Namespace test lookup** — supports `bonus/crises` format and flat test directories.
|
|
35
|
+
- **Empty inputs** — `near:""` in edit_context and `pattern:""` in search return helpful errors.
|
|
36
|
+
|
|
8
37
|
## [0.15.4] - 2026-03-22
|
|
9
38
|
|
|
10
39
|
### Fixed
|
data/README.md
CHANGED
|
@@ -295,22 +295,45 @@ end
|
|
|
295
295
|
|
|
296
296
|
| Option | Default | Description |
|
|
297
297
|
|--------|---------|-------------|
|
|
298
|
+
| **Presets & Introspectors** | | |
|
|
298
299
|
| `preset` | `:standard` | Introspector preset (`:standard` or `:full`) |
|
|
299
300
|
| `introspectors` | 13 core | Array of introspector symbols |
|
|
301
|
+
| **Context Generation** | | |
|
|
300
302
|
| `context_mode` | `:compact` | `:compact` (≤150 lines) or `:full` (dump everything) |
|
|
301
303
|
| `claude_max_lines` | `150` | Max lines for CLAUDE.md in compact mode |
|
|
302
|
-
| `
|
|
303
|
-
| `
|
|
304
|
-
|
|
|
305
|
-
| `
|
|
304
|
+
| `generate_root_files` | `true` | Generate root files (CLAUDE.md, etc.) — set `false` for split rules only |
|
|
305
|
+
| `output_dir` | `Rails.root` | Output directory for generated context files |
|
|
306
|
+
| **MCP Server** | | |
|
|
307
|
+
| `server_name` | `"rails-ai-context"` | MCP server name |
|
|
308
|
+
| `server_version` | gem version | MCP server version |
|
|
306
309
|
| `auto_mount` | `false` | Auto-mount HTTP MCP endpoint |
|
|
307
310
|
| `http_path` | `"/mcp"` | HTTP endpoint path |
|
|
308
311
|
| `http_port` | `6029` | HTTP server port |
|
|
309
312
|
| `http_bind` | `"127.0.0.1"` | HTTP server bind address |
|
|
310
313
|
| `cache_ttl` | `30` | Cache TTL in seconds |
|
|
314
|
+
| `max_tool_response_chars` | `120_000` | Safety cap for MCP tool responses |
|
|
311
315
|
| `live_reload` | `:auto` | `:auto`, `true`, or `false` — MCP live reload |
|
|
312
316
|
| `live_reload_debounce` | `1.5` | Debounce interval in seconds |
|
|
313
|
-
|
|
|
317
|
+
| **Filtering & Exclusions** | | |
|
|
318
|
+
| `excluded_models` | internal Rails models | Models to skip during introspection |
|
|
319
|
+
| `excluded_paths` | `node_modules tmp log vendor .git` | Paths excluded from code search |
|
|
320
|
+
| `sensitive_patterns` | `.env .env.* config/master.key config/credentials.yml.enc config/credentials/*.yml.enc *.pem *.key` | File patterns blocked from search and read tools |
|
|
321
|
+
| `excluded_controllers` | `DeviseController` etc. | Controller classes hidden from listings |
|
|
322
|
+
| `excluded_route_prefixes` | `action_mailbox/ active_storage/ rails/` etc. | Route controller prefixes hidden with app_only |
|
|
323
|
+
| `excluded_concerns` | Rails/Devise/framework patterns | Regex patterns for concerns to hide |
|
|
324
|
+
| `excluded_filters` | `verify_authenticity_token` etc. | Framework filter names hidden from controller output |
|
|
325
|
+
| `excluded_middleware` | standard Rack/Rails middleware | Default middleware hidden from config output |
|
|
326
|
+
| **File Size Limits** | | |
|
|
327
|
+
| `max_file_size` | `2_000_000` | Per-file read limit for tools (bytes) |
|
|
328
|
+
| `max_test_file_size` | `500_000` | Test file read limit (bytes) |
|
|
329
|
+
| `max_schema_file_size` | `10_000_000` | schema.rb / structure.sql parse limit (bytes) |
|
|
330
|
+
| `max_view_total_size` | `5_000_000` | Total aggregated view content for UI patterns (bytes) |
|
|
331
|
+
| `max_view_file_size` | `500_000` | Per-view file during aggregation (bytes) |
|
|
332
|
+
| `max_search_results` | `100` | Max search results per call |
|
|
333
|
+
| `max_validate_files` | `20` | Max files per validate call |
|
|
334
|
+
| **Search & Discovery** | | |
|
|
335
|
+
| `search_extensions` | `rb js erb yml yaml json ts tsx vue svelte haml slim` | File extensions for Ruby fallback search |
|
|
336
|
+
| `concern_paths` | `app/models/concerns app/controllers/concerns` | Where to look for concern source files |
|
|
314
337
|
</details>
|
|
315
338
|
|
|
316
339
|
---
|
data/SECURITY.md
CHANGED
data/docs/GUIDE.md
CHANGED
|
@@ -146,22 +146,23 @@ end
|
|
|
146
146
|
| `app/models/AGENTS.md` | Model reference | Auto-loaded by OpenCode when reading files in `app/models/`. |
|
|
147
147
|
| `app/controllers/AGENTS.md` | Controller reference | Auto-loaded by OpenCode when reading files in `app/controllers/`. |
|
|
148
148
|
|
|
149
|
-
### Cursor (
|
|
149
|
+
### Cursor (5 files)
|
|
150
150
|
|
|
151
151
|
| File | Purpose | Notes |
|
|
152
152
|
|------|---------|-------|
|
|
153
153
|
| `.cursor/rules/rails-project.mdc` | Project overview | `alwaysApply: true` — loaded in every conversation. |
|
|
154
154
|
| `.cursor/rules/rails-models.mdc` | Model reference | `globs: app/models/**/*.rb` — auto-attaches when editing models. |
|
|
155
155
|
| `.cursor/rules/rails-controllers.mdc` | Controller reference | `globs: app/controllers/**/*.rb` — auto-attaches when editing controllers. |
|
|
156
|
-
| `.cursor/rules/rails-ui-patterns.mdc` | UI patterns and design tokens | `
|
|
156
|
+
| `.cursor/rules/rails-ui-patterns.mdc` | UI patterns and design tokens | `globs: app/views/**/*.erb` — loaded when editing views. |
|
|
157
157
|
| `.cursor/rules/rails-mcp-tools.mdc` | MCP tool reference | `alwaysApply: true` — always available. |
|
|
158
158
|
|
|
159
|
-
### Windsurf (
|
|
159
|
+
### Windsurf (4 files)
|
|
160
160
|
|
|
161
161
|
| File | Purpose | Notes |
|
|
162
162
|
|------|---------|-------|
|
|
163
163
|
| `.windsurfrules` | Main context file | Hard-capped at 5,800 chars (Windsurf's 6K limit). Truncated silently if exceeded. |
|
|
164
164
|
| `.windsurf/rules/rails-context.md` | Project overview | New Windsurf rules format. |
|
|
165
|
+
| `.windsurf/rules/rails-ui-patterns.md` | UI patterns and design tokens | Loaded when editing views. |
|
|
165
166
|
| `.windsurf/rules/rails-mcp-tools.md` | MCP tool reference | Compact — respects 6K per-file limit. |
|
|
166
167
|
|
|
167
168
|
### GitHub Copilot (6 files)
|
|
@@ -172,7 +173,7 @@ end
|
|
|
172
173
|
| `.github/instructions/rails-models.instructions.md` | Model context | `applyTo: app/models/**/*.rb` — loaded when editing models. |
|
|
173
174
|
| `.github/instructions/rails-controllers.instructions.md` | Controller context | `applyTo: app/controllers/**/*.rb` — loaded when editing controllers. |
|
|
174
175
|
| `.github/instructions/rails-context.instructions.md` | Project context and conventions | `applyTo: **/*` — loaded everywhere. |
|
|
175
|
-
| `.github/instructions/rails-ui-patterns.instructions.md` | UI patterns and design tokens | `applyTo:
|
|
176
|
+
| `.github/instructions/rails-ui-patterns.instructions.md` | UI patterns and design tokens | `applyTo: app/views/**/*.erb` — loaded when editing views. |
|
|
176
177
|
| `.github/instructions/rails-mcp-tools.instructions.md` | MCP tool reference | `applyTo: **/*` — loaded everywhere. |
|
|
177
178
|
|
|
178
179
|
### Generic (1 file)
|
|
@@ -296,6 +297,8 @@ Returns model details: associations, validations, scopes, enums, callbacks, conc
|
|
|
296
297
|
|-------|------|-------------|
|
|
297
298
|
| `model` | string | Model class name (e.g. `User`). Case-insensitive. Omit for listing. |
|
|
298
299
|
| `detail` | string | `summary` / `standard` (default) / `full`. Ignored when model is specified. |
|
|
300
|
+
| `limit` | integer | Max models to return when listing. Default: 50. |
|
|
301
|
+
| `offset` | integer | Skip models for pagination. Default: 0. |
|
|
299
302
|
|
|
300
303
|
**Examples:**
|
|
301
304
|
|
|
@@ -328,6 +331,7 @@ Returns all routes: HTTP verbs, paths, controller actions, route names.
|
|
|
328
331
|
| `detail` | string | `summary` / `standard` (default) / `full` |
|
|
329
332
|
| `limit` | integer | Max routes to return. Default: 100 (standard), 200 (full). |
|
|
330
333
|
| `offset` | integer | Skip routes for pagination. Default: 0. |
|
|
334
|
+
| `app_only` | boolean | Filter out internal Rails routes (Active Storage, Action Mailbox, Conductor, etc.). Default: true. |
|
|
331
335
|
|
|
332
336
|
**Examples:**
|
|
333
337
|
|
|
@@ -359,8 +363,11 @@ Returns controller details: actions, filters, strong params, concerns.
|
|
|
359
363
|
|
|
360
364
|
| Param | Type | Description |
|
|
361
365
|
|-------|------|-------------|
|
|
362
|
-
| `controller` | string | Specific controller name (e.g. `UsersController`). Case-insensitive. |
|
|
366
|
+
| `controller` | string | Specific controller name (e.g. `UsersController`, `cooks`, `bonus/crises`). Case-insensitive, flexible format. |
|
|
367
|
+
| `action` | string | Specific action (e.g. `index`). Requires controller. Returns source code with applicable filters. |
|
|
363
368
|
| `detail` | string | `summary` / `standard` (default) / `full`. Ignored when controller is specified. |
|
|
369
|
+
| `limit` | integer | Max controllers to return when listing. Default: 50. |
|
|
370
|
+
| `offset` | integer | Skip this many controllers for pagination. Default: 0. |
|
|
364
371
|
|
|
365
372
|
**Examples:**
|
|
366
373
|
|
|
@@ -382,7 +389,7 @@ rails_get_controllers(detail: "full")
|
|
|
382
389
|
|
|
383
390
|
Returns application configuration. No parameters.
|
|
384
391
|
|
|
385
|
-
**Returns:** cache store, session store, timezone,
|
|
392
|
+
**Returns:** cache store, session store, timezone, queue adapter, mailer settings, custom middleware (framework defaults are filtered out), notable initializers, CurrentAttributes classes.
|
|
386
393
|
|
|
387
394
|
```
|
|
388
395
|
rails_get_config()
|
|
@@ -391,20 +398,35 @@ rails_get_config()
|
|
|
391
398
|
|
|
392
399
|
### rails_get_test_info
|
|
393
400
|
|
|
394
|
-
Returns test infrastructure details.
|
|
401
|
+
Returns test infrastructure details. Optionally filter by model or controller to find existing tests.
|
|
395
402
|
|
|
396
|
-
**
|
|
403
|
+
**Parameters:**
|
|
404
|
+
|
|
405
|
+
| Param | Type | Description |
|
|
406
|
+
|-------|------|-------------|
|
|
407
|
+
| `model` | string | Show tests for a specific model (e.g. `User`). |
|
|
408
|
+
| `controller` | string | Show tests for a specific controller (e.g. `Cooks`). |
|
|
409
|
+
| `detail` | string | `summary` / `standard` (default) / `full`. |
|
|
397
410
|
|
|
398
411
|
```
|
|
399
412
|
rails_get_test_info()
|
|
400
|
-
→ Framework: rspec, Factories: spec/factories (12 files), CI: .github/workflows/ci.yml
|
|
413
|
+
→ Framework: rspec, Factories: spec/factories (12 files), CI: .github/workflows/ci.yml
|
|
414
|
+
|
|
415
|
+
rails_get_test_info(model: "User")
|
|
416
|
+
→ Shows spec/models/user_spec.rb test names (summary/standard) or full source (full)
|
|
401
417
|
```
|
|
402
418
|
|
|
403
419
|
### rails_get_gems
|
|
404
420
|
|
|
405
|
-
Returns notable gems categorized by function.
|
|
421
|
+
Returns notable gems categorized by function.
|
|
406
422
|
|
|
407
|
-
**
|
|
423
|
+
**Parameters:**
|
|
424
|
+
|
|
425
|
+
| Param | Type | Description |
|
|
426
|
+
|-------|------|-------------|
|
|
427
|
+
| `category` | string | Filter by category: `auth`, `jobs`, `frontend`, `api`, `database`, `files`, `testing`, `deploy`, `all` (default). |
|
|
428
|
+
|
|
429
|
+
**Returns:** Notable gems grouped by category with descriptions.
|
|
408
430
|
|
|
409
431
|
```
|
|
410
432
|
rails_get_gems()
|
|
@@ -422,6 +444,108 @@ rails_get_conventions()
|
|
|
422
444
|
→ Architecture: [MVC, Service objects, Concerns], Patterns: [STI, Polymorphism], ...
|
|
423
445
|
```
|
|
424
446
|
|
|
447
|
+
### rails_get_stimulus
|
|
448
|
+
|
|
449
|
+
Returns Stimulus controller details: targets, values, actions, outlets, classes.
|
|
450
|
+
|
|
451
|
+
**Parameters:**
|
|
452
|
+
|
|
453
|
+
| Param | Type | Description |
|
|
454
|
+
|-------|------|-------------|
|
|
455
|
+
| `controller` | string | Specific Stimulus controller name (e.g. `hello`, `filter-form`). Case-insensitive. |
|
|
456
|
+
| `detail` | string | `summary` / `standard` (default) / `full` |
|
|
457
|
+
| `limit` | integer | Max controllers to return when listing. Default: 50. |
|
|
458
|
+
| `offset` | integer | Skip controllers for pagination. Default: 0. |
|
|
459
|
+
|
|
460
|
+
**Examples:**
|
|
461
|
+
|
|
462
|
+
```
|
|
463
|
+
rails_get_stimulus()
|
|
464
|
+
→ Standard: controller names with targets and actions
|
|
465
|
+
|
|
466
|
+
rails_get_stimulus(detail: "summary")
|
|
467
|
+
→ Names with target/action counts
|
|
468
|
+
|
|
469
|
+
rails_get_stimulus(controller: "filter-form")
|
|
470
|
+
→ Full detail: targets, actions, values, outlets, classes, file path
|
|
471
|
+
|
|
472
|
+
rails_get_stimulus(detail: "full")
|
|
473
|
+
→ All controllers with all details
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
### rails_get_view
|
|
477
|
+
|
|
478
|
+
Returns view template contents, partials, and Stimulus controller references.
|
|
479
|
+
|
|
480
|
+
**Parameters:**
|
|
481
|
+
|
|
482
|
+
| Param | Type | Description |
|
|
483
|
+
|-------|------|-------------|
|
|
484
|
+
| `controller` | string | Filter views by controller name (e.g. `cooks`, `brand_profiles`). Use `layouts` for layout files. |
|
|
485
|
+
| `path` | string | Specific view path relative to `app/views` (e.g. `cooks/index.html.erb`). Returns full content. |
|
|
486
|
+
| `detail` | string | `summary` / `standard` (default) / `full` |
|
|
487
|
+
|
|
488
|
+
**Examples:**
|
|
489
|
+
|
|
490
|
+
```
|
|
491
|
+
rails_get_view()
|
|
492
|
+
→ Standard: all view files with partial/stimulus refs
|
|
493
|
+
|
|
494
|
+
rails_get_view(controller: "cooks")
|
|
495
|
+
→ All templates and partials for CooksController
|
|
496
|
+
|
|
497
|
+
rails_get_view(path: "cooks/index.html.erb")
|
|
498
|
+
→ Full template content
|
|
499
|
+
|
|
500
|
+
rails_get_view(controller: "layouts")
|
|
501
|
+
→ Layout files
|
|
502
|
+
|
|
503
|
+
rails_get_view(controller: "cooks", detail: "full")
|
|
504
|
+
→ Full template content for all cooks views
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
### rails_get_edit_context
|
|
508
|
+
|
|
509
|
+
Returns just enough context to make a surgical Edit to a file. Returns the target area with line numbers and surrounding code.
|
|
510
|
+
|
|
511
|
+
**Parameters:**
|
|
512
|
+
|
|
513
|
+
| Param | Type | Description |
|
|
514
|
+
|-------|------|-------------|
|
|
515
|
+
| `file` | string | **Required.** File path relative to Rails root (e.g. `app/models/cook.rb`). |
|
|
516
|
+
| `near` | string | **Required.** What to find — a method name, keyword, or string to locate (e.g. `scope`, `def index`). |
|
|
517
|
+
| `context_lines` | integer | Lines of context above and below the match. Default: 5. |
|
|
518
|
+
|
|
519
|
+
**Examples:**
|
|
520
|
+
|
|
521
|
+
```
|
|
522
|
+
rails_get_edit_context(file: "app/models/cook.rb", near: "scope")
|
|
523
|
+
→ Code around the first scope with line numbers, expanded to full method
|
|
524
|
+
|
|
525
|
+
rails_get_edit_context(file: "app/controllers/cooks_controller.rb", near: "def index")
|
|
526
|
+
→ The index action source with surrounding context
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
### rails_validate
|
|
530
|
+
|
|
531
|
+
Validates syntax of multiple files at once (Ruby, ERB, JavaScript).
|
|
532
|
+
|
|
533
|
+
**Parameters:**
|
|
534
|
+
|
|
535
|
+
| Param | Type | Description |
|
|
536
|
+
|-------|------|-------------|
|
|
537
|
+
| `files` | array | **Required.** File paths relative to Rails root (e.g. `["app/models/cook.rb", "app/views/cooks/index.html.erb"]`). |
|
|
538
|
+
|
|
539
|
+
**Examples:**
|
|
540
|
+
|
|
541
|
+
```
|
|
542
|
+
rails_validate(files: ["app/models/cook.rb"])
|
|
543
|
+
→ ✓ app/models/cook.rb — syntax OK
|
|
544
|
+
|
|
545
|
+
rails_validate(files: ["app/models/cook.rb", "app/controllers/cooks_controller.rb", "app/views/cooks/index.html.erb"])
|
|
546
|
+
→ Checks all three files, reports pass/fail for each
|
|
547
|
+
```
|
|
548
|
+
|
|
425
549
|
### rails_search_code
|
|
426
550
|
|
|
427
551
|
Ripgrep-powered regex search across the codebase.
|
|
@@ -431,8 +555,10 @@ Ripgrep-powered regex search across the codebase.
|
|
|
431
555
|
| Param | Type | Description |
|
|
432
556
|
|-------|------|-------------|
|
|
433
557
|
| `pattern` | string | **Required.** Regex pattern to search for. |
|
|
558
|
+
| `path` | string | Subdirectory to search in (e.g. `app/models`, `config`). Default: entire app. |
|
|
434
559
|
| `file_type` | string | Filter by file type (e.g. `rb`, `erb`, `js`). Alphanumeric only. |
|
|
435
|
-
| `max_results` | integer | Max results to return. Default:
|
|
560
|
+
| `max_results` | integer | Max results to return. Default: 30, max: 100. |
|
|
561
|
+
| `context_lines` | integer | Lines of context before and after each match (like grep -C). Default: 0, max: 5. |
|
|
436
562
|
|
|
437
563
|
**Examples:**
|
|
438
564
|
|
|
@@ -445,18 +571,28 @@ rails_search_code(pattern: "class.*Controller", file_type: "rb")
|
|
|
445
571
|
|
|
446
572
|
rails_search_code(pattern: "def create", file_type: "rb", max_results: 50)
|
|
447
573
|
→ First 50 create methods across the codebase
|
|
574
|
+
|
|
575
|
+
rails_search_code(pattern: "current_user", path: "app/controllers")
|
|
576
|
+
→ Search only in app/controllers/
|
|
577
|
+
|
|
578
|
+
rails_search_code(pattern: "validates", context_lines: 2)
|
|
579
|
+
→ Matches with 2 lines of context before and after
|
|
448
580
|
```
|
|
449
581
|
|
|
450
|
-
**Security:** Uses `Open3.capture2` with array arguments (no shell injection). Validates file_type. Blocks path traversal. Respects `excluded_paths` config.
|
|
582
|
+
**Security:** Uses `Open3.capture2` with array arguments (no shell injection). Validates file_type. Blocks path traversal. Respects `excluded_paths` and `sensitive_patterns` config.
|
|
451
583
|
|
|
452
584
|
### Detail Level Summary
|
|
453
585
|
|
|
454
|
-
|
|
455
|
-
|
|
586
|
+
All tools that support `detail` use these three levels. Default limits vary by tool — schema defaults shown below:
|
|
587
|
+
|
|
588
|
+
| Level | What it returns | Schema default limit | Best for |
|
|
589
|
+
|-------|----------------|---------------------|----------|
|
|
456
590
|
| `summary` | Names + counts | 50 | Getting the landscape, understanding what exists |
|
|
457
591
|
| `standard` | Names + key details | 15 | Working context, column types, action names |
|
|
458
592
|
| `full` | Everything | 5 | Deep inspection, indexes, FKs, constraints |
|
|
459
593
|
|
|
594
|
+
Other tools default to higher limits (e.g. models/controllers/stimulus: 50 for all levels, routes: 100/200).
|
|
595
|
+
|
|
460
596
|
### Recommended Workflow
|
|
461
597
|
|
|
462
598
|
1. **Start with `detail:"summary"`** to see what exists
|
|
@@ -617,6 +753,49 @@ RailsAiContext.configure do |config|
|
|
|
617
753
|
# Paths to exclude from code search
|
|
618
754
|
config.excluded_paths += %w[vendor/bundle]
|
|
619
755
|
|
|
756
|
+
# Sensitive file patterns blocked from search and read tools
|
|
757
|
+
# config.sensitive_patterns += %w[config/my_secret.yml]
|
|
758
|
+
|
|
759
|
+
# Controllers hidden from listings (e.g. Devise internals)
|
|
760
|
+
# config.excluded_controllers += %w[MyInternalController]
|
|
761
|
+
|
|
762
|
+
# Route prefixes hidden with app_only (e.g. admin frameworks)
|
|
763
|
+
# config.excluded_route_prefixes += %w[admin/]
|
|
764
|
+
|
|
765
|
+
# Regex patterns for concerns to hide from model output
|
|
766
|
+
# config.excluded_concerns += [/MyInternal::/]
|
|
767
|
+
|
|
768
|
+
# Framework filter names hidden from controller output
|
|
769
|
+
# config.excluded_filters += %w[my_internal_filter]
|
|
770
|
+
|
|
771
|
+
# Default middleware hidden from config output
|
|
772
|
+
# config.excluded_middleware += %w[MyMiddleware]
|
|
773
|
+
|
|
774
|
+
# --- File size limits ---
|
|
775
|
+
|
|
776
|
+
# Per-file read limit for tools (default: 2MB)
|
|
777
|
+
# config.max_file_size = 2_000_000
|
|
778
|
+
|
|
779
|
+
# Test file read limit (default: 500KB)
|
|
780
|
+
# config.max_test_file_size = 500_000
|
|
781
|
+
|
|
782
|
+
# schema.rb / structure.sql parse limit (default: 10MB)
|
|
783
|
+
# config.max_schema_file_size = 10_000_000
|
|
784
|
+
|
|
785
|
+
# Max search results per call (default: 100)
|
|
786
|
+
# config.max_search_results = 100
|
|
787
|
+
|
|
788
|
+
# Max files per validate call (default: 20)
|
|
789
|
+
# config.max_validate_files = 20
|
|
790
|
+
|
|
791
|
+
# --- Search and file discovery ---
|
|
792
|
+
|
|
793
|
+
# File extensions for Ruby fallback search
|
|
794
|
+
# config.search_extensions = %w[rb js erb yml yaml json ts tsx vue svelte haml slim]
|
|
795
|
+
|
|
796
|
+
# Where to look for concern source files
|
|
797
|
+
# config.concern_paths = %w[app/models/concerns app/controllers/concerns]
|
|
798
|
+
|
|
620
799
|
# --- Live reload ---
|
|
621
800
|
|
|
622
801
|
# Auto-invalidate MCP tool caches on file changes
|
|
@@ -648,6 +827,7 @@ end
|
|
|
648
827
|
| `cache_ttl` | Integer | `30` | Cache TTL in seconds for introspection results |
|
|
649
828
|
| `excluded_models` | Array | internal Rails models | Models to skip |
|
|
650
829
|
| `excluded_paths` | Array | `node_modules tmp log vendor .git` | Paths excluded from code search |
|
|
830
|
+
| `sensitive_patterns` | Array | `.env`, `.key`, `.pem`, credentials | File patterns blocked from search and read tools |
|
|
651
831
|
| `output_dir` | String | `nil` (Rails.root) | Where to write context files |
|
|
652
832
|
| `auto_mount` | Boolean | `false` | Auto-mount HTTP MCP endpoint |
|
|
653
833
|
| `http_path` | String | `"/mcp"` | HTTP endpoint path |
|
|
@@ -656,7 +836,22 @@ end
|
|
|
656
836
|
| `live_reload` | Symbol/Boolean | `:auto` | `:auto`, `true`, or `false` — enable MCP live reload |
|
|
657
837
|
| `live_reload_debounce` | Float | `1.5` | Debounce interval in seconds for live reload |
|
|
658
838
|
| `server_name` | String | `"rails-ai-context"` | MCP server name |
|
|
839
|
+
| `server_version` | String | gem version | MCP server version |
|
|
659
840
|
| `generate_root_files` | Boolean | `true` | Generate root files (CLAUDE.md, .windsurfrules, etc.) — set `false` for split rules only |
|
|
841
|
+
| `max_file_size` | Integer | `2_000_000` | Per-file read limit for tools (2MB) |
|
|
842
|
+
| `max_test_file_size` | Integer | `500_000` | Test file read limit (500KB) |
|
|
843
|
+
| `max_schema_file_size` | Integer | `10_000_000` | schema.rb / structure.sql parse limit (10MB) |
|
|
844
|
+
| `max_view_total_size` | Integer | `5_000_000` | Total aggregated view content for UI patterns (5MB) |
|
|
845
|
+
| `max_view_file_size` | Integer | `500_000` | Per-view file during aggregation (500KB) |
|
|
846
|
+
| `max_search_results` | Integer | `100` | Max search results per call |
|
|
847
|
+
| `max_validate_files` | Integer | `20` | Max files per validate call |
|
|
848
|
+
| `excluded_controllers` | Array | `DeviseController`, etc. | Controller classes hidden from listings |
|
|
849
|
+
| `excluded_route_prefixes` | Array | `action_mailbox/`, `active_storage/`, etc. | Route controller prefixes hidden with `app_only` |
|
|
850
|
+
| `excluded_concerns` | Array | framework regex patterns | Regex patterns for concerns to hide from model output |
|
|
851
|
+
| `excluded_filters` | Array | `verify_authenticity_token`, etc. | Framework filter names hidden from controller output |
|
|
852
|
+
| `excluded_middleware` | Array | standard Rails middleware | Default middleware hidden from config output |
|
|
853
|
+
| `search_extensions` | Array | `rb js erb yml yaml json ts tsx vue svelte haml slim` | File extensions for Ruby fallback search |
|
|
854
|
+
| `concern_paths` | Array | `app/models/concerns app/controllers/concerns` | Where to look for concern source files |
|
|
660
855
|
|
|
661
856
|
### Root file generation
|
|
662
857
|
|
|
@@ -731,7 +926,7 @@ config.preset = :full
|
|
|
731
926
|
|
|
732
927
|
```ruby
|
|
733
928
|
# Start with standard, add specific ones
|
|
734
|
-
config.introspectors += %i[views turbo auth api
|
|
929
|
+
config.introspectors += %i[views turbo auth api]
|
|
735
930
|
|
|
736
931
|
# Or build from scratch
|
|
737
932
|
config.introspectors = %i[schema models routes gems auth api]
|
|
@@ -60,6 +60,26 @@ module RailsAiContext
|
|
|
60
60
|
# When false, only generates split rule files (.claude/rules/, .cursor/rules/, etc.)
|
|
61
61
|
attr_accessor :generate_root_files
|
|
62
62
|
|
|
63
|
+
# File size limits (bytes) — increase for larger projects
|
|
64
|
+
attr_accessor :max_file_size # Per-file read limit for tools (default: 2MB)
|
|
65
|
+
attr_accessor :max_test_file_size # Test file read limit (default: 500KB)
|
|
66
|
+
attr_accessor :max_schema_file_size # schema.rb / structure.sql parse limit (default: 10MB)
|
|
67
|
+
attr_accessor :max_view_total_size # Total aggregated view content for UI patterns (default: 5MB)
|
|
68
|
+
attr_accessor :max_view_file_size # Per-view file during aggregation (default: 500KB)
|
|
69
|
+
attr_accessor :max_search_results # Max search results per call (default: 100)
|
|
70
|
+
attr_accessor :max_validate_files # Max files per validate call (default: 20)
|
|
71
|
+
|
|
72
|
+
# Filtering — customize what's hidden from AI output
|
|
73
|
+
attr_accessor :excluded_controllers # Controller classes hidden from listings (e.g. DeviseController)
|
|
74
|
+
attr_accessor :excluded_route_prefixes # Route controller prefixes hidden with app_only (e.g. action_mailbox/)
|
|
75
|
+
attr_accessor :excluded_concerns # Regex patterns for concerns to hide (e.g. /Devise::Models/)
|
|
76
|
+
attr_accessor :excluded_filters # Framework filter names hidden from controller output
|
|
77
|
+
attr_accessor :excluded_middleware # Default middleware hidden from config output
|
|
78
|
+
|
|
79
|
+
# Search and file discovery
|
|
80
|
+
attr_accessor :search_extensions # File extensions for Ruby fallback search (default: rb,js,erb,yml,yaml,json)
|
|
81
|
+
attr_accessor :concern_paths # Where to look for concern source files (default: app/models/concerns)
|
|
82
|
+
|
|
63
83
|
def initialize
|
|
64
84
|
@server_name = "rails-ai-context"
|
|
65
85
|
@server_version = RailsAiContext::VERSION
|
|
@@ -87,6 +107,41 @@ module RailsAiContext
|
|
|
87
107
|
@live_reload = :auto
|
|
88
108
|
@live_reload_debounce = 1.5
|
|
89
109
|
@generate_root_files = true
|
|
110
|
+
@max_file_size = 2_000_000
|
|
111
|
+
@max_test_file_size = 500_000
|
|
112
|
+
@max_schema_file_size = 10_000_000
|
|
113
|
+
@max_view_total_size = 5_000_000
|
|
114
|
+
@max_view_file_size = 500_000
|
|
115
|
+
@max_search_results = 100
|
|
116
|
+
@max_validate_files = 20
|
|
117
|
+
@excluded_controllers = %w[DeviseController Devise::OmniauthCallbacksController]
|
|
118
|
+
@excluded_route_prefixes = %w[action_mailbox/ active_storage/ rails/ conductor/ devise/ turbo/]
|
|
119
|
+
@excluded_concerns = [
|
|
120
|
+
/::Generated/,
|
|
121
|
+
/\A(ActiveRecord|ActiveModel|ActiveSupport|ActionText|ActionMailbox|ActiveStorage)/,
|
|
122
|
+
/\A(ActionDispatch|ActionController|ActionView|AbstractController)/,
|
|
123
|
+
/\A(Devise::Models|Devise::Orm|Bullet::|Turbo::|GlobalID::|Rolify::)/
|
|
124
|
+
]
|
|
125
|
+
@excluded_filters = %w[
|
|
126
|
+
verify_authenticity_token verify_same_origin_request
|
|
127
|
+
turbo_tracking_request_id handle_unverified_request
|
|
128
|
+
mark_for_same_origin_verification
|
|
129
|
+
]
|
|
130
|
+
@excluded_middleware = %w[
|
|
131
|
+
Rack::Sendfile ActionDispatch::Static ActionDispatch::Executor
|
|
132
|
+
ActionDispatch::ServerTiming Rack::Runtime
|
|
133
|
+
ActionDispatch::RequestId ActionDispatch::RemoteIp
|
|
134
|
+
Rails::Rack::Logger ActionDispatch::ShowExceptions
|
|
135
|
+
ActionDispatch::DebugExceptions ActionDispatch::Callbacks
|
|
136
|
+
ActionDispatch::Cookies ActionDispatch::Session::CookieStore
|
|
137
|
+
ActionDispatch::Flash ActionDispatch::ContentSecurityPolicy::Middleware
|
|
138
|
+
ActionDispatch::PermissionsPolicy::Middleware ActionDispatch::ActionableExceptions
|
|
139
|
+
Rack::Head Rack::ConditionalGet Rack::ETag Rack::TempfileReaper
|
|
140
|
+
ActiveRecord::Migration::CheckPending ActionDispatch::HostAuthorization
|
|
141
|
+
Rack::MethodOverride ActionDispatch::Session::AbstractSecureStore
|
|
142
|
+
]
|
|
143
|
+
@search_extensions = %w[rb js erb yml yaml json ts tsx vue svelte haml slim]
|
|
144
|
+
@concern_paths = %w[app/models/concerns app/controllers/concerns]
|
|
90
145
|
end
|
|
91
146
|
|
|
92
147
|
def preset=(name)
|
|
@@ -9,12 +9,9 @@ module RailsAiContext
|
|
|
9
9
|
class ControllerIntrospector
|
|
10
10
|
attr_reader :app
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
turbo_tracking_request_id handle_unverified_request
|
|
16
|
-
mark_for_same_origin_verification
|
|
17
|
-
].freeze
|
|
12
|
+
def excluded_filters
|
|
13
|
+
RailsAiContext.configuration.excluded_filters
|
|
14
|
+
end
|
|
18
15
|
|
|
19
16
|
def initialize(app)
|
|
20
17
|
@app = app
|
|
@@ -164,7 +161,7 @@ module RailsAiContext
|
|
|
164
161
|
|
|
165
162
|
ctrl._process_action_callbacks.filter_map do |cb|
|
|
166
163
|
next if cb.filter.is_a?(Proc) || cb.filter.to_s.start_with?("_")
|
|
167
|
-
next if
|
|
164
|
+
next if excluded_filters.include?(cb.filter.to_s)
|
|
168
165
|
|
|
169
166
|
filter = { name: cb.filter.to_s, kind: cb.kind.to_s }
|
|
170
167
|
filter[:only] = cb.instance_variable_get(:@if)&.filter_map { |c| extract_action_condition(c) }&.flatten
|
|
@@ -59,6 +59,7 @@ module RailsAiContext
|
|
|
59
59
|
table_name: model.table_name,
|
|
60
60
|
associations: extract_associations(model),
|
|
61
61
|
validations: extract_validations(model),
|
|
62
|
+
custom_validates: extract_custom_validates(model),
|
|
62
63
|
scopes: extract_scopes(model),
|
|
63
64
|
enums: extract_enums(model),
|
|
64
65
|
callbacks: extract_callbacks(model),
|
|
@@ -109,6 +110,17 @@ module RailsAiContext
|
|
|
109
110
|
[]
|
|
110
111
|
end
|
|
111
112
|
|
|
113
|
+
# Extract custom validate :method_name calls from source
|
|
114
|
+
# These are business-rule validators that model.validators doesn't include
|
|
115
|
+
def extract_custom_validates(model)
|
|
116
|
+
source_path = model_source_path(model)
|
|
117
|
+
return [] unless source_path && File.exist?(source_path)
|
|
118
|
+
|
|
119
|
+
File.read(source_path).scan(/^\s*validate\s+:(\w+)/).flatten
|
|
120
|
+
rescue
|
|
121
|
+
[]
|
|
122
|
+
end
|
|
123
|
+
|
|
112
124
|
def model_source_path(model)
|
|
113
125
|
root = app.root.to_s
|
|
114
126
|
underscored = model.name.underscore
|
|
@@ -156,11 +168,8 @@ module RailsAiContext
|
|
|
156
168
|
|
|
157
169
|
def framework_concern?(name)
|
|
158
170
|
return true if name.nil?
|
|
159
|
-
return true if name.include?("::Generated")
|
|
160
|
-
return true if name.match?(/\A(ActiveRecord|ActiveModel|ActiveSupport|ActionText|ActionMailbox|ActiveStorage|ActionDispatch|ActionController|ActionView|AbstractController)/)
|
|
161
|
-
return true if name.match?(/\A(Devise::Models|Devise::Orm|Bullet::|Turbo::|GlobalID::|Rolify::)/)
|
|
162
171
|
return true if %w[Kernel JSON PP Marshal MessagePack].include?(name)
|
|
163
|
-
|
|
172
|
+
RailsAiContext.configuration.excluded_concerns.any? { |pattern| name.match?(pattern) }
|
|
164
173
|
end
|
|
165
174
|
|
|
166
175
|
def extract_public_class_methods(model)
|
|
@@ -150,7 +150,9 @@ module RailsAiContext
|
|
|
150
150
|
File.join(app.root, "db", "structure.sql")
|
|
151
151
|
end
|
|
152
152
|
|
|
153
|
-
|
|
153
|
+
def max_schema_file_size
|
|
154
|
+
RailsAiContext.configuration.max_schema_file_size
|
|
155
|
+
end
|
|
154
156
|
|
|
155
157
|
# Fallback: parse schema file as text when DB isn't connected.
|
|
156
158
|
# Tries db/schema.rb first, then db/structure.sql.
|
|
@@ -166,7 +168,7 @@ module RailsAiContext
|
|
|
166
168
|
end
|
|
167
169
|
|
|
168
170
|
def parse_schema_rb(path)
|
|
169
|
-
return { error: "schema.rb too large (#{File.size(path)} bytes)" } if File.size(path) >
|
|
171
|
+
return { error: "schema.rb too large (#{File.size(path)} bytes)" } if File.size(path) > max_schema_file_size
|
|
170
172
|
content = File.read(path)
|
|
171
173
|
tables = {}
|
|
172
174
|
current_table = nil
|
|
@@ -209,7 +211,7 @@ module RailsAiContext
|
|
|
209
211
|
end
|
|
210
212
|
|
|
211
213
|
def parse_structure_sql(path) # rubocop:disable Metrics/MethodLength
|
|
212
|
-
return { error: "structure.sql too large (#{File.size(path)} bytes)" } if File.size(path) >
|
|
214
|
+
return { error: "structure.sql too large (#{File.size(path)} bytes)" } if File.size(path) > max_schema_file_size
|
|
213
215
|
content = File.read(path)
|
|
214
216
|
tables = {}
|
|
215
217
|
|
|
@@ -61,15 +61,14 @@ module RailsAiContext
|
|
|
61
61
|
partials
|
|
62
62
|
end
|
|
63
63
|
|
|
64
|
-
MAX_TOTAL_VIEW_SIZE = 5_000_000 # 5MB cap for aggregated view content
|
|
65
|
-
MAX_SINGLE_VIEW_SIZE = 500_000 # 500KB per file
|
|
66
|
-
|
|
67
64
|
def collect_all_view_content(views_dir)
|
|
65
|
+
max_total = RailsAiContext.configuration.max_view_total_size
|
|
66
|
+
max_single = RailsAiContext.configuration.max_view_file_size
|
|
68
67
|
content = +""
|
|
69
68
|
Dir.glob(File.join(views_dir, "**", "*.{erb,haml,slim}")).each do |path|
|
|
70
69
|
next if File.directory?(path)
|
|
71
|
-
next if File.size(path) >
|
|
72
|
-
break if content.bytesize >=
|
|
70
|
+
next if File.size(path) > max_single
|
|
71
|
+
break if content.bytesize >= max_total
|
|
73
72
|
content << (File.read(path, encoding: "UTF-8", invalid: :replace, undef: :replace) rescue "")
|
|
74
73
|
end
|
|
75
74
|
content
|