rails-ai-context 4.2.3 → 4.3.0

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.
@@ -24,20 +24,20 @@ module RailsAiContext
24
24
  end
25
25
 
26
26
  def tools_header
27
- "## Tools (33) — MANDATORY, Use Before Read"
27
+ "## Tools (37) — MANDATORY, Use Before Read"
28
28
  end
29
29
 
30
30
  def tools_intro
31
31
  case tool_mode
32
32
  when :cli
33
33
  [
34
- "This project has 33 introspection tools. **MANDATORY — use these instead of reading files.**",
34
+ "This project has 37 introspection tools. **MANDATORY — use these instead of reading files.**",
35
35
  "They return only relevant, structured data and save tokens. Read files ONLY when you are about to Edit them.",
36
36
  ""
37
37
  ]
38
38
  else
39
39
  [
40
- "This project has 33 MCP tools via `rails ai:serve` (configured in `.mcp.json`).",
40
+ "This project has 37 MCP tools via `rails ai:serve` (configured in `.mcp.json`).",
41
41
  "**MANDATORY — use these instead of reading files.** They return structured data and save tokens.",
42
42
  "Read files ONLY when you are about to Edit them.",
43
43
  "If MCP tools are not connected, use CLI fallback: `#{cli_cmd("TOOL_NAME", "param=value")}`",
@@ -46,57 +46,92 @@ module RailsAiContext
46
46
  end
47
47
  end
48
48
 
49
- def tools_task_section # rubocop:disable Metrics/MethodLength
49
+ def tools_detail_guidance
50
+ detail_param = tool_mode == :cli ? "detail=summary" : "detail:\"summary\""
50
51
  [
51
- "### What Are You Trying to Do?",
52
+ "### detail parameter ALWAYS start with summary",
52
53
  "",
53
- "**Understand a feature or area:**",
54
- tool_call("rails_analyze_feature(feature:\"cook\")", cli_cmd("analyze_feature", "feature=cook")),
55
- tool_call("rails_get_context(model:\"Cook\")", cli_cmd("context", "model=Cook")),
56
- tool_call("rails_get_frontend_stack", cli_cmd("frontend_stack")),
54
+ "Most tools accept `#{detail_param}`. Use the right level:",
55
+ "- **summary** — first call, orient yourself (table list, model names, route overview)",
56
+ "- **standard** — working detail (columns with types, associations, action source) — DEFAULT",
57
+ "- **full** — only when you need indexes, foreign keys, code snippets, or complete content",
57
58
  "",
58
- "**Understand a method (who calls it, what it calls):**",
59
- tool_call("rails_search_code(pattern:\"can_cook?\", match_type:\"trace\")", cli_cmd("search_code", "pattern=\"can_cook?\" match_type=trace")),
59
+ "Pattern: summary to find the target standard to understand it → full only if needed.",
60
+ ""
61
+ ]
62
+ end
63
+
64
+ def tools_power_tool_section
65
+ [
66
+ "### Start here — composite tools save multiple calls",
60
67
  "",
61
- "**Add a field or modify a model:**",
62
- tool_call("rails_get_schema(table:\"cooks\")", cli_cmd("schema", "table=cooks")),
63
- tool_call("rails_get_model_details(model:\"Cook\")", cli_cmd("model_details", "model=Cook")),
64
- tool_call("rails_migration_advisor(action:\"add_column\", table:\"cooks\", column:\"rating\", type:\"integer\")", cli_cmd("migration_advisor", "action=add_column table=cooks column=rating type=integer")),
68
+ "**New to this project?** Get a full walkthrough first:",
69
+ tool_call("rails_onboard(detail:\"standard\")", cli_cmd("onboard", "detail=standard")),
65
70
  "",
66
- "**Fix a controller bug:**",
67
- tool_call("rails_get_controllers(controller:\"CooksController\", action:\"create\")", cli_cmd("controllers", "controller=CooksController action=create")),
71
+ "**`get_context` is your power tool** bundles schema + model + controller + routes + views in ONE call:",
72
+ tool_call("rails_get_context(controller:\"CooksController\", action:\"create\")", cli_cmd("context", "controller=CooksController action=create")),
73
+ tool_call("rails_get_context(model:\"Cook\")", cli_cmd("context", "model=Cook")),
74
+ tool_call("rails_get_context(feature:\"cook\")", cli_cmd("context", "feature=cook")),
68
75
  "",
69
- "**Build or modify a view:**",
70
- tool_call("rails_get_design_system(detail:\"standard\")", cli_cmd("design_system", "detail=standard")),
71
- tool_call("rails_get_view(controller:\"cooks\")", cli_cmd("view", "controller=cooks")),
72
- tool_call("rails_get_partial_interface(partial:\"shared/status_badge\")", cli_cmd("partial_interface", "partial=shared/status_badge")),
73
- tool_call("rails_get_component_catalog(component:\"Alert\")", cli_cmd("component_catalog", "component=Alert")),
76
+ "**`analyze_feature` for broad discovery** scans all layers (models, controllers, routes, services, jobs, views, tests):",
77
+ tool_call("rails_analyze_feature(feature:\"authentication\")", cli_cmd("analyze_feature", "feature=authentication")),
74
78
  "",
75
- "**Write tests:**",
76
- tool_call("rails_get_test_info(detail:\"standard\")", cli_cmd("test_info", "detail=standard")),
77
- tool_call("rails_get_test_info(model:\"Cook\")", cli_cmd("test_info", "model=Cook")),
79
+ "Use individual tools only when you need deeper detail on a specific layer.",
80
+ ""
81
+ ]
82
+ end
83
+
84
+ def tools_workflow_section # rubocop:disable Metrics/MethodLength
85
+ [
86
+ "### Step-by-step workflows (follow this order)",
78
87
  "",
79
- "**Find code:**",
80
- tool_call("rails_search_code(pattern:\"has_many\")", cli_cmd("search_code", "pattern=\"has_many\"")),
81
- tool_call("rails_search_code(pattern:\"create\", match_type:\"definition\")", cli_cmd("search_code", "pattern=create match_type=definition")),
88
+ "**Modify a model** (add field, change validation, add scope):",
89
+ "1. #{tool_call_inline("rails_get_context", "model:\"Cook\"", "context", "model=Cook")} — schema + associations + validations in one call",
90
+ "2. Read the model file, make your edit",
91
+ "3. #{tool_call_inline("rails_migration_advisor", "action:\"add_column\", table:\"cooks\", column:\"rating\", type:\"integer\"", "migration_advisor", "action=add_column table=cooks column=rating type=integer")} — if schema change needed",
92
+ "4. #{tool_call_inline("rails_validate", "files:[\"app/models/cook.rb\"], level:\"rails\"", "validate", "files=app/models/cook.rb level=rails")} — EVERY time after editing",
93
+ "5. #{tool_call_inline("rails_generate_test", "model:\"Cook\"", "generate_test", "model=Cook")} — generate tests matching project patterns",
82
94
  "",
83
- "**Check performance:**",
84
- tool_call("rails_performance_check(model:\"Cook\")", cli_cmd("performance_check", "model=Cook")),
95
+ "**Fix a controller bug:**",
96
+ "1. #{tool_call_inline("rails_get_context", "controller:\"CooksController\", action:\"create\"", "context", "controller=CooksController action=create")} — action source + routes + views + model",
97
+ "2. Read the controller file, make your fix",
98
+ "3. #{tool_call_inline("rails_validate", "files:[\"app/controllers/cooks_controller.rb\"], level:\"rails\"", "validate", "files=app/controllers/cooks_controller.rb level=rails")}",
85
99
  "",
86
- "**Understand dependencies:**",
87
- tool_call("rails_dependency_graph(model:\"Cook\", format:\"mermaid\")", cli_cmd("dependency_graph", "model=Cook format=mermaid")),
100
+ "**Build or modify a view:**",
101
+ "1. #{tool_call_inline("rails_get_design_system", "detail:\"standard\"", "design_system", "detail=standard")} — get copy-paste HTML/ERB patterns",
102
+ "2. #{tool_call_inline("rails_get_view", "controller:\"cooks\"", "view", "controller=cooks")} — existing templates, partials, Stimulus refs",
103
+ "3. #{tool_call_inline("rails_get_partial_interface", "partial:\"shared/status_badge\"", "partial_interface", "partial=shared/status_badge")} — partial locals contract",
104
+ "4. Read the view file, make your edit",
105
+ "5. #{tool_call_inline("rails_validate", "files:[\"app/views/cooks/index.html.erb\"]", "validate", "files=app/views/cooks/index.html.erb")}",
88
106
  "",
89
- "**Query the database:**",
90
- tool_call("rails_query(sql:\"SELECT COUNT(*) FROM users WHERE created_at > '2024-01-01'\")", cli_cmd("query", "sql=\"SELECT COUNT(*) FROM users WHERE created_at > '2024-01-01'\"")),
107
+ "**Trace a method:**",
108
+ tool_call("rails_search_code(pattern:\"can_cook?\", match_type:\"trace\")", cli_cmd("search_code", "pattern=\"can_cook?\" match_type=trace")),
91
109
  "",
92
- "**Debug errors:**",
93
- tool_call("rails_read_logs(level:\"error\", lines:100)", cli_cmd("read_logs", "level=error lines=100")),
110
+ "**Debug an error (one call — gathers context + git + logs + fix):**",
111
+ tool_call("rails_diagnose(error:\"NoMethodError: undefined method `foo` for nil\", file:\"app/models/cook.rb\")", cli_cmd("diagnose", "error=\"NoMethodError: undefined method foo\" file=app/models/cook.rb")),
94
112
  "",
95
- "**Search docs:**",
96
- tool_call("rails_search_docs(query:\"active_record_queries\")", cli_cmd("search_docs", "query=active_record_queries")),
113
+ "**Review changes before merging:**",
114
+ tool_call("rails_review_changes(ref:\"main\")", cli_cmd("review_changes", "ref=main")),
97
115
  "",
98
- "**After editing (EVERY time):**",
99
- tool_call("rails_validate(files:[\"app/models/cook.rb\"], level:\"rails\")", cli_cmd("validate", "files=app/models/cook.rb level=rails")),
116
+ "**Generate tests matching project patterns:**",
117
+ tool_call("rails_generate_test(model:\"Cook\")", cli_cmd("generate_test", "model=Cook")),
118
+ ""
119
+ ]
120
+ end
121
+
122
+ def tools_antipatterns_section
123
+ search_tool = tool_mode == :cli ? cli_cmd("search_code") : "rails_search_code"
124
+ validate_tool = tool_mode == :cli ? cli_cmd("validate") : "rails_validate"
125
+ [
126
+ "### Common mistakes — avoid these",
127
+ "",
128
+ "- **Don't read db/schema.rb** — use `get_schema`. It adds [indexed]/[unique] hints you'd miss.",
129
+ "- **Don't read model files for reference** — use `get_model_details`. It resolves concerns, inherited methods, and implicit belongs_to validations.",
130
+ "- **Don't use Grep/search agents** — use `#{search_tool}`. It excludes sensitive files, supports `match_type:\"trace\"`, and paginates.",
131
+ "- **Don't call tools without a target** — `get_model_details()` without `model:` returns a paginated list, not an error. Always specify what you want.",
132
+ "- **Don't skip validation** — run `#{validate_tool}` after EVERY edit. It catches syntax errors AND Rails-specific issues (missing partials, bad column refs).",
133
+ "- **Don't ignore cross-references** — tool responses include `_Next:` hints suggesting the best follow-up call. Follow them.",
134
+ "- **Don't call `detail:\"full\"` first** — start with `summary` to find your target, then drill in. Full responses waste tokens.",
100
135
  ""
101
136
  ]
102
137
  end
@@ -107,30 +142,32 @@ module RailsAiContext
107
142
  [
108
143
  "### Rules",
109
144
  "",
110
- "1. NEVER read db/schema.rb, config/routes.rb, model files, or test files for reference — use the CLI tools above",
111
- "2. NEVER use Grep or search agents for code searchuse `#{cli_cmd("search_code")}`",
112
- "3. NEVER run `ruby -c`, `erb`, or `node -c` — use `#{cli_cmd("validate")}`",
113
- "4. Read files ONLY when you are about to Edit them",
114
- "5. Start with `detail=summary` to orient, then drill into specifics",
145
+ "1. **Use composite tools first** `#{cli_cmd("context")}` and `#{cli_cmd("analyze_feature")}` before individual tools",
146
+ "2. **NEVER read reference files** db/schema.rb, config/routes.rb, model files, test files tools are better",
147
+ "3. **NEVER use Grep** — use `#{cli_cmd("search_code")}`",
148
+ "4. **Read files ONLY to Edit them** not for reference",
149
+ "5. **Validate EVERY edit** `#{cli_cmd("validate", "files=... level=rails")}`",
150
+ "6. **Follow _Next:_ hints** — tool responses suggest the best follow-up call",
115
151
  ""
116
152
  ]
117
153
  else
118
154
  [
119
155
  "### Rules",
120
156
  "",
121
- "1. NEVER read db/schema.rb, config/routes.rb, model files, or test files for reference — use the MCP tools above",
122
- "2. NEVER use Grep or search agents for code searchuse `rails_search_code`",
123
- "3. NEVER run `ruby -c`, `erb`, or `node -c` — use `rails_validate`",
124
- "4. Read files ONLY when you are about to Edit them",
125
- "5. Start with `detail:\"summary\"` to orient, then drill into specifics",
126
- "6. If MCP tools are not connected, use CLI: `#{cli_cmd("TOOL_NAME", "param=value")}`",
157
+ "1. **Use composite tools first** `rails_get_context` and `rails_analyze_feature` before individual tools",
158
+ "2. **NEVER read reference files** db/schema.rb, config/routes.rb, model files, test files tools are better",
159
+ "3. **NEVER use Grep** — use `rails_search_code`",
160
+ "4. **Read files ONLY to Edit them** not for reference",
161
+ "5. **Validate EVERY edit** — `rails_validate(files:[...], level:\"rails\")`",
162
+ "6. **Follow _Next:_ hints** tool responses suggest the best follow-up call",
163
+ "7. If MCP tools are not connected, use CLI: `#{cli_cmd("TOOL_NAME", "param=value")}`",
127
164
  ""
128
165
  ]
129
166
  end
130
167
  end
131
168
 
132
169
  def tools_table # rubocop:disable Metrics/MethodLength
133
- lines = [ "### All 33 Tools", "" ]
170
+ lines = [ "### All 37 Tools", "" ]
134
171
 
135
172
  if tool_mode == :cli
136
173
  lines.concat(tools_table_cli)
@@ -145,11 +182,11 @@ module RailsAiContext
145
182
  [
146
183
  "| MCP | CLI | What it does |",
147
184
  "|-----|-----|-------------|",
185
+ "| `rails_get_context(model:\"X\")` | `#{cli_cmd("context", "model=X")}` | **START HERE** — schema + model + controller + routes + views in one call |",
148
186
  "| `rails_analyze_feature(feature:\"X\")` | `#{cli_cmd("analyze_feature", "feature=X")}` | Full-stack: models + controllers + routes + services + jobs + views + tests |",
149
- "| `rails_get_context(model:\"X\")` | `#{cli_cmd("context", "model=X")}` | Composite: schema + model + controller + routes + views in one call |",
150
- "| `rails_search_code(pattern:\"X\", match_type:\"trace\")` | `#{cli_cmd("search_code", "pattern=X match_type=trace")}` | Trace: definition + source + siblings + callers + test coverage |",
187
+ "| `rails_search_code(pattern:\"X\", match_type:\"trace\")` | `#{cli_cmd("search_code", "pattern=X match_type=trace")}` | Search + trace: definition, source, callers, test coverage. Also: `match_type:\"any\"` for regex search |",
151
188
  "| `rails_get_controllers(controller:\"X\", action:\"Y\")` | `#{cli_cmd("controllers", "controller=X action=Y")}` | Action source + inherited filters + render map + private methods |",
152
- "| `rails_validate(files:[...], level:\"rails\")` | `#{cli_cmd("validate", "files=a.rb,b.rb level=rails")}` | Syntax + semantic validation + Brakeman security |",
189
+ "| `rails_validate(files:[...], level:\"rails\")` | `#{cli_cmd("validate", "files=a.rb,b.rb level=rails")}` | Syntax + semantic validation (run after EVERY edit) |",
153
190
  "| `rails_get_schema(table:\"X\")` | `#{cli_cmd("schema", "table=X")}` | Columns with [indexed]/[unique]/[encrypted]/[default] hints |",
154
191
  "| `rails_get_model_details(model:\"X\")` | `#{cli_cmd("model_details", "model=X")}` | Associations, validations, scopes, enums, macros, delegations |",
155
192
  "| `rails_get_routes(controller:\"X\")` | `#{cli_cmd("routes", "controller=X")}` | Routes with code-ready helpers and controller filters inline |",
@@ -160,7 +197,6 @@ module RailsAiContext
160
197
  "| `rails_get_concern(name:\"X\", detail:\"full\")` | `#{cli_cmd("concern", "name=X detail=full")}` | Concern methods with source + which models include it |",
161
198
  "| `rails_get_callbacks(model:\"X\")` | `#{cli_cmd("callbacks", "model=X")}` | Callbacks in Rails execution order with source |",
162
199
  "| `rails_get_edit_context(file:\"X\", near:\"Y\")` | `#{cli_cmd("edit_context", "file=X near=Y")}` | Code around a match with class/method context |",
163
- "| `rails_search_code(pattern:\"X\")` | `#{cli_cmd("search_code", "pattern=X")}` | Regex search + `exclude_tests` + `group_by_file` + pagination |",
164
200
  "| `rails_get_service_pattern` | `#{cli_cmd("service_pattern")}` | Service objects: interface, dependencies, side effects, callers |",
165
201
  "| `rails_get_job_pattern` | `#{cli_cmd("job_pattern")}` | Jobs: queue, retries, guard clauses, broadcasts, schedules |",
166
202
  "| `rails_get_env` | `#{cli_cmd("env")}` | Environment variables + credentials keys (not values) |",
@@ -178,7 +214,11 @@ module RailsAiContext
178
214
  "| `rails_get_frontend_stack` | `#{cli_cmd("frontend_stack")}` | React/Vue/Svelte/Angular, Inertia, TypeScript, package manager |",
179
215
  "| `rails_search_docs(query:\"X\")` | `#{cli_cmd("search_docs", "query=X")}` | Bundled topic index with weighted keyword search, on-demand GitHub fetch |",
180
216
  "| `rails_query(sql:\"X\")` | `#{cli_cmd("query", "sql=X")}` | Safe read-only SQL queries with timeout, row limit, column redaction |",
181
- "| `rails_read_logs(level:\"X\")` | `#{cli_cmd("read_logs", "level=X")}` | Reverse file tail with level filtering and sensitive data redaction |"
217
+ "| `rails_read_logs(level:\"X\")` | `#{cli_cmd("read_logs", "level=X")}` | Reverse file tail with level filtering and sensitive data redaction |",
218
+ "| `rails_generate_test(model:\"X\")` | `#{cli_cmd("generate_test", "model=X")}` | Generate test scaffolding matching project patterns (framework, factories, style) |",
219
+ "| `rails_diagnose(error:\"X\")` | `#{cli_cmd("diagnose", "error=\"X\"")}` | One-call error diagnosis: context + git changes + logs + fix suggestions |",
220
+ "| `rails_review_changes(ref:\"main\")` | `#{cli_cmd("review_changes", "ref=main")}` | PR/commit review: file context + warnings (missing indexes, removed validations) |",
221
+ "| `rails_onboard(detail:\"standard\")` | `#{cli_cmd("onboard", "detail=standard")}` | Narrative app walkthrough for new developers or AI agents |"
182
222
  ]
183
223
  end
184
224
 
@@ -186,11 +226,11 @@ module RailsAiContext
186
226
  [
187
227
  "| CLI | What it does |",
188
228
  "|-----|-------------|",
229
+ "| `#{cli_cmd("context", "model=X")}` | **START HERE** — schema + model + controller + routes + views in one call |",
189
230
  "| `#{cli_cmd("analyze_feature", "feature=X")}` | Full-stack: models + controllers + routes + services + jobs + views + tests |",
190
- "| `#{cli_cmd("context", "model=X")}` | Composite: schema + model + controller + routes + views in one call |",
191
- "| `#{cli_cmd("search_code", "pattern=X match_type=trace")}` | Trace: definition + source + siblings + callers + test coverage |",
231
+ "| `#{cli_cmd("search_code", "pattern=X match_type=trace")}` | Search + trace: definition, source, callers, test coverage. Also: `match_type=any` for regex search |",
192
232
  "| `#{cli_cmd("controllers", "controller=X action=Y")}` | Action source + inherited filters + render map + private methods |",
193
- "| `#{cli_cmd("validate", "files=a.rb,b.rb level=rails")}` | Syntax + semantic validation + Brakeman security |",
233
+ "| `#{cli_cmd("validate", "files=a.rb,b.rb level=rails")}` | Syntax + semantic validation (run after EVERY edit) |",
194
234
  "| `#{cli_cmd("schema", "table=X")}` | Columns with [indexed]/[unique]/[encrypted]/[default] hints |",
195
235
  "| `#{cli_cmd("model_details", "model=X")}` | Associations, validations, scopes, enums, macros, delegations |",
196
236
  "| `#{cli_cmd("routes", "controller=X")}` | Routes with code-ready helpers and controller filters inline |",
@@ -201,7 +241,6 @@ module RailsAiContext
201
241
  "| `#{cli_cmd("concern", "name=X detail=full")}` | Concern methods with source + which models include it |",
202
242
  "| `#{cli_cmd("callbacks", "model=X")}` | Callbacks in Rails execution order with source |",
203
243
  "| `#{cli_cmd("edit_context", "file=X near=Y")}` | Code around a match with class/method context |",
204
- "| `#{cli_cmd("search_code", "pattern=X")}` | Regex search + `exclude_tests` + `group_by_file` + pagination |",
205
244
  "| `#{cli_cmd("service_pattern")}` | Service objects: interface, dependencies, side effects, callers |",
206
245
  "| `#{cli_cmd("job_pattern")}` | Jobs: queue, retries, guard clauses, broadcasts, schedules |",
207
246
  "| `#{cli_cmd("env")}` | Environment variables + credentials keys (not values) |",
@@ -219,22 +258,65 @@ module RailsAiContext
219
258
  "| `#{cli_cmd("frontend_stack")}` | React/Vue/Svelte/Angular, Inertia, TypeScript, package manager |",
220
259
  "| `#{cli_cmd("search_docs", "query=X")}` | Bundled topic index with weighted keyword search, on-demand GitHub fetch |",
221
260
  "| `#{cli_cmd("query", "sql=X")}` | Safe read-only SQL queries with timeout, row limit, column redaction |",
222
- "| `#{cli_cmd("read_logs", "level=X")}` | Reverse file tail with level filtering and sensitive data redaction |"
261
+ "| `#{cli_cmd("read_logs", "level=X")}` | Reverse file tail with level filtering and sensitive data redaction |",
262
+ "| `#{cli_cmd("generate_test", "model=X")}` | Generate test scaffolding matching project patterns (framework, factories, style) |",
263
+ "| `#{cli_cmd("diagnose", "error=\"X\"")}` | One-call error diagnosis: context + git changes + logs + fix suggestions |",
264
+ "| `#{cli_cmd("review_changes", "ref=main")}` | PR/commit review: file context + warnings (missing indexes, removed validations) |",
265
+ "| `#{cli_cmd("onboard", "detail=standard")}` | Narrative app walkthrough for new developers or AI agents |"
223
266
  ]
224
267
  end
225
268
 
226
- # Full tool guide section — used by all serializers.
269
+ # Full tool guide section — used by split rules files (.claude/rules/, .cursor/rules/, etc.)
227
270
  def render_tools_guide
228
271
  lines = []
229
272
  lines << tools_header
230
273
  lines << ""
231
274
  lines.concat(tools_intro)
232
- lines.concat(tools_task_section)
275
+ lines.concat(tools_detail_guidance)
276
+ lines.concat(tools_power_tool_section)
277
+ lines.concat(tools_workflow_section)
278
+ lines.concat(tools_antipatterns_section)
233
279
  lines.concat(tools_rules_section)
234
280
  lines.concat(tools_table)
235
281
  lines
236
282
  end
237
283
 
284
+ # Compact tool guide for root files (CLAUDE.md, AGENTS.md) that have line limits.
285
+ # Includes power tools + workflows + rules + dense tool name list (no table).
286
+ def render_tools_guide_compact
287
+ lines = []
288
+ lines << tools_header
289
+ lines << ""
290
+ lines.concat(tools_intro)
291
+ lines.concat(tools_power_tool_section)
292
+ lines.concat(tools_workflow_section)
293
+ lines.concat(tools_rules_section)
294
+ lines.concat(tools_name_list)
295
+ lines
296
+ end
297
+
298
+ # Dense one-line-per-tool listing — fits in compact mode without the table overhead
299
+ def tools_name_list
300
+ all_tools = %w[
301
+ rails_get_context rails_analyze_feature rails_search_code rails_get_controllers
302
+ rails_validate rails_get_schema rails_get_model_details rails_get_routes
303
+ rails_get_view rails_get_design_system rails_get_stimulus rails_get_test_info
304
+ rails_get_concern rails_get_callbacks rails_get_edit_context
305
+ rails_get_service_pattern rails_get_job_pattern rails_get_env
306
+ rails_get_partial_interface rails_get_turbo_map rails_get_helper_methods
307
+ rails_get_config rails_get_gems rails_get_conventions rails_security_scan
308
+ rails_get_component_catalog rails_performance_check rails_dependency_graph
309
+ rails_migration_advisor rails_get_frontend_stack rails_search_docs
310
+ rails_query rails_read_logs rails_generate_test rails_diagnose
311
+ rails_review_changes rails_onboard
312
+ ]
313
+ [
314
+ "### All #{all_tools.size} tools",
315
+ "`#{all_tools.join('` `')}`",
316
+ ""
317
+ ]
318
+ end
319
+
238
320
  private
239
321
 
240
322
  # Generate zsh-safe CLI command: rails 'ai:tool[name]' params
@@ -243,6 +325,19 @@ module RailsAiContext
243
325
  cmd += " #{params}" if params
244
326
  cmd
245
327
  end
328
+
329
+ # Inline tool call for workflow steps (shorter format).
330
+ # mcp_name is the full MCP tool name (e.g. "rails_validate", "rails_get_context").
331
+ def tool_call_inline(mcp_name, mcp_params, cli_short, cli_params)
332
+ case tool_mode
333
+ when :cli
334
+ "`#{cli_cmd(cli_short, cli_params)}`"
335
+ when :mcp
336
+ "`#{mcp_name}(#{mcp_params})` or `#{cli_cmd(cli_short, cli_params)}`"
337
+ else
338
+ "`#{mcp_name}(#{mcp_params})`"
339
+ end
340
+ end
246
341
  end
247
342
  end
248
343
  end
@@ -41,7 +41,11 @@ module RailsAiContext
41
41
  Tools::GetFrontendStack,
42
42
  Tools::SearchDocs,
43
43
  Tools::Query,
44
- Tools::ReadLogs
44
+ Tools::ReadLogs,
45
+ Tools::GenerateTest,
46
+ Tools::Diagnose,
47
+ Tools::ReviewChanges,
48
+ Tools::Onboard
45
49
  ].freeze
46
50
 
47
51
  def initialize(app, transport: :stdio)