rails-ai-context 1.1.0 → 1.1.1
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 +4 -4
- data/CHANGELOG.md +11 -0
- data/SECURITY.md +1 -1
- data/lib/rails_ai_context/serializers/claude_rules_serializer.rb +8 -1
- data/lib/rails_ai_context/serializers/claude_serializer.rb +5 -11
- data/lib/rails_ai_context/serializers/copilot_instructions_serializer.rb +6 -1
- data/lib/rails_ai_context/serializers/copilot_serializer.rb +3 -0
- data/lib/rails_ai_context/serializers/cursor_rules_serializer.rb +6 -1
- data/lib/rails_ai_context/serializers/opencode_serializer.rb +5 -11
- data/lib/rails_ai_context/serializers/stack_overview_helper.rb +82 -0
- data/lib/rails_ai_context/serializers/windsurf_rules_serializer.rb +2 -1
- data/lib/rails_ai_context/serializers/windsurf_serializer.rb +4 -0
- data/lib/rails_ai_context/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: dc7244d020376cc416232a1cbbc0a287866dc4243b9566e4fa2d50d556e5a1c6
|
|
4
|
+
data.tar.gz: 5251eb33ca4d3f72803e3acc77d272a4ec038c9a367390752db463195126675a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ddda0c23e18344f9b95d4ff2b0e5ce9dba9c247a2915a1337226f98fb1ef2ab83b07370e2baf26bbb25261241baf75ccf40c952dd03cae4d6b6004c93398c14f
|
|
7
|
+
data.tar.gz: 790dc32dffed8275469eaebae74491dcaa0dbc2b979e53fc8e959b889c69c2eec6982304a1d0d39e22900e79a0214743cf616a8f4e70bea8a4797be679be9c9c
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,17 @@ 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
|
+
## [1.1.1] - 2026-03-23
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **Full-preset stack overview in all serializers** — compact mode now surfaces summary lines for auth, Hotwire/Turbo, API, I18n, ActiveStorage, ActionText, assets, engines, and multi-database in generated context files (CLAUDE.md, AGENTS.md, .windsurfrules, and all split rules). Previously this data was only available via MCP tools.
|
|
13
|
+
- **`rails_analyze_feature` in all tool reference sections** — the 14th tool (added in v1.0.0) was missing from serializer output. Now listed in all generated files across Claude, Cursor, Windsurf, Copilot, and OpenCode formats.
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- **Tool count corrected from 13 to 14** across all serializers to reflect `rails_analyze_feature` added in v1.0.0.
|
|
18
|
+
|
|
8
19
|
## [1.1.0] - 2026-03-23
|
|
9
20
|
|
|
10
21
|
### Changed
|
data/SECURITY.md
CHANGED
|
@@ -5,6 +5,8 @@ module RailsAiContext
|
|
|
5
5
|
# Generates .claude/rules/ files for Claude Code auto-discovery.
|
|
6
6
|
# These provide quick-reference lists without bloating CLAUDE.md.
|
|
7
7
|
class ClaudeRulesSerializer
|
|
8
|
+
include StackOverviewHelper
|
|
9
|
+
|
|
8
10
|
attr_reader :context
|
|
9
11
|
|
|
10
12
|
def initialize(context)
|
|
@@ -77,6 +79,8 @@ module RailsAiContext
|
|
|
77
79
|
(conv[:architecture] || []).first(5).each { |p| lines << "- #{p}" }
|
|
78
80
|
end
|
|
79
81
|
|
|
82
|
+
lines.concat(full_preset_stack_lines)
|
|
83
|
+
|
|
80
84
|
# ApplicationController before_actions — apply to all controllers
|
|
81
85
|
begin
|
|
82
86
|
root = defined?(Rails) ? Rails.root.to_s : Dir.pwd
|
|
@@ -342,7 +346,7 @@ module RailsAiContext
|
|
|
342
346
|
"- app/javascript/controllers/index.js — Stimulus auto-registers controllers. No need to read.",
|
|
343
347
|
"- Test files — use `rails_get_test_info(detail:\"full\")` for patterns.",
|
|
344
348
|
"",
|
|
345
|
-
"## Tools (
|
|
349
|
+
"## Tools (14)",
|
|
346
350
|
"",
|
|
347
351
|
"**rails_get_schema** — database tables, columns, indexes, foreign keys",
|
|
348
352
|
"- `rails_get_schema(detail:\"summary\")` — all tables with column counts",
|
|
@@ -380,6 +384,9 @@ module RailsAiContext
|
|
|
380
384
|
"**rails_validate** — syntax checker for edited files",
|
|
381
385
|
"- `rails_validate(files:[\"app/models/cook.rb\"])` — checks Ruby, ERB, JS syntax in one call",
|
|
382
386
|
"",
|
|
387
|
+
"**rails_analyze_feature** — combined schema + models + controllers + routes for a feature area",
|
|
388
|
+
"- `rails_analyze_feature(feature:\"authentication\")` — one call gets everything related to a feature",
|
|
389
|
+
"",
|
|
383
390
|
"**rails_get_config** — cache store, session, timezone, middleware, initializers",
|
|
384
391
|
"**rails_get_gems** — notable gems categorized by function",
|
|
385
392
|
"**rails_get_conventions** — architecture patterns, directory structure",
|
|
@@ -7,6 +7,7 @@ module RailsAiContext
|
|
|
7
7
|
# In :full mode, delegates to MarkdownSerializer with behavioral rules.
|
|
8
8
|
class ClaudeSerializer
|
|
9
9
|
include TestCommandDetection
|
|
10
|
+
include StackOverviewHelper
|
|
10
11
|
|
|
11
12
|
attr_reader :context
|
|
12
13
|
|
|
@@ -79,16 +80,6 @@ module RailsAiContext
|
|
|
79
80
|
lines << "- Routes: #{routes[:total_routes]} across #{app_ctrls.size} controllers"
|
|
80
81
|
end
|
|
81
82
|
|
|
82
|
-
auth = context[:auth]
|
|
83
|
-
if auth.is_a?(Hash) && !auth[:error]
|
|
84
|
-
parts = []
|
|
85
|
-
parts << "Devise" if auth.dig(:authentication, :devise)&.any?
|
|
86
|
-
parts << "Rails 8 auth" if auth.dig(:authentication, :rails_auth)
|
|
87
|
-
parts << "Pundit" if auth.dig(:authorization, :pundit)&.any?
|
|
88
|
-
parts << "CanCanCan" if auth.dig(:authorization, :cancancan)
|
|
89
|
-
lines << "- Auth: #{parts.join(' + ')}" if parts.any?
|
|
90
|
-
end
|
|
91
|
-
|
|
92
83
|
jobs = context[:jobs]
|
|
93
84
|
if jobs.is_a?(Hash) && !jobs[:error]
|
|
94
85
|
job_count = jobs[:jobs]&.size || 0
|
|
@@ -107,6 +98,8 @@ module RailsAiContext
|
|
|
107
98
|
lines << "- Migrations: #{migrations[:total]} total, #{pending&.size || 0} pending"
|
|
108
99
|
end
|
|
109
100
|
|
|
101
|
+
lines.concat(full_preset_stack_lines)
|
|
102
|
+
|
|
110
103
|
lines << ""
|
|
111
104
|
lines
|
|
112
105
|
end
|
|
@@ -232,7 +225,7 @@ module RailsAiContext
|
|
|
232
225
|
|
|
233
226
|
def render_mcp_guide # rubocop:disable Metrics/MethodLength
|
|
234
227
|
[
|
|
235
|
-
"## MCP Tools (
|
|
228
|
+
"## MCP Tools (14) — ALWAYS Use These First",
|
|
236
229
|
"",
|
|
237
230
|
"Use MCP for reference files (schema, routes, tests). Read directly if you'll edit.",
|
|
238
231
|
"MCP tools return line numbers. Start with `detail:\"summary\"`.",
|
|
@@ -244,6 +237,7 @@ module RailsAiContext
|
|
|
244
237
|
"- `rails_get_view(controller:\"cooks\")` — view list; `(path:\"cooks/index.html.erb\")` — content",
|
|
245
238
|
"- `rails_get_stimulus(detail:\"summary\")` → `(controller:\"name\")` — targets, actions, values",
|
|
246
239
|
"- `rails_get_test_info(detail:\"full\")` — fixtures, factories, helpers; `(model:\"Cook\")` — tests",
|
|
240
|
+
"- `rails_analyze_feature(feature:\"auth\")` — schema + models + controllers + routes for a feature",
|
|
247
241
|
"- `rails_get_config` | `rails_get_gems` | `rails_get_conventions` | `rails_search_code`",
|
|
248
242
|
"- `rails_validate(files:[\"path/to/file.rb\"])` — validate Ruby, ERB, JS syntax in one call",
|
|
249
243
|
""
|
|
@@ -5,6 +5,8 @@ module RailsAiContext
|
|
|
5
5
|
# Generates .github/instructions/*.instructions.md files with applyTo frontmatter
|
|
6
6
|
# for GitHub Copilot path-specific instructions.
|
|
7
7
|
class CopilotInstructionsSerializer
|
|
8
|
+
include StackOverviewHelper
|
|
9
|
+
|
|
8
10
|
attr_reader :context
|
|
9
11
|
|
|
10
12
|
def initialize(context)
|
|
@@ -79,6 +81,8 @@ module RailsAiContext
|
|
|
79
81
|
(conv[:architecture] || []).first(5).each { |p| lines << "- #{arch_labels[p] || p}" }
|
|
80
82
|
end
|
|
81
83
|
|
|
84
|
+
lines.concat(full_preset_stack_lines)
|
|
85
|
+
|
|
82
86
|
# List service objects
|
|
83
87
|
begin
|
|
84
88
|
root = defined?(Rails) ? Rails.root.to_s : Dir.pwd
|
|
@@ -241,7 +245,7 @@ module RailsAiContext
|
|
|
241
245
|
"applyTo: \"**/*\"",
|
|
242
246
|
"---",
|
|
243
247
|
"",
|
|
244
|
-
"# Rails MCP Tools (
|
|
248
|
+
"# Rails MCP Tools (14) — Use These First",
|
|
245
249
|
"",
|
|
246
250
|
"Use MCP for reference files (schema, routes, tests). Read directly if you'll edit.",
|
|
247
251
|
"MCP tools return line numbers for surgical edits.",
|
|
@@ -254,6 +258,7 @@ module RailsAiContext
|
|
|
254
258
|
"- `rails_get_view(controller:\"cooks\")` — view list; `(path:\"cooks/index.html.erb\")` — content",
|
|
255
259
|
"- `rails_get_stimulus(detail:\"summary\")` → `(controller:\"name\")` — targets, actions, values",
|
|
256
260
|
"- `rails_get_test_info(detail:\"full\")` — fixtures, factories, helpers; `(model:\"Cook\")` — existing tests",
|
|
261
|
+
"- `rails_analyze_feature(feature:\"auth\")` — schema + models + controllers + routes for a feature",
|
|
257
262
|
"- `rails_get_config` | `rails_get_gems` | `rails_get_conventions` | `rails_search_code`",
|
|
258
263
|
"- `rails_get_edit_context(file:\"path\", near:\"keyword\")` — surgical edit context with line numbers",
|
|
259
264
|
"- `rails_validate(files:[\"path\"])` — validate Ruby, ERB, JS syntax in one call",
|
|
@@ -7,6 +7,7 @@ module RailsAiContext
|
|
|
7
7
|
# In :full mode, delegates to MarkdownSerializer with Copilot header.
|
|
8
8
|
class CopilotSerializer
|
|
9
9
|
include TestCommandDetection
|
|
10
|
+
include StackOverviewHelper
|
|
10
11
|
|
|
11
12
|
attr_reader :context
|
|
12
13
|
|
|
@@ -44,6 +45,8 @@ module RailsAiContext
|
|
|
44
45
|
lines << "- Routes: #{routes[:total_routes]} across #{(routes[:by_controller] || {}).size} controllers"
|
|
45
46
|
end
|
|
46
47
|
|
|
48
|
+
lines.concat(full_preset_stack_lines)
|
|
49
|
+
|
|
47
50
|
# Gems by category
|
|
48
51
|
gems = context[:gems]
|
|
49
52
|
if gems.is_a?(Hash) && !gems[:error]
|
|
@@ -6,6 +6,8 @@ module RailsAiContext
|
|
|
6
6
|
# Each file is focused, <50 lines, with YAML frontmatter.
|
|
7
7
|
# .cursorrules is deprecated by Cursor; this is the recommended format.
|
|
8
8
|
class CursorRulesSerializer
|
|
9
|
+
include StackOverviewHelper
|
|
10
|
+
|
|
9
11
|
attr_reader :context
|
|
10
12
|
|
|
11
13
|
def initialize(context)
|
|
@@ -87,6 +89,8 @@ module RailsAiContext
|
|
|
87
89
|
(conv[:architecture] || []).first(5).each { |p| lines << "- #{arch_labels[p] || p}" }
|
|
88
90
|
end
|
|
89
91
|
|
|
92
|
+
lines.concat(full_preset_stack_lines)
|
|
93
|
+
|
|
90
94
|
# List service objects
|
|
91
95
|
begin
|
|
92
96
|
root = defined?(Rails) ? Rails.root.to_s : Dir.pwd
|
|
@@ -269,7 +273,7 @@ module RailsAiContext
|
|
|
269
273
|
"alwaysApply: true",
|
|
270
274
|
"---",
|
|
271
275
|
"",
|
|
272
|
-
"# Rails MCP Tools (
|
|
276
|
+
"# Rails MCP Tools (14) — Use These First",
|
|
273
277
|
"",
|
|
274
278
|
"Use MCP for reference files (schema, routes, tests). Read files directly if you'll edit them.",
|
|
275
279
|
"MCP tools return line numbers for surgical edits.",
|
|
@@ -281,6 +285,7 @@ module RailsAiContext
|
|
|
281
285
|
"- `rails_get_view(controller:\"cooks\")` — view list; `rails_get_view(path:\"cooks/index.html.erb\")` — content",
|
|
282
286
|
"- `rails_get_stimulus(detail:\"summary\")` → `rails_get_stimulus(controller:\"name\")`",
|
|
283
287
|
"- `rails_get_test_info(detail:\"full\")` — fixtures, factories, helpers; `(model:\"Cook\")` — existing tests",
|
|
288
|
+
"- `rails_analyze_feature(feature:\"auth\")` — schema + models + controllers + routes for a feature",
|
|
284
289
|
"- `rails_get_config` | `rails_get_gems` | `rails_get_conventions` | `rails_search_code`",
|
|
285
290
|
"- `rails_get_edit_context(file:\"path\", near:\"keyword\")` — surgical edit context with line numbers",
|
|
286
291
|
"- `rails_validate(files:[\"path\"])` — validate Ruby, ERB, JS syntax in one call",
|
|
@@ -7,6 +7,7 @@ module RailsAiContext
|
|
|
7
7
|
# In :full mode, delegates to MarkdownSerializer with OpenCode header.
|
|
8
8
|
class OpencodeSerializer
|
|
9
9
|
include TestCommandDetection
|
|
10
|
+
include StackOverviewHelper
|
|
10
11
|
|
|
11
12
|
attr_reader :context
|
|
12
13
|
|
|
@@ -78,16 +79,6 @@ module RailsAiContext
|
|
|
78
79
|
lines << "- Routes: #{routes[:total_routes]} across #{app_ctrls.size} controllers"
|
|
79
80
|
end
|
|
80
81
|
|
|
81
|
-
auth = context[:auth]
|
|
82
|
-
if auth.is_a?(Hash) && !auth[:error]
|
|
83
|
-
parts = []
|
|
84
|
-
parts << "Devise" if auth.dig(:authentication, :devise)&.any?
|
|
85
|
-
parts << "Rails 8 auth" if auth.dig(:authentication, :rails_auth)
|
|
86
|
-
parts << "Pundit" if auth.dig(:authorization, :pundit)&.any?
|
|
87
|
-
parts << "CanCanCan" if auth.dig(:authorization, :cancancan)
|
|
88
|
-
lines << "- Auth: #{parts.join(" + ")}" if parts.any?
|
|
89
|
-
end
|
|
90
|
-
|
|
91
82
|
jobs = context[:jobs]
|
|
92
83
|
if jobs.is_a?(Hash) && !jobs[:error]
|
|
93
84
|
job_count = jobs[:jobs]&.size || 0
|
|
@@ -106,6 +97,8 @@ module RailsAiContext
|
|
|
106
97
|
lines << "- Migrations: #{migrations[:total]} total, #{pending&.size || 0} pending"
|
|
107
98
|
end
|
|
108
99
|
|
|
100
|
+
lines.concat(full_preset_stack_lines)
|
|
101
|
+
|
|
109
102
|
lines << ""
|
|
110
103
|
lines
|
|
111
104
|
end
|
|
@@ -186,7 +179,7 @@ module RailsAiContext
|
|
|
186
179
|
|
|
187
180
|
def render_mcp_guide # rubocop:disable Metrics/MethodLength
|
|
188
181
|
[
|
|
189
|
-
"## MCP Tools (
|
|
182
|
+
"## MCP Tools (14) — ALWAYS Use These First",
|
|
190
183
|
"",
|
|
191
184
|
"Use MCP for reference files (schema, routes, tests). Read directly if you'll edit.",
|
|
192
185
|
"MCP tools return line numbers. Start with `detail:\"summary\"`.",
|
|
@@ -199,6 +192,7 @@ module RailsAiContext
|
|
|
199
192
|
"- `rails_get_stimulus(detail:\"summary\")` → `(controller:\"name\")` — targets, actions, values",
|
|
200
193
|
"- `rails_get_test_info(detail:\"full\")` — fixtures, factories, helpers; `(model:\"Cook\")` — tests",
|
|
201
194
|
"- `rails_get_edit_context(file:\"path\", near:\"keyword\")` — surgical edit context with line numbers",
|
|
195
|
+
"- `rails_analyze_feature(feature:\"auth\")` — schema + models + controllers + routes for a feature",
|
|
202
196
|
"- `rails_validate(files:[...])` — batch syntax check for Ruby, ERB, JS",
|
|
203
197
|
"- `rails_get_config` | `rails_get_gems` | `rails_get_conventions` | `rails_search_code`",
|
|
204
198
|
""
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RailsAiContext
|
|
4
|
+
module Serializers
|
|
5
|
+
# Shared helper for rendering stack overview lines from full-preset introspectors.
|
|
6
|
+
# Include in any serializer that has a `context` reader and renders a project overview.
|
|
7
|
+
module StackOverviewHelper
|
|
8
|
+
# Returns an array of summary lines for full-preset introspectors.
|
|
9
|
+
# Each line is only added if the introspector returned meaningful data.
|
|
10
|
+
def full_preset_stack_lines(ctx = context)
|
|
11
|
+
lines = []
|
|
12
|
+
|
|
13
|
+
auth = ctx[:auth]
|
|
14
|
+
if auth.is_a?(Hash) && !auth[:error]
|
|
15
|
+
parts = []
|
|
16
|
+
parts << "Devise" if auth.dig(:authentication, :devise)&.any?
|
|
17
|
+
parts << "Rails 8 auth" if auth.dig(:authentication, :rails_auth)
|
|
18
|
+
parts << "Pundit" if auth.dig(:authorization, :pundit)&.any?
|
|
19
|
+
parts << "CanCanCan" if auth.dig(:authorization, :cancancan)
|
|
20
|
+
lines << "- Auth: #{parts.join(' + ')}" if parts.any?
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
turbo = ctx[:turbo]
|
|
24
|
+
if turbo.is_a?(Hash) && !turbo[:error]
|
|
25
|
+
parts = []
|
|
26
|
+
parts << "#{(turbo[:frames] || []).size} frames" if turbo[:frames]&.any?
|
|
27
|
+
parts << "#{(turbo[:streams] || []).size} streams" if turbo[:streams]&.any?
|
|
28
|
+
parts << "broadcasts" if turbo[:broadcasts]&.any?
|
|
29
|
+
lines << "- Hotwire: #{parts.join(', ')}" if parts.any?
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
api = ctx[:api]
|
|
33
|
+
if api.is_a?(Hash) && !api[:error]
|
|
34
|
+
parts = []
|
|
35
|
+
parts << "API-only" if api[:api_only]
|
|
36
|
+
parts << "#{(api[:versions] || []).size} versions" if api[:versions]&.any?
|
|
37
|
+
parts << "GraphQL" if api[:graphql]&.any?
|
|
38
|
+
parts << api[:serializer_library] if api[:serializer_library]
|
|
39
|
+
lines << "- API: #{parts.join(', ')}" if parts.any?
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
i18n_data = ctx[:i18n]
|
|
43
|
+
if i18n_data.is_a?(Hash) && !i18n_data[:error]
|
|
44
|
+
locales = i18n_data[:available_locales] || []
|
|
45
|
+
lines << "- I18n: #{locales.size} locales (#{locales.first(5).join(', ')})" if locales.size > 1
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
storage = ctx[:active_storage]
|
|
49
|
+
if storage.is_a?(Hash) && !storage[:error] && storage[:attachments]&.any?
|
|
50
|
+
lines << "- Storage: ActiveStorage (#{storage[:attachments].size} models with attachments)"
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
action_text = ctx[:action_text]
|
|
54
|
+
if action_text.is_a?(Hash) && !action_text[:error] && action_text[:rich_text_fields]&.any?
|
|
55
|
+
lines << "- RichText: ActionText (#{action_text[:rich_text_fields].size} fields)"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
assets = ctx[:assets]
|
|
59
|
+
if assets.is_a?(Hash) && !assets[:error]
|
|
60
|
+
parts = []
|
|
61
|
+
parts << assets[:pipeline] if assets[:pipeline]
|
|
62
|
+
parts << assets[:js_bundler] if assets[:js_bundler]
|
|
63
|
+
parts << assets[:css_framework] if assets[:css_framework]
|
|
64
|
+
lines << "- Assets: #{parts.join(', ')}" if parts.any?
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
engines = ctx[:engines]
|
|
68
|
+
if engines.is_a?(Hash) && !engines[:error] && engines[:mounted]&.any?
|
|
69
|
+
names = engines[:mounted].map { |e| e[:name] || e[:engine] }.compact.first(5)
|
|
70
|
+
lines << "- Engines: #{names.join(', ')}" if names.any?
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
multi_db = ctx[:multi_database]
|
|
74
|
+
if multi_db.is_a?(Hash) && !multi_db[:error] && multi_db[:databases]&.size.to_i > 1
|
|
75
|
+
lines << "- Databases: #{multi_db[:databases].size} (#{multi_db[:databases].keys.first(3).join(', ')})"
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
lines
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -101,7 +101,7 @@ module RailsAiContext
|
|
|
101
101
|
|
|
102
102
|
def render_mcp_tools_rule # rubocop:disable Metrics/MethodLength
|
|
103
103
|
lines = [
|
|
104
|
-
"# Rails MCP Tools (
|
|
104
|
+
"# Rails MCP Tools (14) — Use These First",
|
|
105
105
|
"",
|
|
106
106
|
"Use MCP for reference files (schema, routes, tests). Read directly if you'll edit.",
|
|
107
107
|
"",
|
|
@@ -112,6 +112,7 @@ module RailsAiContext
|
|
|
112
112
|
"- rails_get_view(controller:\"cooks\") — views; rails_get_view(path:\"file\") — content",
|
|
113
113
|
"- rails_get_stimulus(detail:\"summary\") → rails_get_stimulus(controller:\"name\")",
|
|
114
114
|
"- rails_get_test_info(detail:\"full\") — fixtures, helpers; (model:\"Cook\") — tests",
|
|
115
|
+
"- rails_analyze_feature(feature:\"auth\") — schema + models + controllers + routes for a feature",
|
|
115
116
|
"- rails_get_config | rails_get_gems | rails_get_conventions | rails_search_code",
|
|
116
117
|
"- rails_get_edit_context(file:\"path\", near:\"keyword\") — surgical edit context with line numbers",
|
|
117
118
|
"- rails_validate(files:[\"path\"]) — validate Ruby, ERB, JS syntax in one call",
|
|
@@ -6,6 +6,7 @@ module RailsAiContext
|
|
|
6
6
|
# Always produces compact output regardless of context_mode.
|
|
7
7
|
class WindsurfSerializer
|
|
8
8
|
include TestCommandDetection
|
|
9
|
+
include StackOverviewHelper
|
|
9
10
|
|
|
10
11
|
MAX_CHARS = 5_800 # Leave buffer below 6K limit
|
|
11
12
|
|
|
@@ -42,6 +43,8 @@ module RailsAiContext
|
|
|
42
43
|
routes = context[:routes]
|
|
43
44
|
lines << "Routes: #{routes[:total_routes]}" if routes && !routes[:error]
|
|
44
45
|
|
|
46
|
+
lines.concat(full_preset_stack_lines)
|
|
47
|
+
|
|
45
48
|
# Gems (one line per category)
|
|
46
49
|
gems = context[:gems]
|
|
47
50
|
if gems.is_a?(Hash) && !gems[:error]
|
|
@@ -165,6 +168,7 @@ module RailsAiContext
|
|
|
165
168
|
lines << "- rails_get_conventions — architecture patterns"
|
|
166
169
|
lines << "- rails_search_code(pattern:\"regex\"|file_type:\"rb\"|max_results:N)"
|
|
167
170
|
lines << "- rails_get_edit_context(file:\"path\"|near:\"keyword\")"
|
|
171
|
+
lines << "- rails_analyze_feature(feature:\"auth\") — combined context for a feature"
|
|
168
172
|
lines << "- rails_validate(files:[\"path\"])"
|
|
169
173
|
lines << "Start with detail:\"summary\", then drill into specifics."
|
|
170
174
|
lines << ""
|
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: 1.1.
|
|
4
|
+
version: 1.1.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- crisnahine
|
|
@@ -240,6 +240,7 @@ files:
|
|
|
240
240
|
- lib/rails_ai_context/serializers/opencode_rules_serializer.rb
|
|
241
241
|
- lib/rails_ai_context/serializers/opencode_serializer.rb
|
|
242
242
|
- lib/rails_ai_context/serializers/rules_serializer.rb
|
|
243
|
+
- lib/rails_ai_context/serializers/stack_overview_helper.rb
|
|
243
244
|
- lib/rails_ai_context/serializers/test_command_detection.rb
|
|
244
245
|
- lib/rails_ai_context/serializers/windsurf_rules_serializer.rb
|
|
245
246
|
- lib/rails_ai_context/serializers/windsurf_serializer.rb
|