@reinteractive/rails-insight 1.0.1 → 1.0.3

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.
package/README.md CHANGED
@@ -12,13 +12,13 @@ Generic code-analysis tools treat Ruby files as plain text. RailsInsight underst
12
12
  ## Installation
13
13
 
14
14
  ```bash
15
- npx @reinteractive/railsinsight
15
+ npx @reinteractive/rails-insight
16
16
  ```
17
17
 
18
18
  Or install globally:
19
19
 
20
20
  ```bash
21
- npm install -g @reinteractive/railsinsight
21
+ npm install -g @reinteractive/rails-insight
22
22
  ```
23
23
 
24
24
  ## Quick Start
@@ -26,7 +26,7 @@ npm install -g @reinteractive/railsinsight
26
26
  Run from your Rails project root:
27
27
 
28
28
  ```bash
29
- npx @reinteractive/railsinsight
29
+ npx @reinteractive/rails-insight
30
30
  ```
31
31
 
32
32
  This starts a local MCP server over stdio. The indexer scans your project structure, extracts Rails conventions, builds a relationship graph, and exposes everything through MCP tools.
@@ -34,7 +34,7 @@ This starts a local MCP server over stdio. The indexer scans your project struct
34
34
  To point at a different Rails app:
35
35
 
36
36
  ```bash
37
- npx @reinteractive/railsinsight --project-root /path/to/your/rails/app
37
+ npx @reinteractive/rails-insight --project-root /path/to/your/rails/app
38
38
  ```
39
39
 
40
40
  ### CLI Options
@@ -57,22 +57,22 @@ Add to your Claude Code MCP configuration:
57
57
  "mcpServers": {
58
58
  "railsinsight": {
59
59
  "command": "npx",
60
- "args": ["@reinteractive/railsinsight"]
60
+ "args": ["@reinteractive/rails-insight"]
61
61
  }
62
62
  }
63
63
  }
64
64
  ```
65
65
 
66
- ## Cursor / VS Code Integration
66
+ ## Cursor Integration
67
67
 
68
- In your `.cursor/mcp.json` or VS Code MCP settings:
68
+ In your `.cursor/mcp.json`:
69
69
 
70
70
  ```json
71
71
  {
72
72
  "mcpServers": {
73
73
  "railsinsight": {
74
74
  "command": "npx",
75
- "args": ["@reinteractive/railsinsight"]
75
+ "args": ["@reinteractive/rails-insight"]
76
76
  }
77
77
  }
78
78
  }
@@ -80,41 +80,58 @@ In your `.cursor/mcp.json` or VS Code MCP settings:
80
80
 
81
81
  The server uses the workspace directory as the project root automatically, so no path argument is needed for normal project-local use.
82
82
 
83
+ ## VS Code Integration
84
+
85
+ In your VS Code `.mcp.json` file:
86
+
87
+ ```json
88
+ {
89
+ "servers": {
90
+ "railsinsight": {
91
+ "command": "npx",
92
+ "args": ["@reinteractive/railsinsight"]
93
+ }
94
+ }
95
+ }
96
+ ```
97
+
98
+ This configuration is required for the VS Code MCP extension, which expects the `servers` block and the package name to be `@reinteractive/railsinsight` (no hyphen).
99
+
83
100
  ## Available Tools
84
101
 
85
102
  All 17 tools are available with no tier restrictions.
86
103
 
87
104
  ### Core Tools
88
105
 
89
- | Tool | Description |
90
- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
91
- | `index_project` | Re-index the Rails project. In local mode, re-scans the project root. Accepts `force` (boolean) to bypass cache. Returns statistics and duration. |
92
- | `get_overview` | Project summary: Rails/Ruby versions, database, auth strategy, key models and controllers, frontend stack, file counts. Call this first. |
93
- | `get_full_index` | Complete index JSON trimmed to fit a specified token budget (default: 12,000 tokens). |
94
- | `get_model` | Deep extraction for a specific model: associations, validations, scopes with queries, enums with values, callbacks, public methods, database columns. Requires `name`. |
95
- | `get_controller` | Deep extraction for a specific controller: actions with routes, filters, rate limiting, strong params, rescue handlers. Requires `name`. |
96
- | `get_routes` | Complete route map with namespaces, nested resources, member/collection routes. |
97
- | `get_schema` | Database schema with tables, columns, indexes, foreign keys, and model-to-table mapping. |
98
- | `get_subgraph` | Skill-scoped relationship subgraph with ranked files. Skills: `authentication`, `database`, `frontend`, `api`, `jobs`, `email`. |
99
- | `search_patterns` | Search across all extractions for a specific Rails pattern type (e.g. `has_many_through`, `before_action`, `turbo_broadcast`). |
100
- | `get_deep_analysis` | Deep analysis for a specific category. Categories: `authentication`, `authorization`, `jobs`, `email`, `storage`, `caching`, `realtime`, `api_patterns`, `dependencies`, `components`, `stimulus`, `views`, `convention_drift`, `manifest`, `detected_stack`, `related`, `model_list`, `controller_list`, `component_list`. Accepts optional `name` (entity name) and `depth` (BFS hops for `related`, default 2). |
106
+ | Tool | Description |
107
+ | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
108
+ | `index_project` | Re-index the Rails project. In local mode, re-scans the project root. Accepts `force` (boolean) to bypass cache. Returns statistics and duration. |
109
+ | `get_overview` | Project summary: Rails/Ruby versions, database, auth strategy, key models and controllers, frontend stack, file counts. Call this first. |
110
+ | `get_full_index` | Complete index JSON trimmed to fit a specified token budget (default: 12,000 tokens). |
111
+ | `get_model` | Deep extraction for a specific model: associations, validations, scopes with queries, enums with values, callbacks, public methods, database columns. Requires `name`. |
112
+ | `get_controller` | Deep extraction for a specific controller: actions with routes, filters, rate limiting, strong params, rescue handlers. Requires `name`. |
113
+ | `get_routes` | Complete route map with namespaces, nested resources, member/collection routes. |
114
+ | `get_schema` | Database schema with tables, columns, indexes, foreign keys, and model-to-table mapping. |
115
+ | `get_subgraph` | Skill-scoped relationship subgraph with ranked files. Skills: `authentication`, `database`, `frontend`, `api`, `jobs`, `email`. |
116
+ | `search_patterns` | Search across all extractions for a specific Rails pattern type (e.g. `has_many_through`, `before_action`, `turbo_broadcast`). |
117
+ | `get_deep_analysis` | Deep analysis for a specific category. Categories: `authentication`, `authorization`, `jobs`, `email`, `storage`, `caching`, `realtime`, `api_patterns`, `dependencies`, `cela`|
101
118
 
102
119
  ### Test Intelligence Tools
103
120
 
104
- | Tool | Description |
105
- | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
106
- | `get_coverage_gaps` | Prioritised list of files needing test coverage, with structural context and per-method coverage data from SimpleCov. Accepts optional `category`, `min_gap`, and `limit`. |
107
- | `get_test_conventions` | Detected test patterns and conventions: spec style (request vs controller), let style, auth helper, factories, shared examples, custom matchers, and pattern reference files. |
108
- | `get_domain_clusters` | Domain-clustered file groups for parallel test generation. Files in the same cluster share associations and factories; different clusters can be worked on simultaneously. Accepts `max_cluster_size` and `include_covered`. |
109
- | `get_factory_registry` | Parsed FactoryBot factory definitions including attributes, traits, sequences, and associations. Accepts optional `model` to filter by factory name. |
110
- | `get_well_tested_examples` | High-quality existing spec files suitable as pattern references for test generation agents. Selected by structural complexity per spec category. Accepts `category` and `limit`. |
121
+ | Tool | Description |
122
+ | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
123
+ | `get_coverage_gaps` | Prioritised list of files needing test coverage, with structural context and per-method coverage data from SimpleCov. Accepts optional `category`, `min_gap`, and `l... |
124
+ | `get_test_conventions` | Detected test patterns and conventions: spec style (request vs controller), let style, auth helper, factories, shared examples, custom matchers, and pattern referen... |
125
+ | `get_domain_clusters` | Domain-clustered file groups for parallel test generation. Files in the same cluster share associations and factories; different clusters can be worked on simultane... |
126
+ | `get_factory_registry` | Parsed FactoryBot factory definitions including attributes, traits, sequences, and associations. Accepts optional `model` to filter by factory name. |
127
+ | `get_well_tested_examples` | High-quality existing spec files suitable as pattern references for test generation agents. Selected by structural complexity per spec category. Accepts `category` ... |
111
128
 
112
129
  ### Blast Radius Tools
113
130
 
114
- | Tool | Description |
115
- | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
116
- | `get_blast_radius` | Analyse the impact of code changes. Accepts explicit file paths or auto-detects from git diff. Returns impacted entities classified by risk level (CRITICAL/HIGH/MEDIUM/LOW) with affected tests. Accepts `files`, `base_ref`, `staged`, `max_depth`. |
117
- | `get_review_context` | Build a token-budget-aware review summary for changed files. Combines blast radius analysis with relevant code context for AI-assisted code review. Accepts `files`, `base_ref`, `staged`, `token_budget`. |
131
+ | Tool | Description |
132
+ | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
133
+ | `get_blast_radius` | Analyse the impact of code changes. Accepts explicit file paths or auto-detects from git diff. Returns impacted entities classified by risk level (CRITICAL/HIGH/MEDIUM/LO... |
134
+ | `get_review_context` | Build a token-budget-aware review summary for changed files. Combines blast radius analysis with relevant code context for AI-assisted code review. Accepts `files`, `base... |
118
135
 
119
136
  ## What It Detects
120
137
 
@@ -207,4 +224,4 @@ If you encounter a pattern that isn't detected, please [open an issue](https://g
207
224
 
208
225
  ## License
209
226
 
210
- ISC — see [LICENSE](LICENSE) for details.
227
+ ISC — see [LICENSE](LICENSE) for details.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reinteractive/rails-insight",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "Rails-aware codebase indexer — MCP server for AI agents",
5
5
  "type": "module",
6
6
  "bin": {
@@ -59,4 +59,4 @@
59
59
  "engines": {
60
60
  "node": ">=18.0.0"
61
61
  }
62
- }
62
+ }
@@ -10,7 +10,7 @@ export const SCHEMA_PATTERNS = {
10
10
  /^\s*t\.(?:references|belongs_to)\s+['"]?:?(\w+)['"]?(?:,\s*(.+))?/m,
11
11
  timestamps: /^\s*t\.timestamps/m,
12
12
  index:
13
- /^\s*(?:t\.index|add_index)\s+(?:\[([^\]]+)\]|['"](\w+)['"]),?\s*(.+)?/m,
13
+ /^\s*(?:t\.index|add_index)\s+(?:\[([^\]]+)\]|['"]([^'"]+)['"]),?\s*(.+)?/m,
14
14
  foreignKey:
15
15
  /^\s*add_foreign_key\s+['"](\w+)['"],\s*['"](\w+)['"](?:,\s*(.+))?/m,
16
16
  checkConstraint:
@@ -149,16 +149,22 @@ export function extractSchema(provider) {
149
149
  // Index
150
150
  const indexMatch = trimmed.match(SCHEMA_PATTERNS.index)
151
151
  if (indexMatch) {
152
+ const isExpression = indexMatch[1] === undefined && indexMatch[2] !== undefined && /[^a-zA-Z0-9_]/.test(indexMatch[2])
152
153
  const columns = indexMatch[1]
153
154
  ? indexMatch[1]
154
155
  .match(/['"](\w+)['"]/g)
155
156
  ?.map((c) => c.replace(/['"]/g, '')) || []
156
- : [indexMatch[2]]
157
+ : isExpression
158
+ ? []
159
+ : [indexMatch[2]]
157
160
  const opts = indexMatch[3] || ''
158
161
  currentTable.indexes.push({
159
162
  columns,
163
+ ...(isExpression ? { expression: indexMatch[2] } : {}),
160
164
  unique: /unique:\s*true/.test(opts),
161
165
  name: opts.match(/name:\s*['"]([^'"]+)['"]/)?.[1] || null,
166
+ where: opts.match(/where:\s*['"]([^'"]+)['"]/)?.[1] || null,
167
+ using: opts.match(/using:\s*:(\w+)/)?.[1] || null,
162
168
  })
163
169
  continue
164
170
  }
@@ -23,6 +23,7 @@ export function register(server, state) {
23
23
  const controllers = index.extractions?.controllers || {}
24
24
  const tier2 = index.extractions?.tier2 || {}
25
25
  const tier3 = index.extractions?.tier3 || {}
26
+ const jobs = index.extractions?.jobs || {}
26
27
 
27
28
  // Auth summary
28
29
  const authSummary = {
@@ -114,7 +115,7 @@ export function register(server, state) {
114
115
  frontend_stack: v.frontend || [],
115
116
  authentication: authSummary,
116
117
  authorization: authzSummary,
117
- job_adapter: config.queue_adapter || 'unknown',
118
+ job_adapter: config.queue_adapter || jobs.adapter || 'unknown',
118
119
  cache_store: caching.store || 'unknown',
119
120
  test_framework: v.test_framework || 'unknown',
120
121
  key_models: keyModels,
@@ -124,12 +125,14 @@ export function register(server, state) {
124
125
  workers: {
125
126
  sidekiq_native_count: Object.keys(index.extractions?.workers || {})
126
127
  .length,
128
+ active_job_count: (jobs.jobs || []).length,
127
129
  queues: [
128
- ...new Set(
129
- Object.values(index.extractions?.workers || {}).map(
130
+ ...new Set([
131
+ ...Object.values(index.extractions?.workers || {}).map(
130
132
  (w) => w.queue,
131
133
  ),
132
- ),
134
+ ...(jobs.jobs || []).map((j) => j.queue),
135
+ ]),
133
136
  ],
134
137
  },
135
138
  helpers: {
@@ -15,9 +15,10 @@ export function register(server, state) {
15
15
  const schema = state.index.extractions?.schema || {}
16
16
  const models = state.index.extractions?.models || {}
17
17
 
18
- // Add model ↔ table mapping
18
+ // Add model ↔ table mapping (concrete AR models only, not concerns/modules)
19
19
  const modelTableMap = {}
20
20
  for (const [modelName, modelData] of Object.entries(models)) {
21
+ if (modelData.type === 'concern') continue
21
22
  const tableName = modelData.table_name || toTableName(modelName)
22
23
  modelTableMap[modelName] = tableName
23
24
  }