rails-ai-context 4.1.0 → 4.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: af24e6340b8328b0526c9f030d60b495f4cb1e7130b7f16cadd039e2b9912aab
4
- data.tar.gz: e74d337f614f853fec1bacaff748bea4b212ed96034c22b5fd3d75326da6fc13
3
+ metadata.gz: f82bdd4a192f2776214a228f36e54c62cc6e5e19ac5351d997ade9e5bbdd1667
4
+ data.tar.gz: 303476c0cf9c43ed4eb4f10df5cdf89c7dba0e5b8858d86a90b984c7cd5ffd0e
5
5
  SHA512:
6
- metadata.gz: 9e8d9261310e038cce1cc20ba21d81d203eec2d813dcf318aa3f2071da646a67dc11fd812671a0d982d6d0d234ed84c2079144be3b62863b311e09d0b12181f9
7
- data.tar.gz: 3f6001ba2d788b76e4a6e7b576a9447e7eed91df1a0b689dba679a3c6fbd876db1278e7ebd70637b35bedb01e2e77b1546cf3b96d8c5d37536f1f053fd35f9d3
6
+ metadata.gz: aacc3fad8dbbced828ff47eece6d37db6baefaf92b5e2ad1fa4a55d18fa720857d284aba325742985dde0e8e83420f3bb45b8cccf6be6e37d8a9b4973f96365a
7
+ data.tar.gz: 8c860fedacf47a88253f732a74298f6e7a0a878631d09d090aff3f017703b930bc4add8909bf33407c4165121e942d15c3abce6befc88ccc9e08b0cb09a9e0bb
data/CHANGELOG.md CHANGED
@@ -5,6 +5,18 @@ 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
+ ## [4.2.0] — 2026-03-26
9
+
10
+ ### Added
11
+ - New `rails_search_docs` tool: bundled topic index with weighted keyword search, on-demand GitHub fetch for Rails documentation
12
+ - New `rails_query` tool: safe read-only SQL queries with defense-in-depth (regex pre-filter + SET TRANSACTION READ ONLY + configurable timeout + row limit + column redaction)
13
+ - New `rails_read_logs` tool: reverse file tail with level filtering (debug/info/warn/error/fatal) and sensitive data redaction
14
+ - New config options: `query_timeout` (default timeout for SQL queries), `query_row_limit` (max rows returned), `query_redacted_columns` (columns to mask in query results), `allow_query_in_production` (safety gate, default false), `log_lines` (default number of log lines to read)
15
+
16
+ ### Changed
17
+ - Tool count: 30 → 33
18
+ - Test count: 893 → 983
19
+
8
20
  ## [4.1.0] — 2026-03-29
9
21
 
10
22
  ### Added
data/CLAUDE.md CHANGED
@@ -9,7 +9,7 @@ structure to AI assistants via the Model Context Protocol (MCP).
9
9
  - `lib/rails_ai_context/configuration.rb` — User-facing config with presets (:standard, :full)
10
10
  - `lib/rails_ai_context/introspector.rb` — Orchestrates sub-introspectors
11
11
  - `lib/rails_ai_context/introspectors/` — 33 introspectors (schema, models, routes, jobs, gems, conventions, stimulus, database_stats, controllers, views, view_templates, design_tokens, turbo, i18n, config, active_storage, action_text, auth, api, tests, rake_tasks, assets, devops, action_mailbox, migrations, seeds, middleware, engines, multi_database, components, accessibility, performance, frontend_frameworks)
12
- - `lib/rails_ai_context/tools/` — 30 MCP tools using the official mcp SDK
12
+ - `lib/rails_ai_context/tools/` — 33 MCP tools using the official mcp SDK
13
13
  - `lib/rails_ai_context/cli/` — CLI tool runner (`tool_runner.rb`) — executes MCP tools from rake/Thor
14
14
  - `lib/rails_ai_context/serializers/` — Output formatters (claude, claude_rules, opencode, opencode_rules, cursor_rules, copilot, copilot_instructions, rules, markdown, JSON, context_file_serializer, test_command_detection, tool_guide_helper, design_system_helper, stack_overview_helper)
15
15
  - `lib/rails_ai_context/resources.rb` — MCP resources (static data AI clients read directly)
@@ -40,12 +40,12 @@ structure to AI assistants via the Model Context Protocol (MCP).
40
40
  13. **Per-tool split rules** — `.claude/rules/`, `.cursor/rules/`, `.github/instructions/`
41
41
  14. **Section markers** — root file content wrapped in `<!-- BEGIN/END rails-ai-context -->` to preserve user content
42
42
  15. **generate_root_files toggle** — when false, skip root files (CLAUDE.md, etc.), only generate split rules
43
- 16. **custom_tools API** — `config.custom_tools` array lets users register additional MCP::Tool subclasses alongside the 30 built-in tools
43
+ 16. **custom_tools API** — `config.custom_tools` array lets users register additional MCP::Tool subclasses alongside the 33 built-in tools
44
44
  17. **Design system extraction** — view templates analyzed for canonical examples, color palette, typography, responsive patterns, interactive states, dark mode
45
45
  18. **skip_tools API** — `config.skip_tools` array lets users exclude specific built-in tools (e.g. `%w[rails_security_scan]`)
46
46
  19. **Security scanning** — optional Brakeman integration via `rails_security_scan` tool (graceful degradation if not installed)
47
47
  20. **tool_mode config** — `:mcp` (default, MCP primary + CLI fallback) or `:cli` (CLI only, no MCP server needed). Selected during install.
48
- 21. **CLI tool access** — all 30 MCP tools callable from terminal: `rails ai:tool[schema]`, `rails-ai-context tool schema`. Tool name resolution: `schema` → `get_schema` → `rails_get_schema`.
48
+ 21. **CLI tool access** — all 33 MCP tools callable from terminal: `rails ai:tool[schema]`, `rails-ai-context tool schema`. Tool name resolution: `schema` → `get_schema` → `rails_get_schema`.
49
49
  22. **Shared ToolGuideHelper** — serializers use a shared module for tool reference sections, rendering MCP or CLI syntax based on `tool_mode`
50
50
  23. **Component catalog** — ViewComponent/Phlex introspection: props, slots, previews, sidecar assets, usage examples via `rails_get_component_catalog`
51
51
  24. **Accessibility scanning** — ARIA attributes, semantic HTML, screen reader text, alt text, landmark roles, accessibility score via AccessibilityIntrospector
@@ -53,11 +53,14 @@ structure to AI assistants via the Model Context Protocol (MCP).
53
53
  26. **Migration advisor** — migration code generation with duplicate/nonexistent column warnings, reversibility flags, table name normalization via `rails_migration_advisor`
54
54
  27. **Frontend framework detection** — auto-detects React/Vue/Svelte/Angular from package.json, Vite/Shakapacker/Webpacker config, TypeScript setup, monorepo layout, package manager via `rails_get_frontend_stack`
55
55
  28. **Install generator idempotency** — re-install preserves existing config, only adds new sections, updates ai_tools/tool_mode selections, prompts per-tool file cleanup for removed tools
56
+ 29. **Docs search** — bundled topic index with weighted keyword search, on-demand GitHub fetch
57
+ 30. **Safe SQL queries** — defense-in-depth: regex pre-filter + SET TRANSACTION READ ONLY + timeout
58
+ 31. **Log reading** — reverse file tail with level filtering and sensitive data redaction
56
59
 
57
60
  ## Testing
58
61
 
59
62
  ```bash
60
- bundle exec rspec # Run specs (893 examples)
63
+ bundle exec rspec # Run specs (983 examples)
61
64
  bundle exec rubocop # Lint
62
65
  ```
63
66
 
data/CONTRIBUTING.md CHANGED
@@ -20,7 +20,7 @@ The test suite uses [Combustion](https://github.com/pat/combustion) to boot a mi
20
20
  lib/rails_ai_context/
21
21
  ├── cli/ # CLI tool runner (tool_runner.rb) — executes MCP tools from rake/Thor
22
22
  ├── introspectors/ # 33 introspectors (schema, models, routes, etc.)
23
- ├── tools/ # 30 MCP tools with detail levels and pagination
23
+ ├── tools/ # 33 MCP tools with detail levels and pagination
24
24
  ├── serializers/ # Per-assistant formatters + shared ToolGuideHelper
25
25
  ├── server.rb # MCP server setup (stdio + HTTP)
26
26
  ├── live_reload.rb # MCP live reload (file watcher + cache invalidation)
data/README.md CHANGED
@@ -3,20 +3,24 @@
3
3
  ### Your AI is guessing. This gem makes it know.
4
4
 
5
5
  [![Gem Version](https://img.shields.io/gem/v/rails-ai-context?color=brightgreen)](https://rubygems.org/gems/rails-ai-context)
6
- [![MCP Registry](https://img.shields.io/badge/MCP_Registry-listed-green)](https://registry.modelcontextprotocol.io)
6
+ [![Downloads](https://img.shields.io/gem/dt/rails-ai-context?color=blue)](https://rubygems.org/gems/rails-ai-context)
7
7
  [![CI](https://github.com/crisnahine/rails-ai-context/actions/workflows/ci.yml/badge.svg)](https://github.com/crisnahine/rails-ai-context/actions)
8
+ [![MCP Registry](https://img.shields.io/badge/MCP_Registry-listed-green)](https://registry.modelcontextprotocol.io)
9
+ [![Ruby](https://img.shields.io/badge/Ruby-3.2%20%7C%203.3%20%7C%203.4-red)](https://github.com/crisnahine/rails-ai-context)
10
+ [![Rails](https://img.shields.io/badge/Rails-7.1%20%7C%207.2%20%7C%208.0-red)](https://github.com/crisnahine/rails-ai-context)
11
+ [![Tests](https://img.shields.io/badge/Tests-983%20passing-brightgreen)](https://github.com/crisnahine/rails-ai-context/actions)
8
12
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
9
13
 
10
14
  **Works with:** Claude Code &bull; Cursor &bull; GitHub Copilot &bull; OpenCode &bull; Any terminal
11
15
 
12
- > Built by a Rails developer with 10+ years of production experience. AI assisted — the same way it assists me shipping features at work. I designed the architecture, made every decision, reviewed every line, and wrote 893 tests. This gem exists because I understand Rails deeply enough to know exactly what AI agents get wrong and what context they need to get it right.
16
+ > Built by a Rails developer with 10+ years of production experience. AI assisted — the same way it assists me shipping features at work. I designed the architecture, made every decision, reviewed every line, and wrote 983 tests. This gem exists because I understand Rails deeply enough to know exactly what AI agents get wrong and what context they need to get it right.
13
17
 
14
18
  ```bash
15
19
  gem "rails-ai-context", group: :development
16
20
  rails generate rails_ai_context:install
17
21
  ```
18
22
 
19
- That's it. Your AI now has 30 tools that understand your entire Rails app — via MCP server or CLI. Zero config.
23
+ That's it. Your AI now has 33 tools that understand your entire Rails app — via MCP server or CLI. Zero config.
20
24
 
21
25
  > **[Full Guide →](docs/GUIDE.md)** — every command, every parameter, every configuration option.
22
26
 
@@ -46,7 +50,7 @@ rails 'ai:tool[schema]' table=users
46
50
  rails 'ai:tool[analyze_feature]' feature=billing
47
51
  ```
48
52
 
49
- Same 30 tools. Same output. AI agents run these as shell commands. **Works in any terminal, any AI tool, any workflow.** No MCP client required.
53
+ Same 33 tools. Same output. AI agents run these as shell commands. **Works in any terminal, any AI tool, any workflow.** No MCP client required.
50
54
 
51
55
  ---
52
56
 
@@ -170,7 +174,7 @@ Tested on a real Rails 8 app (5 models, 19 controllers, 95 routes):
170
174
 
171
175
  ---
172
176
 
173
- ## 30 Tools
177
+ ## 33 Tools
174
178
 
175
179
  Every tool is **read-only** and returns structured, token-efficient data.
176
180
 
@@ -216,6 +220,10 @@ Every tool is **read-only** and returns structured, token-efficient data.
216
220
  | `migration_advisor` | `rails_migration_advisor` | `rails 'ai:tool[migration_advisor]'` | Migration code generation with reversibility + affected models |
217
221
  | **Frontend** | | | |
218
222
  | `get_frontend_stack` | `rails_get_frontend_stack` | `rails 'ai:tool[frontend_stack]'` | React/Vue/Svelte/Angular, Inertia, TypeScript, package manager |
223
+ | **Data & Debugging** | | | |
224
+ | `search_docs` | `rails_search_docs(topic:"X")` | `rails 'ai:tool[search_docs]'` | Bundled topic index with weighted keyword search, on-demand GitHub fetch |
225
+ | `query` | `rails_query(sql:"X")` | `rails 'ai:tool[query]'` | Safe read-only SQL queries with timeout, row limit, column redaction |
226
+ | `read_logs` | `rails_read_logs(level:"X")` | `rails 'ai:tool[read_logs]'` | Reverse file tail with level filtering and sensitive data redaction |
219
227
 
220
228
  > **[Full parameter docs →](docs/GUIDE.md)**
221
229
 
@@ -238,7 +246,7 @@ Every tool is **read-only** and returns structured, token-efficient data.
238
246
  ▼ ▼ ▼
239
247
  ┌──────────────────┐ ┌────────────┐ ┌────────────────────┐
240
248
  │ Static Files │ │ MCP Server │ │ CLI Tools │
241
- │ CLAUDE.md │ │ 30 tools │ │ Same 30 tools │
249
+ │ CLAUDE.md │ │ 33 tools │ │ Same 33 tools │
242
250
  │ .cursor/rules/ │ │ stdio/HTTP │ │ No server needed │
243
251
  │ .github/instr... │ │ .mcp.json │ │ rails 'ai:tool[X]' │
244
252
  └──────────────────┘ └────────────┘ └────────────────────┘
@@ -274,7 +282,7 @@ MCP auto-discovery: `.mcp.json` is detected automatically by Claude Code and Cur
274
282
  | Command | What it does |
275
283
  |---------|-------------|
276
284
  | `rails ai:context` | Generate context files for your AI tools |
277
- | `rails 'ai:tool[NAME]'` | Run any of the 30 tools from the CLI |
285
+ | `rails 'ai:tool[NAME]'` | Run any of the 33 tools from the CLI |
278
286
  | `rails ai:tool` | List all available tools with short names |
279
287
  | `rails ai:serve` | Start MCP server (stdio) |
280
288
  | `rails ai:doctor` | Diagnostics + AI readiness score |
@@ -347,7 +355,7 @@ end
347
355
  ```bash
348
356
  git clone https://github.com/crisnahine/rails-ai-context.git
349
357
  cd rails-ai-context && bundle install
350
- bundle exec rspec # 893 examples
358
+ bundle exec rspec # 983 examples
351
359
  bundle exec rubocop # Lint
352
360
  ```
353
361
 
data/SECURITY.md CHANGED
@@ -4,6 +4,7 @@
4
4
 
5
5
  | Version | Supported |
6
6
  |---------|--------------------|
7
+ | 4.2.x | :white_check_mark: |
7
8
  | 4.1.x | :white_check_mark: |
8
9
  | 4.0.x | :white_check_mark: |
9
10
  | 3.1.x | :white_check_mark: |
@@ -25,7 +26,7 @@ If you discover a security vulnerability in rails-ai-context, please report it r
25
26
 
26
27
  ## Security Design
27
28
 
28
- - All 30 MCP tools are **read-only** and never modify your application or database.
29
+ - All 33 MCP tools are **read-only** and never modify your application or database.
29
30
  - **Sensitive file blocking** — configurable `sensitive_patterns` blocks access to `.env`, `*.key`, `*.pem`, `credentials.yml.enc` across all search and read tools. Patterns are checked in `rails_search_code`, `rails_get_edit_context`, and all new tools.
30
31
  - **Path traversal protection** — all file-reading tools validate paths with `File.realpath()` against `Rails.root` to prevent directory escape.
31
32
  - **Command injection prevention** — code search uses `Open3.capture2` with array arguments (never shell strings). The `--` flag separator prevents pattern injection.
data/docs/GUIDE.md CHANGED
@@ -252,7 +252,7 @@ rails ai:context:claude # Use this instead (no quoting needed)
252
252
 
253
253
  ## CLI Tools
254
254
 
255
- All 30 MCP tools can be run directly from the terminal — no MCP server or AI client needed.
255
+ All 33 MCP tools can be run directly from the terminal — no MCP server or AI client needed.
256
256
 
257
257
  ### Rake
258
258
 
@@ -316,7 +316,7 @@ The `tool_mode` is selected during `rails generate rails_ai_context:install`.
316
316
 
317
317
  ## MCP Tools — Full Reference
318
318
 
319
- All 30 tools are **read-only** and **idempotent** — they never modify your application or database.
319
+ All 33 tools are **read-only** and **idempotent** — they never modify your application or database.
320
320
 
321
321
  ### rails_get_schema
322
322
 
@@ -1117,7 +1117,7 @@ RailsAiContext.configure do |config|
1117
1117
  end
1118
1118
  ```
1119
1119
 
1120
- Both transports are **read-only** — they expose the same 30 tools and never modify your app.
1120
+ Both transports are **read-only** — they expose the same 33 tools and never modify your app.
1121
1121
 
1122
1122
  ---
1123
1123
 
@@ -436,9 +436,9 @@ module RailsAiContext
436
436
  say ""
437
437
  say "Commands:", :yellow
438
438
  say " rails ai:context # Regenerate context files"
439
- say " rails 'ai:tool[schema]' # Run any of the 30 tools from CLI"
439
+ say " rails 'ai:tool[schema]' # Run any of the 33 tools from CLI"
440
440
  if @tool_mode == :mcp
441
- say " rails ai:serve # Start MCP server (30 live tools)"
441
+ say " rails ai:serve # Start MCP server (33 live tools)"
442
442
  end
443
443
  say " rails ai:doctor # Check AI readiness"
444
444
  say " rails ai:inspect # Print introspection summary"
@@ -222,9 +222,23 @@ module RailsAiContext
222
222
  # For missing required params: strip empty values so the tool's own guards
223
223
  # can return a friendly response (matching MCP behavior).
224
224
  # For invalid enums: strip the bad value and let the tool use its default.
225
+ # For unknown params: raise InvalidArgumentError with closest-match suggestion.
225
226
  def validate_kwargs!(kwargs, schema)
226
227
  properties = schema[:properties] || {}
227
228
  required = (schema[:required] || []).map(&:to_s)
229
+ known_keys = properties.keys.map(&:to_s)
230
+
231
+ # Check for unknown params and raise a helpful error with suggestions.
232
+ # server_context is always allowed (internal MCP param).
233
+ unknown = kwargs.keys.map(&:to_s) - known_keys - [ "server_context" ]
234
+ if unknown.any?
235
+ msgs = unknown.map do |k|
236
+ suggestion = Tools::BaseTool.find_closest_match(k, known_keys)
237
+ suggestion ? " '#{k}' — did you mean '#{suggestion}='?" : " '#{k}'"
238
+ end
239
+ valid_str = known_keys.any? ? "Valid params: #{known_keys.join(', ')}" : "This tool takes no params."
240
+ raise InvalidArgumentError, "Unknown param#{unknown.size > 1 ? 's' : ''}:\n#{msgs.join("\n")}\n#{valid_str}"
241
+ end
228
242
 
229
243
  # For required params with empty-string values, keep the key but set to nil
230
244
  # so the tool's own guards can return friendly "parameter is required" messages
@@ -98,6 +98,15 @@ module RailsAiContext
98
98
  attr_accessor :frontend_paths # User-declared frontend dirs (e.g. ["app/frontend", "../web-client"])
99
99
  attr_accessor :mobile_paths # User-declared mobile dirs (e.g. ["../mobile-app"])
100
100
 
101
+ # Database query tool settings (rails_query)
102
+ attr_accessor :query_timeout # Statement timeout in seconds (default: 5)
103
+ attr_accessor :query_row_limit # Max rows returned (default: 100, hard cap: 1000)
104
+ attr_accessor :query_redacted_columns # Column names whose values are redacted in output
105
+ attr_accessor :allow_query_in_production # Allow rails_query in production (default: false)
106
+
107
+ # Log reading settings (rails_read_logs)
108
+ attr_accessor :log_lines # Default lines to tail (default: 50)
109
+
101
110
  def initialize
102
111
  @server_name = "rails-ai-context"
103
112
  @server_version = RailsAiContext::VERSION
@@ -166,6 +175,16 @@ module RailsAiContext
166
175
  @concern_paths = %w[app/models/concerns app/controllers/concerns]
167
176
  @frontend_paths = nil
168
177
  @mobile_paths = nil
178
+ @query_timeout = 5
179
+ @query_row_limit = 100
180
+ @query_redacted_columns = %w[
181
+ password_digest encrypted_password password_hash
182
+ reset_password_token confirmation_token unlock_token
183
+ otp_secret session_data secret_key
184
+ api_key api_secret access_token refresh_token jti
185
+ ]
186
+ @allow_query_in_production = false
187
+ @log_lines = 50
169
188
  end
170
189
 
171
190
  def preset=(name)