rails-ai-context 2.0.4 → 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: 70a0eb825c34329a1f0bc9d387a4a2bfd2a42b56717305dcaa5df4c0712264f7
4
- data.tar.gz: 5a2e229f4bbcaf39d9eebe3e3851444ceed0860b79ad4bcccf11fdba9487ac0a
3
+ metadata.gz: e17feb99495b6f8328eedaa95020ca097aa4ee7df658ed0a51a925cd6961cdee
4
+ data.tar.gz: 8b5dc406788cc2af104813e0711887bfc6a5ef0e97ddc79464291b0da74ad7df
5
5
  SHA512:
6
- metadata.gz: eca131443eb443b24a7681233f5e5adcef9a2c2fb3f4ee6d4e665c795470bed1e0bfdfa92f4f4861136f3e7c2b34210972273b2d0b976f3ffb7fa88834ed31b7
7
- data.tar.gz: b2e96f95e25b8e9cf9fb140446969fc7a027ff22e210321c3ade42da59aa7c6ed702ceabc0c8be62e8a56c2fa25230dcb460bfd3182716c3a1ef1cc300b836bb
6
+ metadata.gz: a8b7ff36197da72c8b1d3ca1c7199da2333015fda502a37c83d819a95394732449b2d26f20084a14687b59c6fcde10445dda5fbf4705890793ae213bda2cba33
7
+ data.tar.gz: 22e5d0ae93d2af2c01f383197a10e454667f0d24af0bb463a191922913702d3c976f04fb918e7716833af874ee1913d86182d234e36c65bb568469a8ead8f116
data/CHANGELOG.md CHANGED
@@ -5,6 +5,13 @@ 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
+
8
15
  ## [2.0.4] - 2026-03-25
9
16
 
10
17
  ### Added
@@ -297,134 +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, orphaned table detection",
348
- "- `rails_get_schema(detail:\"summary\")` all tables with column counts + orphaned tables (tables with no ActiveRecord model)",
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, including inherited filters from parent controllers and code-ready route helpers",
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 with trace mode for deep call-chain analysis",
394
- "- `rails_search_code(pattern:\"regex\", file_type:\"rb\")` — basic regex search across files",
395
- "- `rails_search_code(pattern:\"can_cook?\", match_type:\"trace\")` — trace mode: definition + class context + source + siblings + callers with route chain + test coverage",
396
- "- `rails_search_code(pattern:\"cook\", exclude_tests: true)` — search app code only, skip test files",
397
- "",
398
- "**rails_security_scan** — Brakeman security analysis",
399
- "- `rails_security_scan` — run security scan, returns warnings by confidence",
400
- "",
401
- "**rails_get_concern** — concern methods and includers",
402
- "- `rails_get_concern(name:\"Searchable\")` — methods, included modules, includers",
403
- "- `rails_get_concern(name:\"Searchable\", detail:\"full\")` — + method source code",
404
- "",
405
- "**rails_get_callbacks** — model callbacks in execution order",
406
- "- `rails_get_callbacks(model:\"User\")` — before/after/around callbacks by type",
407
- "",
408
- "**rails_get_helper_methods** — app + framework helpers",
409
- "- `rails_get_helper_methods` — all helper methods across app and framework",
410
- "",
411
- "**rails_get_service_pattern** — service object patterns and interfaces",
412
- "- `rails_get_service_pattern` — service objects with call signatures and dependencies",
413
- "",
414
- "**rails_get_job_pattern** — background job patterns and schedules",
415
- "- `rails_get_job_pattern` — job classes, queues, retry policies, schedules",
416
- "",
417
- "**rails_get_env** — environment variables and credentials keys",
418
- "- `rails_get_env` — ENV vars referenced in code + credentials structure",
419
- "",
420
- "**rails_get_partial_interface** — partial locals contract",
421
- "- `rails_get_partial_interface(path:\"shared/_form\")` — required/optional locals for a partial",
422
- "",
423
- "**rails_get_turbo_map** — Turbo Streams/Frames wiring",
424
- "- `rails_get_turbo_map` — Turbo Frame IDs, Stream channels, broadcast sources",
425
- "",
426
- "**rails_get_context** — composite cross-layer context",
427
- "- `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 |"
428
374
  ]
429
375
 
430
376
  lines.join("\n")
@@ -196,43 +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\")` — includes orphaned table warnings | 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\")` — models + controllers (inherited filters) + routes (code-ready helpers) + services + jobs + views + tests + gaps | Explore agent / Grep |",
221
- "| Find code | `rails_search_code(pattern:\"x\", match_type:\"trace\")` | 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\", detail:\"full\")` — concern methods with source code | `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_search_code(pattern:\"method\", match_type:\"trace\")` — **trace mode**: definition + class context + source + siblings + callers + test coverage in one call",
235
- "- `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 |",
236
277
  ""
237
278
  ]
238
279
  end
@@ -267,18 +308,8 @@ module RailsAiContext
267
308
  "- Follow existing patterns and conventions",
268
309
  "- Match existing code style",
269
310
  "- Run tests after changes",
270
- "- After editing, ALWAYS use `rails_validate(files:[...])` — do NOT use separate ruby -c / erb / node -c calls",
271
311
  "- Do NOT re-read files to verify edits — trust your Edit, validate syntax only",
272
312
  "- Stimulus controllers auto-register — no manual import in controllers/index.js needed",
273
- "",
274
- "## MCP-First Rule — Do NOT Bypass",
275
- "- Do NOT read db/schema.rb — use `rails_get_schema`",
276
- "- Do NOT read config/routes.rb for reference — use `rails_get_routes`",
277
- "- Do NOT read model files for associations/scopes — use `rails_get_model_details`",
278
- "- Do NOT use Grep to search code — use `rails_search_code`",
279
- "- Do NOT launch Explore agents for context — use `rails_analyze_feature`",
280
- "- Do NOT read test files for patterns — use `rails_get_test_info`",
281
- "- Read files ONLY when you are about to Edit them",
282
313
  ""
283
314
  ]
284
315
  end
@@ -213,50 +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",
254
269
  "",
255
- "## Power Features",
256
- "- `rails_search_code(pattern:\"method\", match_type:\"trace\")` — trace: definition + source + siblings + callers + tests",
257
- "- `rails_get_concern(name:\"X\", detail:\"full\")` concern methods with source code",
258
- "- `rails_analyze_feature` full-stack with inherited filters, route helpers, test gaps",
259
- "- `rails_get_schema` columns, indexes, defaults, encrypted hints, orphaned table warnings"
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 |"
260
298
  ]
261
299
 
262
300
  lines.join("\n")
@@ -253,50 +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",
294
310
  "",
295
- "## Power Features",
296
- "- `rails_search_code(pattern:\"method\", match_type:\"trace\")` — trace: definition + source + siblings + callers + tests",
297
- "- `rails_get_concern(name:\"X\", detail:\"full\")` concern methods with source code",
298
- "- `rails_analyze_feature` full-stack with inherited filters, route helpers, test gaps",
299
- "- `rails_get_schema` columns, indexes, defaults, encrypted hints, orphaned table warnings"
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 |"
300
339
  ]
301
340
 
302
341
  lines.join("\n")
@@ -163,42 +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:\"...\")` — models + controllers (inherited filters) + routes (code-ready helpers) + services + jobs + views + tests + gaps",
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\")` — includes orphaned table warnings |",
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\", match_type:\"trace\")` |",
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(name:\"X\", detail:\"full\")` concern methods with source code | `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_search_code(pattern:\"method\", match_type:\"trace\")` **trace mode**: definition + class context + source + siblings + callers + test coverage in one call",
201
- "- `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 |",
202
244
  ""
203
245
  ]
204
246
  end
@@ -65,43 +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",
90
80
  "",
91
- "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",
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
99
  "",
100
- "Power Features:",
101
- "- rails_search_code(pattern:\"method\", match_type:\"trace\") — trace: definition + source + siblings + callers + tests",
102
- "- rails_get_concern(name:\"X\", detail:\"full\") — concern methods with source code",
103
- "- rails_analyze_featurefull-stack with inherited filters, route helpers, test gaps",
104
- "- rails_get_schema — columns, indexes, defaults, encrypted hints, orphaned table warnings"
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",
114
+ "",
115
+ "All 25 Tools:",
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"
105
142
  ]
106
143
 
107
144
  lines.join("\n")
@@ -386,7 +386,14 @@ module RailsAiContext
386
386
  # Extract method source from raw source string using indentation-based matching
387
387
  private_class_method def self.extract_method_source(source, method_name)
388
388
  source_lines = source.lines
389
- start_idx = source_lines.index { |l| l.match?(/\A\s*def\s+#{Regexp.escape(method_name.to_s)}\b/) }
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) }
390
397
  return nil unless start_idx
391
398
 
392
399
  def_indent = source_lines[start_idx][/\A\s*/].length
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsAiContext
4
- VERSION = "2.0.4"
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.4",
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.4/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.4
4
+ version: 2.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - crisnahine