rails-ai-context 2.0.3 → 2.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 582aebf4849cdb8617b33dff88f3822009b8960e1334bbd1aa2eb6a3f6a03350
4
- data.tar.gz: 03c8eedbf4989f07a75f878fe86380b809dd4ae1e2afd0020836a848da99b5c3
3
+ metadata.gz: e17feb99495b6f8328eedaa95020ca097aa4ee7df658ed0a51a925cd6961cdee
4
+ data.tar.gz: 8b5dc406788cc2af104813e0711887bfc6a5ef0e97ddc79464291b0da74ad7df
5
5
  SHA512:
6
- metadata.gz: 5a2abfe4dc7c9c123dacd427354789810197c478fab741ac88e9aa0d8c95fcccc5cac2b5005f01615cf678f7229362d3e4ea5838d7c76d2210b28a8531edd9da
7
- data.tar.gz: 3f04bb928f49325badb6a956a54c1adb9dec73ac2f73b9d7f81831f5da5931ac0ef1f4494a5c71780cdabcfa159c38ff11a4bd6f7fbcbb7ac79272aaf5de4e3b
6
+ metadata.gz: a8b7ff36197da72c8b1d3ca1c7199da2333015fda502a37c83d819a95394732449b2d26f20084a14687b59c6fcde10445dda5fbf4705890793ae213bda2cba33
7
+ data.tar.gz: 22e5d0ae93d2af2c01f383197a10e454667f0d24af0bb463a191922913702d3c976f04fb918e7716833af874ee1913d86182d234e36c65bb568469a8ead8f116
data/CHANGELOG.md CHANGED
@@ -5,6 +5,24 @@ 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
+ ## [2.0.5] - 2026-03-25
9
+
10
+ ### Changed
11
+
12
+ - **Task-based MCP tool instructions** — all 6 serializers (Claude, Cursor, Copilot, Windsurf, OpenCode) rewritten from tool-first to task-first: "What are you trying to do?" → exact tool call. 7 task categories: understand a feature, trace a method, add a field, fix a controller, build a view, write tests, find code. Every AI agent now understands which tool to use for any task.
13
+ - **Concern detail:"full" bug fix** — `\b` after `?`/`!` prevented 13 of 15 method bodies from being extracted. All methods now show source code.
14
+
15
+ ## [2.0.4] - 2026-03-25
16
+
17
+ ### Added
18
+
19
+ - **Orphaned table detection** — `get_schema` standard mode flags tables with no ActiveRecord model: "⚠ Orphaned tables: content_calendars, cook_comments"
20
+ - **Concern method source code** — `get_concern(name:"X", detail:"full")` shows method bodies inline, same pattern as callbacks tool.
21
+ - **analyze_feature: inherited filters** — shows `authenticate_user! (from ApplicationController)` in controller section.
22
+ - **analyze_feature: code-ready route helpers** — `cook_path(@record)`, `cooks_path` inline with routes.
23
+ - **analyze_feature: service test gaps** — checks services for missing test files, not just models/controllers/jobs.
24
+ - **All 6 serializers updated** — Claude, Cursor, Copilot, Windsurf, OpenCode all document trace mode, concern source, orphaned tables, inherited filters.
25
+
8
26
  ## [2.0.3] - 2026-03-25
9
27
 
10
28
  ### Added
@@ -297,130 +297,80 @@ module RailsAiContext
297
297
  lines = [
298
298
  "# Rails MCP Tools — MANDATORY, Use Before Read/Grep",
299
299
  "",
300
- "CRITICAL: This project has live MCP tools. You MUST use them for gathering context.",
301
- "MCP tools return parsed, up-to-date, token-efficient data with line numbers.",
302
- "Read files ONLY when you are about to Edit them. Never read reference files directly.",
303
- "",
304
- "## Mandatory Workflow — Follow This Order",
305
- "",
306
- "### 1. Gathering context (BEFORE writing any code)",
307
- "- Exploring a feature area → `rails_analyze_feature(feature:\"...\")` — NOT Explore agents, NOT Grep",
308
- "- Understanding a model → `rails_get_model_details(model:\"...\")` — NOT reading the model file",
309
- "- Checking database columns `rails_get_schema(table:\"...\")` NOT reading db/schema.rb",
310
- "- Checking routes → `rails_get_routes(controller:\"...\")` — NOT reading config/routes.rb",
311
- "- Understanding a controller → `rails_get_controllers(controller:\"...\", action:\"...\")` — NOT reading the file",
312
- "- Finding code patterns `rails_search_code(pattern:\"...\")` — NOT using Grep tool",
313
- "- UI patterns → `rails_get_design_system` — NOT reading view files for patterns",
314
- "- Full cross-layer context → `rails_get_context(model:\"...\")` — replaces multiple Read calls",
315
- "",
316
- "### 2. Reading files (ONLY files you will edit)",
317
- "- Read a file ONLY when you are about to Edit it (Read is required before Edit)",
318
- "- For everything else — schema, routes, models, tests, patterns — use MCP tools above",
319
- "",
320
- "### 3. After editing (EVERY time, no exceptions)",
321
- "- `rails_validate(files:[\"path/to/file.rb\", \"path/to/view.erb\"])` — one call checks all",
322
- "- Do NOT run `ruby -c`, `erb` checks, or `node -c` separately — use rails_validate instead",
323
- "- Do NOT re-read files to verify edits. Trust your Edit and validate syntax only.",
324
- "",
325
- "## Do NOT Bypass Anti-Patterns",
326
- "| Instead of... | Use this MCP tool |",
327
- "|---------------|-------------------|",
328
- "| Reading db/schema.rb | `rails_get_schema(table:\"name\")` |",
329
- "| Reading config/routes.rb for reference | `rails_get_routes(controller:\"name\")` |",
330
- "| Reading model files for associations | `rails_get_model_details(model:\"Name\")` |",
331
- "| Grep/Explore agent for code search | `rails_search_code(pattern:\"regex\")` |",
332
- "| Reading test files for patterns | `rails_get_test_info(model:\"Name\")` |",
333
- "| Reading controller files for context | `rails_get_controllers(controller:\"Name\")` |",
334
- "| Reading JS files for Stimulus API | `rails_get_stimulus(controller:\"name\")` |",
335
- "| Multiple reads to understand a feature | `rails_analyze_feature(feature:\"keyword\")` |",
336
- "| ruby -c / erb / node -c after edits | `rails_validate(files:[...])` |",
337
- "",
338
- "## Reference-only files NEVER read these, use MCP",
339
- "- db/schema.rb `rails_get_schema` (column types in rails-schema.md rules for quick checks)",
340
- "- config/routes.rb `rails_get_routes` (Read ONLY when adding routes)",
341
- "- Model files `rails_get_model_details` (Read ONLY when editing business logic)",
342
- "- app/javascript/controllers/index.js Stimulus auto-registers. Never read this.",
343
- "- Test files → `rails_get_test_info`",
344
- "",
345
- "## Tools (25)",
346
- "",
347
- "**rails_get_schema** — database tables, columns, indexes, foreign keys",
348
- "- `rails_get_schema(detail:\"summary\")` all tables with column counts",
349
- "- `rails_get_schema(table:\"users\")` full detail for one table",
350
- "",
351
- "**rails_get_model_details** — associations, validations, scopes, enums, callbacks",
352
- "- `rails_get_model_details(detail:\"summary\")` list all model names",
353
- "- `rails_get_model_details(model:\"User\")` full detail for one model",
354
- "",
355
- "**rails_get_routes** HTTP verbs, paths, controller actions",
356
- "- `rails_get_routes(detail:\"summary\")` route counts per controller",
357
- "- `rails_get_routes(controller:\"users\")` routes for one controller",
358
- "",
359
- "**rails_get_controllers** actions, filters, strong params, action source code",
360
- "- `rails_get_controllers(detail:\"summary\")` names + action counts",
361
- "- `rails_get_controllers(controller:\"CooksController\", action:\"index\")` action source code + filters",
362
- "",
363
- "**rails_get_view** view templates, partials, Stimulus references",
364
- "- `rails_get_view(controller:\"cooks\")` list all views for a controller",
365
- "- `rails_get_view(path:\"cooks/index.html.erb\")` full template content",
366
- "",
367
- "**rails_get_stimulus** Stimulus controllers with targets, values, actions",
368
- "- `rails_get_stimulus(detail:\"summary\")` all controllers with counts",
369
- "- `rails_get_stimulus(controller:\"filter-form\")` full detail for one controller",
370
- "",
371
- "**rails_get_test_info** test framework, fixtures, factories, helpers",
372
- "- `rails_get_test_info(detail:\"full\")` fixture names, factory names, helper setup",
373
- "- `rails_get_test_info(model:\"Cook\")` full test source for a model",
374
- "- `rails_get_test_info(model:\"Cook\", detail:\"summary\")` — test names only (saves tokens)",
375
- "- `rails_get_test_info(controller:\"Cooks\")` — existing controller tests",
376
- "",
377
- "**rails_get_edit_context** — surgical edit helper with line numbers",
378
- "- `rails_get_edit_context(file:\"app/models/cook.rb\", near:\"scope\")` — returns code around match with line numbers",
379
- "",
380
- "**rails_validate** — syntax checker for edited files",
381
- "- `rails_validate(files:[\"app/models/cook.rb\"])` — checks Ruby, ERB, JS syntax in one call",
382
- "",
383
- "**rails_analyze_feature** — combined schema + models + controllers + routes for a feature area",
384
- "- `rails_analyze_feature(feature:\"authentication\")` — one call gets everything related to a feature",
385
- "",
386
- "**rails_get_design_system** — color palette, component patterns, canonical page examples",
387
- "- `rails_get_design_system(detail:\"standard\")` — colors + components + real HTML examples + design rules",
388
- "- `rails_get_design_system(detail:\"full\")` — + typography, responsive, dark mode, layout, spacing",
389
- "",
390
- "**rails_get_config** — cache store, session, timezone, middleware, initializers",
391
- "**rails_get_gems** — notable gems categorized by function",
392
- "**rails_get_conventions** — architecture patterns, directory structure",
393
- "**rails_search_code** — regex search: `rails_search_code(pattern:\"regex\", file_type:\"rb\")`",
394
- "",
395
- "**rails_security_scan** — Brakeman security analysis",
396
- "- `rails_security_scan` — run security scan, returns warnings by confidence",
397
- "",
398
- "**rails_get_concern** — concern methods and includers",
399
- "- `rails_get_concern(name:\"Searchable\")` — methods, included modules, includers",
400
- "",
401
- "**rails_get_callbacks** — model callbacks in execution order",
402
- "- `rails_get_callbacks(model:\"User\")` — before/after/around callbacks by type",
403
- "",
404
- "**rails_get_helper_methods** — app + framework helpers",
405
- "- `rails_get_helper_methods` — all helper methods across app and framework",
406
- "",
407
- "**rails_get_service_pattern** — service object patterns and interfaces",
408
- "- `rails_get_service_pattern` — service objects with call signatures and dependencies",
409
- "",
410
- "**rails_get_job_pattern** — background job patterns and schedules",
411
- "- `rails_get_job_pattern` — job classes, queues, retry policies, schedules",
412
- "",
413
- "**rails_get_env** — environment variables and credentials keys",
414
- "- `rails_get_env` — ENV vars referenced in code + credentials structure",
415
- "",
416
- "**rails_get_partial_interface** — partial locals contract",
417
- "- `rails_get_partial_interface(path:\"shared/_form\")` — required/optional locals for a partial",
418
- "",
419
- "**rails_get_turbo_map** — Turbo Streams/Frames wiring",
420
- "- `rails_get_turbo_map` — Turbo Frame IDs, Stream channels, broadcast sources",
421
- "",
422
- "**rails_get_context** — composite cross-layer context",
423
- "- `rails_get_context(model:\"User\")` — schema + model + controllers + views in one call"
300
+ "This project has 25 live MCP tools. You MUST use them instead of reading files.",
301
+ "Read files ONLY when you are about to Edit them.",
302
+ "",
303
+ "## What Are You Trying to Do?",
304
+ "",
305
+ "**Understand a feature or area:**",
306
+ " `rails_analyze_feature(feature:\"cook\")` models + controllers + routes + services + jobs + views + tests in one call",
307
+ "→ `rails_get_context(model:\"Cook\")` — schema + model + controller + views assembled together",
308
+ "",
309
+ "**Understand a method (who calls it, what it calls):**",
310
+ "→ `rails_search_code(pattern:\"can_cook?\", match_type:\"trace\")` — definition + source + siblings + all callers + test coverage",
311
+ "",
312
+ "**Add a field or modify a model:**",
313
+ "→ `rails_get_schema(table:\"cooks\")` — columns, types, indexes, defaults, encrypted hints",
314
+ "→ `rails_get_model_details(model:\"Cook\")` — associations, validations, scopes, enums, callbacks, macros",
315
+ "",
316
+ "**Fix a controller bug:**",
317
+ " `rails_get_controllers(controller:\"CooksController\", action:\"create\")` source + inherited filters + render map + side effects + private methods",
318
+ "",
319
+ "**Build or modify a view:**",
320
+ " `rails_get_design_system(detail:\"standard\")` canonical HTML/ERB patterns to copy",
321
+ " `rails_get_view(controller:\"cooks\")` — templates with ivars, Turbo wiring, Stimulus refs",
322
+ " `rails_get_partial_interface(partial:\"shared/status_badge\")` what locals to pass",
323
+ "",
324
+ "**Write tests:**",
325
+ " `rails_get_test_info(detail:\"standard\")` framework + fixtures + test template to copy",
326
+ " `rails_get_test_info(model:\"Cook\")` existing tests for a model",
327
+ "",
328
+ "**Find code:**",
329
+ " `rails_search_code(pattern:\"has_many\")` — regex search with 2 lines of context",
330
+ " `rails_search_code(pattern:\"create\", match_type:\"definition\")` — only `def` lines",
331
+ " `rails_search_code(pattern:\"can_cook\", match_type:\"call\")` — only call sites",
332
+ "",
333
+ "**After editing (EVERY time):**",
334
+ " `rails_validate(files:[\"app/models/cook.rb\", \"app/views/cooks/new.html.erb\"], level:\"rails\")` — syntax + semantics + security",
335
+ "",
336
+ "## Rules",
337
+ "",
338
+ "1. NEVER read db/schema.rb, config/routes.rb, model files, or test files for reference — use the MCP tools above",
339
+ "2. NEVER use Grep or Explore agents for code search — use `rails_search_code`",
340
+ "3. NEVER run `ruby -c`, `erb`, or `node -c` use `rails_validate`",
341
+ "4. Read files ONLY when you are about to Edit them",
342
+ "5. Start with `detail:\"summary\"` to orient, then drill into specifics",
343
+ "",
344
+ "## All 25 Tools",
345
+ "",
346
+ "| Tool | What it does |",
347
+ "|------|-------------|",
348
+ "| `rails_analyze_feature(feature:\"X\")` | Full-stack: models + controllers (inherited filters) + routes (helpers) + services + jobs + views + tests + gaps |",
349
+ "| `rails_get_context(model:\"X\")` | Composite: schema + model + controller + routes + views in one call |",
350
+ "| `rails_search_code(pattern:\"X\", match_type:\"trace\")` | Trace: definition + class context + source + siblings + callers + test coverage |",
351
+ "| `rails_get_controllers(controller:\"X\", action:\"Y\")` | Action source + inherited filters + render map + side effects + private methods |",
352
+ "| `rails_validate(files:[...], level:\"rails\")` | Syntax + semantic validation + Brakeman security (if installed) |",
353
+ "| `rails_get_schema(table:\"X\")` | Columns with [indexed]/[unique]/[encrypted]/[default] + orphaned table warnings |",
354
+ "| `rails_get_model_details(model:\"X\")` | Associations, validations, scopes (with body), enums (with backing type), macros, delegations |",
355
+ "| `rails_get_routes(controller:\"X\")` | Routes with code-ready helpers (`cook_path(@record)`) and controller filters inline |",
356
+ "| `rails_get_view(controller:\"X\")` | Templates with ivars, Turbo Frame/Stream IDs, Stimulus refs, partial locals |",
357
+ "| `rails_get_design_system` | Canonical HTML/ERB copy-paste patterns for buttons, inputs, cards, modals |",
358
+ "| `rails_get_stimulus(controller:\"X\")` | Targets, values, actions + copy-paste HTML data-attributes + reverse view lookup |",
359
+ "| `rails_get_test_info(model:\"X\")` | Existing tests + fixture contents with relationships + test template |",
360
+ "| `rails_get_concern(name:\"X\", detail:\"full\")` | Concern methods with full source code + which models include it |",
361
+ "| `rails_get_callbacks(model:\"X\")` | Callbacks in Rails execution order with source |",
362
+ "| `rails_get_edit_context(file:\"X\", near:\"Y\")` | Code around a match with class/method context + line numbers |",
363
+ "| `rails_search_code(pattern:\"X\")` | Regex search with smart limiting + `exclude_tests` + `group_by_file` + pagination |",
364
+ "| `rails_get_service_pattern` | Service objects: interface, dependencies, side effects, callers |",
365
+ "| `rails_get_job_pattern` | Jobs: queue, retries, guard clauses, broadcasts, schedules |",
366
+ "| `rails_get_env` | Environment variables + credentials keys (not values) + external services |",
367
+ "| `rails_get_partial_interface(partial:\"X\")` | Partial locals contract: what to pass + usage examples |",
368
+ "| `rails_get_turbo_map` | Turbo Stream/Frame wiring: broadcasts → subscriptions + mismatch warnings |",
369
+ "| `rails_get_helper_methods` | App + framework helper methods with view cross-references |",
370
+ "| `rails_get_config` | Database adapter, auth framework, assets stack, cache, queue, Action Cable |",
371
+ "| `rails_get_gems` | Notable gems with versions, categories, config file locations |",
372
+ "| `rails_get_conventions` | App patterns: auth checks, flash messages, create action template, test patterns |",
373
+ "| `rails_security_scan` | Brakeman static analysis: SQL injection, XSS, mass assignment |"
424
374
  ]
425
375
 
426
376
  lines.join("\n")
@@ -196,42 +196,84 @@ module RailsAiContext
196
196
  render_design_system(context, max_lines: 30)
197
197
  end
198
198
 
199
- def render_mcp_guide # rubocop:disable Metrics/MethodLength
199
+ def render_mcp_guide # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
200
200
  [
201
- "## MCP Tools (25) — ALWAYS Use These First",
201
+ "## MCP Tools (25) — MANDATORY, Use Before Read/Grep",
202
202
  "",
203
- "This project has live MCP tools. You MUST use them instead of reading reference files.",
204
- "Start with `detail:\"summary\"`, then drill into specifics.",
203
+ "This project has 25 live MCP tools. You MUST use them instead of reading files.",
204
+ "Read files ONLY when you are about to Edit them.",
205
205
  "",
206
- "### Mandatory Workflow",
207
- "1. **Before exploring a feature**: `rails_analyze_feature(feature:\"...\")` — NOT Explore agents or Grep",
208
- "2. **Before writing migrations**: `rails_get_schema(table:\"...\")` — NOT reading db/schema.rb",
209
- "3. **Before modifying a model**: `rails_get_model_details(model:\"...\")` — NOT reading the model file",
210
- "4. **Before adding routes**: `rails_get_routes(controller:\"...\")` — Read routes.rb only when you will edit it",
211
- "5. **Before creating views**: `rails_get_design_system` — match existing patterns",
212
- "6. **After editing ANY file**: `rails_validate(files:[...])` — no exceptions, no ruby -c / erb / node -c",
206
+ "### What Are You Trying to Do?",
213
207
  "",
214
- "### Quick Reference",
215
- "| Need | Use this MCP tool | Do NOT use |",
216
- "|------|-------------------|------------|",
217
- "| Column types | `rails_get_schema(table:\"x\")` | Read db/schema.rb |",
218
- "| Model associations | `rails_get_model_details(model:\"X\")` | Read app/models/x.rb |",
219
- "| Route paths | `rails_get_routes(controller:\"x\")` | Read config/routes.rb |",
220
- "| Feature overview | `rails_analyze_feature(feature:\"x\")` | Explore agent / Grep |",
221
- "| Find code | `rails_search_code(pattern:\"x\")` | Grep tool |",
222
- "| Validate edits | `rails_validate(files:[...])` | ruby -c / erb / node |",
223
- "| Controller logic | `rails_get_controllers(controller:\"X\", action:\"y\")` | Read controller file |",
224
- "| UI patterns | `rails_get_design_system` | Read view files |",
225
- "| Stimulus API | `rails_get_stimulus(controller:\"x\")` | Read JS files |",
226
- "| Test patterns | `rails_get_test_info(model:\"X\")` | Read test files |",
227
- "| Full context | `rails_get_context(model:\"X\")` | Multiple Read calls |",
208
+ "**Understand a feature or area:**",
209
+ " `rails_analyze_feature(feature:\"cook\")` models + controllers + routes + services + jobs + views + tests in one call",
210
+ "→ `rails_get_context(model:\"Cook\")` — schema + model + controller + views assembled together",
228
211
  "",
229
- "### More Tools",
230
- "- `rails_get_view(controller:\"x\")` | `rails_get_concern(name:\"X\")` | `rails_get_callbacks(model:\"X\")`",
231
- "- `rails_get_helper_methods` | `rails_get_service_pattern` | `rails_get_job_pattern`",
232
- "- `rails_get_env` | `rails_get_partial_interface(path:\"shared/_form\")` | `rails_get_turbo_map`",
233
- "- `rails_get_config` | `rails_get_gems` | `rails_get_conventions` | `rails_security_scan`",
234
- "- `rails_get_edit_context(file:\"path\", near:\"keyword\")` — surgical edit helper with line numbers",
212
+ "**Understand a method (who calls it, what it calls):**",
213
+ " `rails_search_code(pattern:\"can_cook?\", match_type:\"trace\")` definition + source + siblings + all callers + test coverage",
214
+ "",
215
+ "**Add a field or modify a model:**",
216
+ " `rails_get_schema(table:\"cooks\")` columns, types, indexes, defaults, encrypted hints",
217
+ " `rails_get_model_details(model:\"Cook\")` — associations, validations, scopes, enums, callbacks, macros",
218
+ "",
219
+ "**Fix a controller bug:**",
220
+ "→ `rails_get_controllers(controller:\"CooksController\", action:\"create\")` — source + inherited filters + render map + side effects + private methods",
221
+ "",
222
+ "**Build or modify a view:**",
223
+ "→ `rails_get_design_system(detail:\"standard\")` — canonical HTML/ERB patterns to copy",
224
+ "→ `rails_get_view(controller:\"cooks\")` — templates with ivars, Turbo wiring, Stimulus refs",
225
+ "→ `rails_get_partial_interface(partial:\"shared/status_badge\")` — what locals to pass",
226
+ "",
227
+ "**Write tests:**",
228
+ "→ `rails_get_test_info(detail:\"standard\")` — framework + fixtures + test template to copy",
229
+ "→ `rails_get_test_info(model:\"Cook\")` — existing tests for a model",
230
+ "",
231
+ "**Find code:**",
232
+ "→ `rails_search_code(pattern:\"has_many\")` — regex search with 2 lines of context",
233
+ "→ `rails_search_code(pattern:\"create\", match_type:\"definition\")` — only `def` lines",
234
+ "→ `rails_search_code(pattern:\"can_cook\", match_type:\"call\")` — only call sites",
235
+ "",
236
+ "**After editing (EVERY time):**",
237
+ "→ `rails_validate(files:[\"app/models/cook.rb\", \"app/views/cooks/new.html.erb\"], level:\"rails\")` — syntax + semantics + security",
238
+ "",
239
+ "### Rules",
240
+ "",
241
+ "1. NEVER read db/schema.rb, config/routes.rb, model files, or test files for reference — use the MCP tools above",
242
+ "2. NEVER use Grep or Explore agents for code search — use `rails_search_code`",
243
+ "3. NEVER run `ruby -c`, `erb`, or `node -c` — use `rails_validate`",
244
+ "4. Read files ONLY when you are about to Edit them",
245
+ "5. Start with `detail:\"summary\"` to orient, then drill into specifics",
246
+ "",
247
+ "### All 25 Tools",
248
+ "",
249
+ "| Tool | What it does |",
250
+ "|------|-------------|",
251
+ "| `rails_analyze_feature(feature:\"X\")` | Full-stack: models + controllers (inherited filters) + routes (helpers) + services + jobs + views + tests + gaps |",
252
+ "| `rails_get_context(model:\"X\")` | Composite: schema + model + controller + routes + views in one call |",
253
+ "| `rails_search_code(pattern:\"X\", match_type:\"trace\")` | Trace: definition + class context + source + siblings + callers + test coverage |",
254
+ "| `rails_get_controllers(controller:\"X\", action:\"Y\")` | Action source + inherited filters + render map + side effects + private methods |",
255
+ "| `rails_validate(files:[...], level:\"rails\")` | Syntax + semantic validation + Brakeman security (if installed) |",
256
+ "| `rails_get_schema(table:\"X\")` | Columns with [indexed]/[unique]/[encrypted]/[default] + orphaned table warnings |",
257
+ "| `rails_get_model_details(model:\"X\")` | Associations, validations, scopes (with body), enums (with backing type), macros, delegations |",
258
+ "| `rails_get_routes(controller:\"X\")` | Routes with code-ready helpers (`cook_path(@record)`) and controller filters inline |",
259
+ "| `rails_get_view(controller:\"X\")` | Templates with ivars, Turbo Frame/Stream IDs, Stimulus refs, partial locals |",
260
+ "| `rails_get_design_system` | Canonical HTML/ERB copy-paste patterns for buttons, inputs, cards, modals |",
261
+ "| `rails_get_stimulus(controller:\"X\")` | Targets, values, actions + copy-paste HTML data-attributes + reverse view lookup |",
262
+ "| `rails_get_test_info(model:\"X\")` | Existing tests + fixture contents with relationships + test template |",
263
+ "| `rails_get_concern(name:\"X\", detail:\"full\")` | Concern methods with full source code + which models include it |",
264
+ "| `rails_get_callbacks(model:\"X\")` | Callbacks in Rails execution order with source |",
265
+ "| `rails_get_edit_context(file:\"X\", near:\"Y\")` | Code around a match with class/method context + line numbers |",
266
+ "| `rails_search_code(pattern:\"X\")` | Regex search with smart limiting + `exclude_tests` + `group_by_file` + pagination |",
267
+ "| `rails_get_service_pattern` | Service objects: interface, dependencies, side effects, callers |",
268
+ "| `rails_get_job_pattern` | Jobs: queue, retries, guard clauses, broadcasts, schedules |",
269
+ "| `rails_get_env` | Environment variables + credentials keys (not values) + external services |",
270
+ "| `rails_get_partial_interface(partial:\"X\")` | Partial locals contract: what to pass + usage examples |",
271
+ "| `rails_get_turbo_map` | Turbo Stream/Frame wiring: broadcasts → subscriptions + mismatch warnings |",
272
+ "| `rails_get_helper_methods` | App + framework helper methods with view cross-references |",
273
+ "| `rails_get_config` | Database adapter, auth framework, assets stack, cache, queue, Action Cable |",
274
+ "| `rails_get_gems` | Notable gems with versions, categories, config file locations |",
275
+ "| `rails_get_conventions` | App patterns: auth checks, flash messages, create action template, test patterns |",
276
+ "| `rails_security_scan` | Brakeman static analysis: SQL injection, XSS, mass assignment |",
235
277
  ""
236
278
  ]
237
279
  end
@@ -266,18 +308,8 @@ module RailsAiContext
266
308
  "- Follow existing patterns and conventions",
267
309
  "- Match existing code style",
268
310
  "- Run tests after changes",
269
- "- After editing, ALWAYS use `rails_validate(files:[...])` — do NOT use separate ruby -c / erb / node -c calls",
270
311
  "- Do NOT re-read files to verify edits — trust your Edit, validate syntax only",
271
312
  "- Stimulus controllers auto-register — no manual import in controllers/index.js needed",
272
- "",
273
- "## MCP-First Rule — Do NOT Bypass",
274
- "- Do NOT read db/schema.rb — use `rails_get_schema`",
275
- "- Do NOT read config/routes.rb for reference — use `rails_get_routes`",
276
- "- Do NOT read model files for associations/scopes — use `rails_get_model_details`",
277
- "- Do NOT use Grep to search code — use `rails_search_code`",
278
- "- Do NOT launch Explore agents for context — use `rails_analyze_feature`",
279
- "- Do NOT read test files for patterns — use `rails_get_test_info`",
280
- "- Read files ONLY when you are about to Edit them",
281
313
  ""
282
314
  ]
283
315
  end
@@ -213,44 +213,88 @@ module RailsAiContext
213
213
  lines.join("\n")
214
214
  end
215
215
 
216
- def render_mcp_tools_instructions # rubocop:disable Metrics/MethodLength
216
+ def render_mcp_tools_instructions # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
217
217
  lines = [
218
218
  "---",
219
219
  "applyTo: \"**/*\"",
220
220
  "---",
221
221
  "",
222
- "# Rails MCP Tools (25) — MANDATORY, Use Before Read",
222
+ "# Rails MCP Tools — MANDATORY, Use Before Read/Grep",
223
223
  "",
224
- "CRITICAL: This project has live MCP tools. You MUST use them for gathering context.",
225
- "Read files ONLY when you are about to edit them. Never read reference files directly.",
226
- "Start with `detail:\"summary\"`, then drill into specifics.",
224
+ "This project has 25 live MCP tools. You MUST use them instead of reading files.",
225
+ "Read files ONLY when you are about to Edit them.",
227
226
  "",
228
- "## Mandatory Workflow",
229
- "1. Gathering context → use MCP tools (NOT file reads, NOT grep)",
230
- "2. Reading files → ONLY files you will edit",
231
- "3. After editing → `rails_validate(files:[...])` every time, no exceptions",
227
+ "## What Are You Trying to Do?",
232
228
  "",
233
- "## Do NOT Bypass",
234
- "| Instead of... | Use this MCP tool |",
235
- "|---------------|-------------------|",
236
- "| Reading db/schema.rb | `rails_get_schema(table:\"name\")` |",
237
- "| Reading config/routes.rb | `rails_get_routes(controller:\"name\")` |",
238
- "| Reading model files for context | `rails_get_model_details(model:\"Name\")` |",
239
- "| Grep for code patterns | `rails_search_code(pattern:\"regex\")` |",
240
- "| Reading test files | `rails_get_test_info(model:\"Name\")` |",
241
- "| Reading controller for context | `rails_get_controllers(controller:\"Name\", action:\"x\")` |",
242
- "| Reading JS for Stimulus API | `rails_get_stimulus(controller:\"name\")` |",
243
- "| Multiple reads for a feature | `rails_analyze_feature(feature:\"keyword\")` |",
244
- "| ruby -c / erb / node -c | `rails_validate(files:[...])` |",
229
+ "**Understand a feature or area:**",
230
+ " `rails_analyze_feature(feature:\"cook\")` models + controllers + routes + services + jobs + views + tests in one call",
231
+ "→ `rails_get_context(model:\"Cook\")` — schema + model + controller + views assembled together",
232
+ "",
233
+ "**Understand a method (who calls it, what it calls):**",
234
+ " `rails_search_code(pattern:\"can_cook?\", match_type:\"trace\")` — definition + source + siblings + all callers + test coverage",
235
+ "",
236
+ "**Add a field or modify a model:**",
237
+ " `rails_get_schema(table:\"cooks\")` — columns, types, indexes, defaults, encrypted hints",
238
+ " `rails_get_model_details(model:\"Cook\")` — associations, validations, scopes, enums, callbacks, macros",
239
+ "",
240
+ "**Fix a controller bug:**",
241
+ "→ `rails_get_controllers(controller:\"CooksController\", action:\"create\")` — source + inherited filters + render map + side effects + private methods",
242
+ "",
243
+ "**Build or modify a view:**",
244
+ "→ `rails_get_design_system(detail:\"standard\")` — canonical HTML/ERB patterns to copy",
245
+ "→ `rails_get_view(controller:\"cooks\")` — templates with ivars, Turbo wiring, Stimulus refs",
246
+ "→ `rails_get_partial_interface(partial:\"shared/status_badge\")` — what locals to pass",
247
+ "",
248
+ "**Write tests:**",
249
+ "→ `rails_get_test_info(detail:\"standard\")` — framework + fixtures + test template to copy",
250
+ "→ `rails_get_test_info(model:\"Cook\")` — existing tests for a model",
251
+ "",
252
+ "**Find code:**",
253
+ "→ `rails_search_code(pattern:\"has_many\")` — regex search with 2 lines of context",
254
+ "→ `rails_search_code(pattern:\"create\", match_type:\"definition\")` — only `def` lines",
255
+ "→ `rails_search_code(pattern:\"can_cook\", match_type:\"call\")` — only call sites",
256
+ "",
257
+ "**After editing (EVERY time):**",
258
+ "→ `rails_validate(files:[\"app/models/cook.rb\", \"app/views/cooks/new.html.erb\"], level:\"rails\")` — syntax + semantics + security",
259
+ "",
260
+ "## Rules",
261
+ "",
262
+ "1. NEVER read db/schema.rb, config/routes.rb, model files, or test files for reference — use the MCP tools above",
263
+ "2. NEVER use Grep or Explore agents for code search — use `rails_search_code`",
264
+ "3. NEVER run `ruby -c`, `erb`, or `node -c` — use `rails_validate`",
265
+ "4. Read files ONLY when you are about to Edit them",
266
+ "5. Start with `detail:\"summary\"` to orient, then drill into specifics",
245
267
  "",
246
268
  "## All 25 Tools",
247
- "- `rails_get_schema` | `rails_get_model_details` | `rails_get_routes` | `rails_get_controllers`",
248
- "- `rails_get_view` | `rails_get_stimulus` | `rails_get_test_info` | `rails_analyze_feature`",
249
- "- `rails_get_design_system` | `rails_get_edit_context` | `rails_validate` | `rails_search_code`",
250
- "- `rails_get_config` | `rails_get_gems` | `rails_get_conventions` | `rails_security_scan`",
251
- "- `rails_get_concern` | `rails_get_callbacks` | `rails_get_helper_methods` | `rails_get_service_pattern`",
252
- "- `rails_get_job_pattern` | `rails_get_env` | `rails_get_partial_interface` | `rails_get_turbo_map`",
253
- "- `rails_get_context(model:\"X\")` composite cross-layer context in one call"
269
+ "",
270
+ "| Tool | What it does |",
271
+ "|------|-------------|",
272
+ "| `rails_analyze_feature(feature:\"X\")` | Full-stack: models + controllers (inherited filters) + routes (helpers) + services + jobs + views + tests + gaps |",
273
+ "| `rails_get_context(model:\"X\")` | Composite: schema + model + controller + routes + views in one call |",
274
+ "| `rails_search_code(pattern:\"X\", match_type:\"trace\")` | Trace: definition + class context + source + siblings + callers + test coverage |",
275
+ "| `rails_get_controllers(controller:\"X\", action:\"Y\")` | Action source + inherited filters + render map + side effects + private methods |",
276
+ "| `rails_validate(files:[...], level:\"rails\")` | Syntax + semantic validation + Brakeman security (if installed) |",
277
+ "| `rails_get_schema(table:\"X\")` | Columns with [indexed]/[unique]/[encrypted]/[default] + orphaned table warnings |",
278
+ "| `rails_get_model_details(model:\"X\")` | Associations, validations, scopes (with body), enums (with backing type), macros, delegations |",
279
+ "| `rails_get_routes(controller:\"X\")` | Routes with code-ready helpers (`cook_path(@record)`) and controller filters inline |",
280
+ "| `rails_get_view(controller:\"X\")` | Templates with ivars, Turbo Frame/Stream IDs, Stimulus refs, partial locals |",
281
+ "| `rails_get_design_system` | Canonical HTML/ERB copy-paste patterns for buttons, inputs, cards, modals |",
282
+ "| `rails_get_stimulus(controller:\"X\")` | Targets, values, actions + copy-paste HTML data-attributes + reverse view lookup |",
283
+ "| `rails_get_test_info(model:\"X\")` | Existing tests + fixture contents with relationships + test template |",
284
+ "| `rails_get_concern(name:\"X\", detail:\"full\")` | Concern methods with full source code + which models include it |",
285
+ "| `rails_get_callbacks(model:\"X\")` | Callbacks in Rails execution order with source |",
286
+ "| `rails_get_edit_context(file:\"X\", near:\"Y\")` | Code around a match with class/method context + line numbers |",
287
+ "| `rails_search_code(pattern:\"X\")` | Regex search with smart limiting + `exclude_tests` + `group_by_file` + pagination |",
288
+ "| `rails_get_service_pattern` | Service objects: interface, dependencies, side effects, callers |",
289
+ "| `rails_get_job_pattern` | Jobs: queue, retries, guard clauses, broadcasts, schedules |",
290
+ "| `rails_get_env` | Environment variables + credentials keys (not values) + external services |",
291
+ "| `rails_get_partial_interface(partial:\"X\")` | Partial locals contract: what to pass + usage examples |",
292
+ "| `rails_get_turbo_map` | Turbo Stream/Frame wiring: broadcasts → subscriptions + mismatch warnings |",
293
+ "| `rails_get_helper_methods` | App + framework helper methods with view cross-references |",
294
+ "| `rails_get_config` | Database adapter, auth framework, assets stack, cache, queue, Action Cable |",
295
+ "| `rails_get_gems` | Notable gems with versions, categories, config file locations |",
296
+ "| `rails_get_conventions` | App patterns: auth checks, flash messages, create action template, test patterns |",
297
+ "| `rails_security_scan` | Brakeman static analysis: SQL injection, XSS, mass assignment |"
254
298
  ]
255
299
 
256
300
  lines.join("\n")
@@ -253,44 +253,89 @@ module RailsAiContext
253
253
  end
254
254
 
255
255
  # Always-on MCP tool reference — strongest enforcement point for Cursor
256
- def render_mcp_tools_rule # rubocop:disable Metrics/MethodLength
256
+ def render_mcp_tools_rule # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
257
257
  lines = [
258
258
  "---",
259
259
  "description: \"Rails MCP tools (25) — MANDATORY, use before reading any reference files\"",
260
260
  "alwaysApply: true",
261
261
  "---",
262
262
  "",
263
- "# Rails MCP Tools (25) — MANDATORY, Use Before Read",
263
+ "# Rails MCP Tools — MANDATORY, Use Before Read/Grep",
264
264
  "",
265
- "CRITICAL: This project has live MCP tools. You MUST use them for gathering context.",
266
- "Read files ONLY when you are about to edit them. Never read reference files directly.",
265
+ "This project has 25 live MCP tools. You MUST use them instead of reading files.",
266
+ "Read files ONLY when you are about to Edit them.",
267
267
  "",
268
- "## Mandatory Workflow",
269
- "1. Gathering context → use MCP tools (NOT file reads, NOT grep)",
270
- "2. Reading files → ONLY files you will edit (Read is required before Edit)",
271
- "3. After editing → `rails_validate(files:[...])` every time, no exceptions",
268
+ "## What Are You Trying to Do?",
272
269
  "",
273
- "## Do NOT Bypass — Anti-Patterns",
274
- "| Instead of... | Use this MCP tool |",
275
- "|---------------|-------------------|",
276
- "| Reading db/schema.rb | `rails_get_schema(table:\"name\")` |",
277
- "| Reading config/routes.rb | `rails_get_routes(controller:\"name\")` |",
278
- "| Reading model files for context | `rails_get_model_details(model:\"Name\")` |",
279
- "| Grep for code patterns | `rails_search_code(pattern:\"regex\")` |",
280
- "| Reading test files for patterns | `rails_get_test_info(model:\"Name\")` |",
281
- "| Reading controller for context | `rails_get_controllers(controller:\"Name\", action:\"x\")` |",
282
- "| Reading JS for Stimulus API | `rails_get_stimulus(controller:\"name\")` |",
283
- "| Multiple reads for a feature | `rails_analyze_feature(feature:\"keyword\")` |",
284
- "| ruby -c / erb / node -c | `rails_validate(files:[...])` |",
270
+ "**Understand a feature or area:**",
271
+ " `rails_analyze_feature(feature:\"cook\")` models + controllers + routes + services + jobs + views + tests in one call",
272
+ "→ `rails_get_context(model:\"Cook\")` — schema + model + controller + views assembled together",
273
+ "",
274
+ "**Understand a method (who calls it, what it calls):**",
275
+ " `rails_search_code(pattern:\"can_cook?\", match_type:\"trace\")` — definition + source + siblings + all callers + test coverage",
276
+ "",
277
+ "**Add a field or modify a model:**",
278
+ " `rails_get_schema(table:\"cooks\")` — columns, types, indexes, defaults, encrypted hints",
279
+ " `rails_get_model_details(model:\"Cook\")` — associations, validations, scopes, enums, callbacks, macros",
280
+ "",
281
+ "**Fix a controller bug:**",
282
+ "→ `rails_get_controllers(controller:\"CooksController\", action:\"create\")` — source + inherited filters + render map + side effects + private methods",
283
+ "",
284
+ "**Build or modify a view:**",
285
+ "→ `rails_get_design_system(detail:\"standard\")` — canonical HTML/ERB patterns to copy",
286
+ "→ `rails_get_view(controller:\"cooks\")` — templates with ivars, Turbo wiring, Stimulus refs",
287
+ "→ `rails_get_partial_interface(partial:\"shared/status_badge\")` — what locals to pass",
288
+ "",
289
+ "**Write tests:**",
290
+ "→ `rails_get_test_info(detail:\"standard\")` — framework + fixtures + test template to copy",
291
+ "→ `rails_get_test_info(model:\"Cook\")` — existing tests for a model",
292
+ "",
293
+ "**Find code:**",
294
+ "→ `rails_search_code(pattern:\"has_many\")` — regex search with 2 lines of context",
295
+ "→ `rails_search_code(pattern:\"create\", match_type:\"definition\")` — only `def` lines",
296
+ "→ `rails_search_code(pattern:\"can_cook\", match_type:\"call\")` — only call sites",
297
+ "",
298
+ "**After editing (EVERY time):**",
299
+ "→ `rails_validate(files:[\"app/models/cook.rb\", \"app/views/cooks/new.html.erb\"], level:\"rails\")` — syntax + semantics + security",
300
+ "",
301
+ "## Rules",
302
+ "",
303
+ "1. NEVER read db/schema.rb, config/routes.rb, model files, or test files for reference — use the MCP tools above",
304
+ "2. NEVER use Grep or Explore agents for code search — use `rails_search_code`",
305
+ "3. NEVER run `ruby -c`, `erb`, or `node -c` — use `rails_validate`",
306
+ "4. Read files ONLY when you are about to Edit them",
307
+ "5. Start with `detail:\"summary\"` to orient, then drill into specifics",
285
308
  "",
286
309
  "## All 25 Tools",
287
- "- `rails_get_schema` | `rails_get_model_details` | `rails_get_routes` | `rails_get_controllers`",
288
- "- `rails_get_view` | `rails_get_stimulus` | `rails_get_test_info` | `rails_analyze_feature`",
289
- "- `rails_get_design_system` | `rails_get_edit_context` | `rails_validate` | `rails_search_code`",
290
- "- `rails_get_config` | `rails_get_gems` | `rails_get_conventions` | `rails_security_scan`",
291
- "- `rails_get_concern` | `rails_get_callbacks` | `rails_get_helper_methods` | `rails_get_service_pattern`",
292
- "- `rails_get_job_pattern` | `rails_get_env` | `rails_get_partial_interface` | `rails_get_turbo_map`",
293
- "- `rails_get_context(model:\"X\")` composite cross-layer context in one call"
310
+ "",
311
+ "| Tool | What it does |",
312
+ "|------|-------------|",
313
+ "| `rails_analyze_feature(feature:\"X\")` | Full-stack: models + controllers (inherited filters) + routes (helpers) + services + jobs + views + tests + gaps |",
314
+ "| `rails_get_context(model:\"X\")` | Composite: schema + model + controller + routes + views in one call |",
315
+ "| `rails_search_code(pattern:\"X\", match_type:\"trace\")` | Trace: definition + class context + source + siblings + callers + test coverage |",
316
+ "| `rails_get_controllers(controller:\"X\", action:\"Y\")` | Action source + inherited filters + render map + side effects + private methods |",
317
+ "| `rails_validate(files:[...], level:\"rails\")` | Syntax + semantic validation + Brakeman security (if installed) |",
318
+ "| `rails_get_schema(table:\"X\")` | Columns with [indexed]/[unique]/[encrypted]/[default] + orphaned table warnings |",
319
+ "| `rails_get_model_details(model:\"X\")` | Associations, validations, scopes (with body), enums (with backing type), macros, delegations |",
320
+ "| `rails_get_routes(controller:\"X\")` | Routes with code-ready helpers (`cook_path(@record)`) and controller filters inline |",
321
+ "| `rails_get_view(controller:\"X\")` | Templates with ivars, Turbo Frame/Stream IDs, Stimulus refs, partial locals |",
322
+ "| `rails_get_design_system` | Canonical HTML/ERB copy-paste patterns for buttons, inputs, cards, modals |",
323
+ "| `rails_get_stimulus(controller:\"X\")` | Targets, values, actions + copy-paste HTML data-attributes + reverse view lookup |",
324
+ "| `rails_get_test_info(model:\"X\")` | Existing tests + fixture contents with relationships + test template |",
325
+ "| `rails_get_concern(name:\"X\", detail:\"full\")` | Concern methods with full source code + which models include it |",
326
+ "| `rails_get_callbacks(model:\"X\")` | Callbacks in Rails execution order with source |",
327
+ "| `rails_get_edit_context(file:\"X\", near:\"Y\")` | Code around a match with class/method context + line numbers |",
328
+ "| `rails_search_code(pattern:\"X\")` | Regex search with smart limiting + `exclude_tests` + `group_by_file` + pagination |",
329
+ "| `rails_get_service_pattern` | Service objects: interface, dependencies, side effects, callers |",
330
+ "| `rails_get_job_pattern` | Jobs: queue, retries, guard clauses, broadcasts, schedules |",
331
+ "| `rails_get_env` | Environment variables + credentials keys (not values) + external services |",
332
+ "| `rails_get_partial_interface(partial:\"X\")` | Partial locals contract: what to pass + usage examples |",
333
+ "| `rails_get_turbo_map` | Turbo Stream/Frame wiring: broadcasts → subscriptions + mismatch warnings |",
334
+ "| `rails_get_helper_methods` | App + framework helper methods with view cross-references |",
335
+ "| `rails_get_config` | Database adapter, auth framework, assets stack, cache, queue, Action Cable |",
336
+ "| `rails_get_gems` | Notable gems with versions, categories, config file locations |",
337
+ "| `rails_get_conventions` | App patterns: auth checks, flash messages, create action template, test patterns |",
338
+ "| `rails_security_scan` | Brakeman static analysis: SQL injection, XSS, mass assignment |"
294
339
  ]
295
340
 
296
341
  lines.join("\n")
@@ -163,41 +163,84 @@ module RailsAiContext
163
163
  render_design_system(context, max_lines: 30)
164
164
  end
165
165
 
166
- def render_mcp_guide # rubocop:disable Metrics/MethodLength
166
+ def render_mcp_guide # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
167
167
  [
168
- "## MCP Tools (25) — MANDATORY, Use Before Read",
168
+ "## MCP Tools (25) — MANDATORY, Use Before Read/Grep",
169
169
  "",
170
- "CRITICAL: This project has live MCP tools. You MUST use them for gathering context.",
171
- "Read files ONLY when you are about to edit them. Never read reference files directly.",
172
- "Start with `detail:\"summary\"`, then drill into specifics.",
170
+ "This project has 25 live MCP tools. You MUST use them instead of reading files.",
171
+ "Read files ONLY when you are about to Edit them.",
173
172
  "",
174
- "### Mandatory Workflow",
175
- "1. **Before exploring a feature**: `rails_analyze_feature(feature:\"...\")` — NOT file reads or grep",
176
- "2. **Before writing migrations**: `rails_get_schema(table:\"...\")` — NOT reading db/schema.rb",
177
- "3. **Before modifying a model**: `rails_get_model_details(model:\"...\")` — NOT reading the model file",
178
- "4. **Before adding routes**: `rails_get_routes(controller:\"...\")` — Read only when you will edit",
179
- "5. **Before creating views**: `rails_get_design_system` — match existing patterns",
180
- "6. **After editing ANY file**: `rails_validate(files:[...])` — no exceptions",
173
+ "### What Are You Trying to Do?",
181
174
  "",
182
- "### Do NOT Bypass",
183
- "| Instead of... | Use this MCP tool |",
184
- "|---------------|-------------------|",
185
- "| Reading db/schema.rb | `rails_get_schema(table:\"x\")` |",
186
- "| Reading model files | `rails_get_model_details(model:\"X\")` |",
187
- "| Reading routes.rb | `rails_get_routes(controller:\"x\")` |",
188
- "| Grep for code | `rails_search_code(pattern:\"x\")` |",
189
- "| Reading test files | `rails_get_test_info(model:\"X\")` |",
190
- "| Reading controller | `rails_get_controllers(controller:\"X\", action:\"y\")` |",
191
- "| ruby -c / erb / node | `rails_validate(files:[...])` |",
175
+ "**Understand a feature or area:**",
176
+ " `rails_analyze_feature(feature:\"cook\")` models + controllers + routes + services + jobs + views + tests in one call",
177
+ "→ `rails_get_context(model:\"Cook\")` — schema + model + controller + views assembled together",
178
+ "",
179
+ "**Understand a method (who calls it, what it calls):**",
180
+ " `rails_search_code(pattern:\"can_cook?\", match_type:\"trace\")` — definition + source + siblings + all callers + test coverage",
181
+ "",
182
+ "**Add a field or modify a model:**",
183
+ " `rails_get_schema(table:\"cooks\")` — columns, types, indexes, defaults, encrypted hints",
184
+ " `rails_get_model_details(model:\"Cook\")` associations, validations, scopes, enums, callbacks, macros",
185
+ "",
186
+ "**Fix a controller bug:**",
187
+ "→ `rails_get_controllers(controller:\"CooksController\", action:\"create\")` — source + inherited filters + render map + side effects + private methods",
188
+ "",
189
+ "**Build or modify a view:**",
190
+ "→ `rails_get_design_system(detail:\"standard\")` — canonical HTML/ERB patterns to copy",
191
+ "→ `rails_get_view(controller:\"cooks\")` — templates with ivars, Turbo wiring, Stimulus refs",
192
+ "→ `rails_get_partial_interface(partial:\"shared/status_badge\")` — what locals to pass",
193
+ "",
194
+ "**Write tests:**",
195
+ "→ `rails_get_test_info(detail:\"standard\")` — framework + fixtures + test template to copy",
196
+ "→ `rails_get_test_info(model:\"Cook\")` — existing tests for a model",
197
+ "",
198
+ "**Find code:**",
199
+ "→ `rails_search_code(pattern:\"has_many\")` — regex search with 2 lines of context",
200
+ "→ `rails_search_code(pattern:\"create\", match_type:\"definition\")` — only `def` lines",
201
+ "→ `rails_search_code(pattern:\"can_cook\", match_type:\"call\")` — only call sites",
202
+ "",
203
+ "**After editing (EVERY time):**",
204
+ "→ `rails_validate(files:[\"app/models/cook.rb\", \"app/views/cooks/new.html.erb\"], level:\"rails\")` — syntax + semantics + security",
205
+ "",
206
+ "### Rules",
207
+ "",
208
+ "1. NEVER read db/schema.rb, config/routes.rb, model files, or test files for reference — use the MCP tools above",
209
+ "2. NEVER use Grep or Explore agents for code search — use `rails_search_code`",
210
+ "3. NEVER run `ruby -c`, `erb`, or `node -c` — use `rails_validate`",
211
+ "4. Read files ONLY when you are about to Edit them",
212
+ "5. Start with `detail:\"summary\"` to orient, then drill into specifics",
192
213
  "",
193
214
  "### All 25 Tools",
194
- "- `rails_get_schema` | `rails_get_model_details` | `rails_get_routes` | `rails_get_controllers`",
195
- "- `rails_get_view` | `rails_get_stimulus` | `rails_get_test_info` | `rails_analyze_feature`",
196
- "- `rails_get_design_system` | `rails_get_edit_context` | `rails_validate` | `rails_search_code`",
197
- "- `rails_get_config` | `rails_get_gems` | `rails_get_conventions` | `rails_security_scan`",
198
- "- `rails_get_concern` | `rails_get_callbacks` | `rails_get_helper_methods` | `rails_get_service_pattern`",
199
- "- `rails_get_job_pattern` | `rails_get_env` | `rails_get_partial_interface` | `rails_get_turbo_map`",
200
- "- `rails_get_context(model:\"X\")` composite cross-layer context in one call",
215
+ "",
216
+ "| Tool | What it does |",
217
+ "|------|-------------|",
218
+ "| `rails_analyze_feature(feature:\"X\")` | Full-stack: models + controllers (inherited filters) + routes (helpers) + services + jobs + views + tests + gaps |",
219
+ "| `rails_get_context(model:\"X\")` | Composite: schema + model + controller + routes + views in one call |",
220
+ "| `rails_search_code(pattern:\"X\", match_type:\"trace\")` | Trace: definition + class context + source + siblings + callers + test coverage |",
221
+ "| `rails_get_controllers(controller:\"X\", action:\"Y\")` | Action source + inherited filters + render map + side effects + private methods |",
222
+ "| `rails_validate(files:[...], level:\"rails\")` | Syntax + semantic validation + Brakeman security (if installed) |",
223
+ "| `rails_get_schema(table:\"X\")` | Columns with [indexed]/[unique]/[encrypted]/[default] + orphaned table warnings |",
224
+ "| `rails_get_model_details(model:\"X\")` | Associations, validations, scopes (with body), enums (with backing type), macros, delegations |",
225
+ "| `rails_get_routes(controller:\"X\")` | Routes with code-ready helpers (`cook_path(@record)`) and controller filters inline |",
226
+ "| `rails_get_view(controller:\"X\")` | Templates with ivars, Turbo Frame/Stream IDs, Stimulus refs, partial locals |",
227
+ "| `rails_get_design_system` | Canonical HTML/ERB copy-paste patterns for buttons, inputs, cards, modals |",
228
+ "| `rails_get_stimulus(controller:\"X\")` | Targets, values, actions + copy-paste HTML data-attributes + reverse view lookup |",
229
+ "| `rails_get_test_info(model:\"X\")` | Existing tests + fixture contents with relationships + test template |",
230
+ "| `rails_get_concern(name:\"X\", detail:\"full\")` | Concern methods with full source code + which models include it |",
231
+ "| `rails_get_callbacks(model:\"X\")` | Callbacks in Rails execution order with source |",
232
+ "| `rails_get_edit_context(file:\"X\", near:\"Y\")` | Code around a match with class/method context + line numbers |",
233
+ "| `rails_search_code(pattern:\"X\")` | Regex search with smart limiting + `exclude_tests` + `group_by_file` + pagination |",
234
+ "| `rails_get_service_pattern` | Service objects: interface, dependencies, side effects, callers |",
235
+ "| `rails_get_job_pattern` | Jobs: queue, retries, guard clauses, broadcasts, schedules |",
236
+ "| `rails_get_env` | Environment variables + credentials keys (not values) + external services |",
237
+ "| `rails_get_partial_interface(partial:\"X\")` | Partial locals contract: what to pass + usage examples |",
238
+ "| `rails_get_turbo_map` | Turbo Stream/Frame wiring: broadcasts → subscriptions + mismatch warnings |",
239
+ "| `rails_get_helper_methods` | App + framework helper methods with view cross-references |",
240
+ "| `rails_get_config` | Database adapter, auth framework, assets stack, cache, queue, Action Cable |",
241
+ "| `rails_get_gems` | Notable gems with versions, categories, config file locations |",
242
+ "| `rails_get_conventions` | App patterns: auth checks, flash messages, create action template, test patterns |",
243
+ "| `rails_security_scan` | Brakeman static analysis: SQL injection, XSS, mass assignment |",
201
244
  ""
202
245
  ]
203
246
  end
@@ -65,37 +65,80 @@ module RailsAiContext
65
65
  lines.join("\n")
66
66
  end
67
67
 
68
- def render_mcp_tools_rule # rubocop:disable Metrics/MethodLength
68
+ def render_mcp_tools_rule # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
69
69
  lines = [
70
- "# Rails MCP Tools (25) — MANDATORY, Use Before Read",
70
+ "# Rails MCP Tools — MANDATORY, Use Before Read/Grep",
71
71
  "",
72
- "CRITICAL: This project has live MCP tools. Use them for ALL context gathering.",
73
- "Read files ONLY when you are about to edit them.",
72
+ "This project has 25 live MCP tools. You MUST use them instead of reading files.",
73
+ "Read files ONLY when you are about to Edit them.",
74
74
  "",
75
- "Mandatory Workflow:",
76
- "1. Gathering context → use MCP tools (NOT file reads)",
77
- "2. Reading files → ONLY files you will edit",
78
- "3. After editing → rails_validate(files:[...]) every time",
75
+ "What Are You Trying to Do?",
79
76
  "",
80
- "Do NOT Bypass:",
81
- "- Reading db/schema.rb → rails_get_schema(table:\"name\")",
82
- "- Reading config/routes.rb → rails_get_routes(controller:\"name\")",
83
- "- Reading model files → rails_get_model_details(model:\"Name\")",
84
- "- Grep for code rails_search_code(pattern:\"regex\")",
85
- "- Reading test files → rails_get_test_info(model:\"Name\")",
86
- "- Reading controller → rails_get_controllers(controller:\"Name\", action:\"x\")",
87
- "- Reading JS for Stimulus rails_get_stimulus(controller:\"name\")",
88
- "- Multiple reads for feature rails_analyze_feature(feature:\"keyword\")",
89
- "- ruby -c / erb / node -c → rails_validate(files:[...])",
77
+ "Understand a feature or area:",
78
+ " rails_analyze_feature(feature:\"cook\") — models + controllers + routes + services + jobs + views + tests in one call",
79
+ " rails_get_context(model:\"Cook\") — schema + model + controller + views assembled together",
80
+ "",
81
+ "Understand a method (who calls it, what it calls):",
82
+ " rails_search_code(pattern:\"can_cook?\", match_type:\"trace\") — definition + source + siblings + all callers + test coverage",
83
+ "",
84
+ "Add a field or modify a model:",
85
+ " rails_get_schema(table:\"cooks\") columns, types, indexes, defaults, encrypted hints",
86
+ " rails_get_model_details(model:\"Cook\") associations, validations, scopes, enums, callbacks, macros",
87
+ "",
88
+ "Fix a controller bug:",
89
+ " rails_get_controllers(controller:\"CooksController\", action:\"create\") — source + inherited filters + render map + side effects + private methods",
90
+ "",
91
+ "Build or modify a view:",
92
+ " rails_get_design_system(detail:\"standard\") — canonical HTML/ERB patterns to copy",
93
+ " rails_get_view(controller:\"cooks\") — templates with ivars, Turbo wiring, Stimulus refs",
94
+ " rails_get_partial_interface(partial:\"shared/status_badge\") — what locals to pass",
95
+ "",
96
+ "Write tests:",
97
+ " rails_get_test_info(detail:\"standard\") — framework + fixtures + test template to copy",
98
+ " rails_get_test_info(model:\"Cook\") — existing tests for a model",
99
+ "",
100
+ "Find code:",
101
+ " rails_search_code(pattern:\"has_many\") — regex search with 2 lines of context",
102
+ " rails_search_code(pattern:\"create\", match_type:\"definition\") — only def lines",
103
+ " rails_search_code(pattern:\"can_cook\", match_type:\"call\") — only call sites",
104
+ "",
105
+ "After editing (EVERY time):",
106
+ " rails_validate(files:[\"app/models/cook.rb\", \"app/views/cooks/new.html.erb\"], level:\"rails\") — syntax + semantics + security",
107
+ "",
108
+ "Rules:",
109
+ "1. NEVER read db/schema.rb, config/routes.rb, model files, or test files for reference — use the MCP tools above",
110
+ "2. NEVER use Grep for code search — use rails_search_code",
111
+ "3. NEVER run ruby -c, erb, or node -c — use rails_validate",
112
+ "4. Read files ONLY when you are about to Edit them",
113
+ "5. Start with detail:\"summary\" to orient, then drill into specifics",
90
114
  "",
91
115
  "All 25 Tools:",
92
- "- rails_get_schema | rails_get_model_details | rails_get_routes | rails_get_controllers",
93
- "- rails_get_view | rails_get_stimulus | rails_get_test_info | rails_analyze_feature",
94
- "- rails_get_design_system | rails_get_edit_context | rails_validate | rails_search_code",
95
- "- rails_get_config | rails_get_gems | rails_get_conventions | rails_security_scan",
96
- "- rails_get_concern | rails_get_callbacks | rails_get_helper_methods | rails_get_service_pattern",
97
- "- rails_get_job_pattern | rails_get_env | rails_get_partial_interface | rails_get_turbo_map",
98
- "- rails_get_context(model:\"X\") — composite cross-layer context in one call"
116
+ "rails_analyze_feature(feature:\"X\") — Full-stack: models + controllers + routes + services + jobs + views + tests + gaps",
117
+ "rails_get_context(model:\"X\") Composite: schema + model + controller + routes + views in one call",
118
+ "rails_search_code(pattern:\"X\", match_type:\"trace\") Trace: definition + source + siblings + callers + test coverage",
119
+ "rails_get_controllers(controller:\"X\", action:\"Y\") Action source + inherited filters + render map + side effects",
120
+ "rails_validate(files:[...], level:\"rails\") Syntax + semantic validation + Brakeman security",
121
+ "rails_get_schema(table:\"X\") Columns with indexed/unique/encrypted/default + orphaned table warnings",
122
+ "rails_get_model_details(model:\"X\") — Associations, validations, scopes, enums, macros, delegations",
123
+ "rails_get_routes(controller:\"X\") — Routes with code-ready helpers and controller filters inline",
124
+ "rails_get_view(controller:\"X\") — Templates with ivars, Turbo Frame/Stream IDs, Stimulus refs, partial locals",
125
+ "rails_get_design_system — Canonical HTML/ERB copy-paste patterns for buttons, inputs, cards, modals",
126
+ "rails_get_stimulus(controller:\"X\") — Targets, values, actions + copy-paste HTML data-attributes",
127
+ "rails_get_test_info(model:\"X\") — Existing tests + fixture contents + test template",
128
+ "rails_get_concern(name:\"X\", detail:\"full\") — Concern methods with full source code + includers",
129
+ "rails_get_callbacks(model:\"X\") — Callbacks in Rails execution order with source",
130
+ "rails_get_edit_context(file:\"X\", near:\"Y\") — Code around a match with class/method context + line numbers",
131
+ "rails_search_code(pattern:\"X\") — Regex search with smart limiting + exclude_tests + group_by_file",
132
+ "rails_get_service_pattern — Service objects: interface, dependencies, side effects, callers",
133
+ "rails_get_job_pattern — Jobs: queue, retries, guard clauses, broadcasts, schedules",
134
+ "rails_get_env — Environment variables + credentials keys (not values) + external services",
135
+ "rails_get_partial_interface(partial:\"X\") — Partial locals contract: what to pass + usage examples",
136
+ "rails_get_turbo_map — Turbo Stream/Frame wiring: broadcasts to subscriptions + mismatch warnings",
137
+ "rails_get_helper_methods — App + framework helper methods with view cross-references",
138
+ "rails_get_config — Database adapter, auth framework, assets stack, cache, queue, Action Cable",
139
+ "rails_get_gems — Notable gems with versions, categories, config file locations",
140
+ "rails_get_conventions — App patterns: auth checks, flash messages, create action template, test patterns",
141
+ "rails_security_scan — Brakeman static analysis: SQL injection, XSS, mass assignment"
99
142
  ]
100
143
 
101
144
  lines.join("\n")
@@ -114,11 +114,17 @@ module RailsAiContext
114
114
  actions = info[:actions]&.join(", ") || "none"
115
115
  lines << "" << "### #{name}"
116
116
  lines << "- **Actions:** #{actions}"
117
+
118
+ # Inherited filters from parent controller
119
+ parent_filters = detect_parent_filters_for_analyze(info[:parent_class], controllers)
120
+ if parent_filters.any?
121
+ lines << "- **Inherited filters:** #{parent_filters.map { |f| "#{f[:name]} _(from #{info[:parent_class]})_" }.join(', ')}"
122
+ end
123
+
117
124
  filters = (info[:filters] || []).select { |f| f.is_a?(Hash) }.map do |f|
118
125
  label = "#{f[:kind]} #{f[:name]}"
119
126
  label += " only: #{Array(f[:only]).join(', ')}" if f[:only]&.any?
120
127
  label += " except: #{Array(f[:except]).join(', ')}" if f[:except]&.any?
121
- label += " unless: #{f[:unless]}" if f[:unless]
122
128
  label
123
129
  end
124
130
  lines << "- **Filters:** #{filters.join('; ')}" if filters.any?
@@ -139,8 +145,14 @@ module RailsAiContext
139
145
  lines << "## Routes (#{route_count})"
140
146
  matched.sort.each do |ctrl, actions|
141
147
  actions.each do |r|
142
- name_part = r[:name] ? " `#{r[:name]}`" : ""
143
- lines << "- `#{r[:verb]}` `#{r[:path]}` → #{ctrl}##{r[:action]}#{name_part}"
148
+ params = r[:path].scan(/:(\w+)/).flatten
149
+ helper = if r[:name]
150
+ args = params.any? ? "(#{params.map { |p| p == "id" ? "@record" : ":#{p}" }.join(', ')})" : ""
151
+ " `#{r[:name]}_path#{args}`"
152
+ else
153
+ ""
154
+ end
155
+ lines << "- `#{r[:verb]}` `#{r[:path]}` → #{ctrl}##{r[:action]}#{helper}"
144
156
  end
145
157
  end
146
158
  else
@@ -321,6 +333,18 @@ module RailsAiContext
321
333
  end
322
334
  end
323
335
 
336
+ # Check services
337
+ service_dir = File.join(root, "app", "services")
338
+ if Dir.exist?(service_dir)
339
+ Dir.glob(File.join(service_dir, "**", "*.rb")).each do |path|
340
+ next unless File.basename(path, ".rb").include?(pattern)
341
+ snake = File.basename(path, ".rb")
342
+ unless test_basenames.any? { |t| t.include?(snake) }
343
+ gaps << "Service `#{snake}` — no test file found"
344
+ end
345
+ end
346
+ end
347
+
324
348
  return if gaps.empty?
325
349
 
326
350
  lines << "## Test Coverage Gaps"
@@ -330,6 +354,28 @@ module RailsAiContext
330
354
  nil
331
355
  end
332
356
 
357
+ # Detect inherited filters from parent controller
358
+ def detect_parent_filters_for_analyze(parent_class, all_controllers)
359
+ return [] unless parent_class
360
+ parent_data = all_controllers[parent_class]
361
+ if parent_data
362
+ return (parent_data[:filters] || []).select { |f| f.is_a?(Hash) && f[:kind] == "before" && !f[:only]&.any? }
363
+ end
364
+
365
+ # Fallback: read source file
366
+ path = Rails.root.join("app", "controllers", "#{parent_class.underscore}.rb")
367
+ return [] unless File.exist?(path)
368
+ source = File.read(path, encoding: "UTF-8") rescue nil
369
+ return [] unless source
370
+
371
+ source.each_line.filter_map do |line|
372
+ next if line.include?("only:") || line.include?("except:")
373
+ { name: $1 } if line.match(/\A\s*before_action\s+:(\w+)/)
374
+ end
375
+ rescue
376
+ []
377
+ end
378
+
333
379
  # --- AF6: Related Models via Associations ---
334
380
  def discover_related_models(ctx, matched_models, lines)
335
381
  return if matched_models.empty?
@@ -18,13 +18,18 @@ module RailsAiContext
18
18
  type: "string",
19
19
  enum: %w[model controller all],
20
20
  description: "Filter by concern type. model: app/models/concerns/. controller: app/controllers/concerns/. all: both (default)."
21
+ },
22
+ detail: {
23
+ type: "string",
24
+ enum: %w[summary standard full],
25
+ description: "Detail level. summary: concern names only. standard: names + method signatures (default). full: method signatures with source code."
21
26
  }
22
27
  }
23
28
  )
24
29
 
25
30
  annotations(read_only_hint: true, destructive_hint: false, idempotent_hint: true, open_world_hint: false)
26
31
 
27
- def self.call(name: nil, type: "all", server_context: nil)
32
+ def self.call(name: nil, type: "all", detail: "standard", server_context: nil)
28
33
  root = rails_app.root.to_s
29
34
  max_size = RailsAiContext.configuration.max_file_size
30
35
 
@@ -36,7 +41,7 @@ module RailsAiContext
36
41
 
37
42
  # Specific concern — full detail
38
43
  if name
39
- return show_concern(name, concern_dirs, root, max_size)
44
+ return show_concern(name, concern_dirs, root, max_size, detail)
40
45
  end
41
46
 
42
47
  # List all concerns
@@ -67,7 +72,7 @@ module RailsAiContext
67
72
  end
68
73
  end
69
74
 
70
- private_class_method def self.show_concern(name, concern_dirs, root, max_size)
75
+ private_class_method def self.show_concern(name, concern_dirs, root, max_size, detail = "standard")
71
76
  # Find the concern file — try underscore variants and nested paths
72
77
  underscore = name.underscore
73
78
  file_path = nil
@@ -121,14 +126,47 @@ module RailsAiContext
121
126
  public_methods = parse_public_methods(source)
122
127
  if public_methods.any?
123
128
  lines << "" << "## Public Methods"
124
- public_methods.each { |m| lines << "- `#{m}`" }
129
+ if detail == "full"
130
+ public_methods.each do |m|
131
+ method_name = m.to_s.split("(").first
132
+ method_source = extract_method_source(source, method_name)
133
+ if method_source
134
+ lines << "### #{m}"
135
+ lines << "```ruby"
136
+ lines << method_source
137
+ lines << "```"
138
+ lines << ""
139
+ else
140
+ lines << "- `#{m}`"
141
+ end
142
+ end
143
+ else
144
+ public_methods.each { |m| lines << "- `#{m}`" }
145
+ end
125
146
  end
126
147
 
127
148
  # Parse class methods (inside class_methods block or def self.)
128
149
  class_methods = parse_class_methods(source)
129
150
  if class_methods.any?
130
151
  lines << "" << "## Class Methods"
131
- class_methods.each { |m| lines << "- `#{m}`" }
152
+ if detail == "full"
153
+ class_methods.each do |m|
154
+ method_name = m.to_s.split("(").first
155
+ # Try both `def method_name` and `def self.method_name`
156
+ method_source = extract_method_source(source, method_name) || extract_method_source(source, "self.#{method_name}")
157
+ if method_source
158
+ lines << "### #{m}"
159
+ lines << "```ruby"
160
+ lines << method_source
161
+ lines << "```"
162
+ lines << ""
163
+ else
164
+ lines << "- `#{m}`"
165
+ end
166
+ end
167
+ else
168
+ class_methods.each { |m| lines << "- `#{m}`" }
169
+ end
132
170
  end
133
171
 
134
172
  # Parse callbacks defined in the concern
@@ -345,6 +383,32 @@ module RailsAiContext
345
383
  []
346
384
  end
347
385
 
386
+ # Extract method source from raw source string using indentation-based matching
387
+ private_class_method def self.extract_method_source(source, method_name)
388
+ source_lines = source.lines
389
+ escaped = Regexp.escape(method_name.to_s)
390
+ # Don't use \b after ? or ! — they ARE word boundaries
391
+ pattern = if method_name.to_s.end_with?("?") || method_name.to_s.end_with?("!")
392
+ /\A\s*def\s+#{escaped}/
393
+ else
394
+ /\A\s*def\s+#{escaped}\b/
395
+ end
396
+ start_idx = source_lines.index { |l| l.match?(pattern) }
397
+ return nil unless start_idx
398
+
399
+ def_indent = source_lines[start_idx][/\A\s*/].length
400
+ result = []
401
+
402
+ source_lines[start_idx..].each_with_index do |line, i|
403
+ result << line.rstrip
404
+ break if i > 0 && line.match?(/\A\s{#{def_indent}}end\b/)
405
+ end
406
+
407
+ result.join("\n")
408
+ rescue
409
+ nil
410
+ end
411
+
348
412
  private_class_method def self.find_includers(concern_name, root, concern_type)
349
413
  includers = []
350
414
  search_dirs = []
@@ -160,6 +160,14 @@ module RailsAiContext
160
160
  lines << cols
161
161
  lines << ""
162
162
  end
163
+
164
+ # Detect orphaned tables (no ActiveRecord model maps to them)
165
+ orphaned = paginated.select { |name| models_for_table(name).empty? }
166
+ if orphaned.any?
167
+ lines << "\u26A0 **Orphaned tables** (no ActiveRecord model): #{orphaned.join(', ')}"
168
+ lines << ""
169
+ end
170
+
163
171
  lines << "_Use `detail:\"summary\"` for all #{total} tables, `detail:\"full\"` for indexes/FKs, or `table:\"name\"` for one table._" if total > limit
164
172
  text_response(lines.join("\n"))
165
173
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsAiContext
4
- VERSION = "2.0.3"
4
+ VERSION = "2.0.5"
5
5
  end
data/server.json CHANGED
@@ -7,11 +7,11 @@
7
7
  "url": "https://github.com/crisnahine/rails-ai-context",
8
8
  "source": "github"
9
9
  },
10
- "version": "2.0.3",
10
+ "version": "2.0.5",
11
11
  "packages": [
12
12
  {
13
13
  "registryType": "mcpb",
14
- "identifier": "https://github.com/crisnahine/rails-ai-context/releases/download/v2.0.3/rails-ai-context-mcp.mcpb",
14
+ "identifier": "https://github.com/crisnahine/rails-ai-context/releases/download/v2.0.5/rails-ai-context-mcp.mcpb",
15
15
  "fileSha256": "dd711a0ad6c4de943ae4da94eaf59a6dc9494b9d57f726e24649ed4e2f156990",
16
16
  "transport": {
17
17
  "type": "stdio"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-ai-context
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.3
4
+ version: 2.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - crisnahine