rails-ai-context 5.7.0 → 5.7.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 +13 -0
- data/lib/rails_ai_context/introspectors/i18n_introspector.rb +1 -1
- data/lib/rails_ai_context/serializers/claude_serializer.rb +2 -21
- data/lib/rails_ai_context/serializers/copilot_instructions_serializer.rb +1 -1
- data/lib/rails_ai_context/serializers/markdown_serializer.rb +28 -1
- data/lib/rails_ai_context/serializers/opencode_serializer.rb +2 -21
- data/lib/rails_ai_context/serializers/tool_guide_helper.rb +2 -15
- data/lib/rails_ai_context/tools/base_tool.rb +21 -0
- data/lib/rails_ai_context/tools/get_config.rb +3 -3
- data/lib/rails_ai_context/tools/get_edit_context.rb +0 -16
- data/lib/rails_ai_context/tools/get_env.rb +1 -21
- data/lib/rails_ai_context/tools/get_job_pattern.rb +0 -8
- data/lib/rails_ai_context/tools/get_model_details.rb +0 -4
- data/lib/rails_ai_context/tools/get_partial_interface.rb +0 -8
- data/lib/rails_ai_context/tools/get_service_pattern.rb +0 -8
- data/lib/rails_ai_context/tools/get_turbo_map.rb +0 -8
- data/lib/rails_ai_context/tools/get_view.rb +0 -4
- data/lib/rails_ai_context/tools/search_code.rb +2 -12
- data/lib/rails_ai_context/version.rb +1 -1
- data/server.json +2 -2
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e613f50465df28b1b7830acae8a75665fb6c5ce1fc2058e9c4e33f0dbc7e5e47
|
|
4
|
+
data.tar.gz: cc04cd3316cba5728ee08c5324ee546aedf60eea9dd656aa942754edccbbb58d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d6950c03b5b7ad58f2ae1df320d698e82dc244976b1140b19fe8c0aad9a37b7430db2504d990a9bb794fc2278ff591e4416b68c0c6027df7df6001198d5fe55f
|
|
7
|
+
data.tar.gz: e80e37aba8ea2602a9142490c69fb35fa574669e234cf9b7c71093846d57687b7c4b355dbdf3fd295459e74b0b4e19fc4316cb69fc009608c8e28b19e9558409
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,19 @@ 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
|
+
## [5.7.1] — 2026-04-09
|
|
9
|
+
|
|
10
|
+
### Changed — SLOP Cleanup
|
|
11
|
+
|
|
12
|
+
Internal code quality improvements — no API changes, no new features.
|
|
13
|
+
|
|
14
|
+
- **Extract `safe_read`, `max_file_size`, `sensitive_file?` to BaseTool** — removed 16 duplicate one-liner methods across 8 tool files (get_env, get_job_pattern, get_service_pattern, get_turbo_map, get_partial_interface, get_view, get_edit_context, get_model_details, search_code)
|
|
15
|
+
- **Extract `FullSerializerBehavior` module** — deduplicated identical `footer` and `architecture_summary` methods from FullClaudeSerializer and FullOpencodeSerializer
|
|
16
|
+
- **Derive `tools_name_list` from `TOOL_ROWS`** — replaced hardcoded 38-tool name array with derivation from single source of truth in ToolGuideHelper
|
|
17
|
+
- **Fix `notable_gems_list` bypass** — copilot_instructions_serializer and markdown_serializer now use the triple-fallback helper instead of raw hash access
|
|
18
|
+
- **Narrow bare `rescue` to `rescue StandardError`** — 4 sites in get_config and i18n_introspector no longer catch `SignalException`/`NoMemoryError`
|
|
19
|
+
- **Delete dead `SENSITIVE_PATTERNS = nil` constant** — vestigial from get_edit_context
|
|
20
|
+
|
|
8
21
|
## [5.7.0] — 2026-04-09
|
|
9
22
|
|
|
10
23
|
### Quickstart — Two commands. Problem gone.
|
|
@@ -104,6 +104,8 @@ module RailsAiContext
|
|
|
104
104
|
|
|
105
105
|
# Internal: full-mode Claude serializer (wraps MarkdownSerializer with behavioral rules)
|
|
106
106
|
class FullClaudeSerializer < MarkdownSerializer
|
|
107
|
+
include FullSerializerBehavior
|
|
108
|
+
|
|
107
109
|
private
|
|
108
110
|
|
|
109
111
|
def header
|
|
@@ -119,27 +121,6 @@ module RailsAiContext
|
|
|
119
121
|
that matches this project's style.
|
|
120
122
|
MD
|
|
121
123
|
end
|
|
122
|
-
|
|
123
|
-
def footer
|
|
124
|
-
rules = []
|
|
125
|
-
rules << "## Behavioral Rules"
|
|
126
|
-
rules << ""
|
|
127
|
-
rules << "When working in this codebase:"
|
|
128
|
-
rules << "- Follow existing patterns and conventions detected above"
|
|
129
|
-
rules << "- Use the database schema as the source of truth for column names and types"
|
|
130
|
-
rules << "- Respect existing associations and validations when modifying models"
|
|
131
|
-
rules << "- Match the project's architecture style (#{architecture_summary})" if architecture_summary
|
|
132
|
-
test_cmd = detect_test_command
|
|
133
|
-
rules << "- Run `#{test_cmd}` after making changes to verify correctness"
|
|
134
|
-
rules << ""
|
|
135
|
-
rules << super
|
|
136
|
-
rules.join("\n")
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
def architecture_summary
|
|
140
|
-
arch = context.dig(:conventions, :architecture)
|
|
141
|
-
arch&.any? ? arch.join(", ") : nil
|
|
142
|
-
end
|
|
143
124
|
end
|
|
144
125
|
end
|
|
145
126
|
end
|
|
@@ -56,7 +56,7 @@ module RailsAiContext
|
|
|
56
56
|
|
|
57
57
|
gems = context[:gems]
|
|
58
58
|
if gems.is_a?(Hash) && !gems[:error]
|
|
59
|
-
notable = gems
|
|
59
|
+
notable = notable_gems_list(gems)
|
|
60
60
|
notable.group_by { |g| g[:category]&.to_s || "other" }.first(6).each do |cat, gem_list|
|
|
61
61
|
lines << "- #{cat}: #{gem_list.map { |g| g[:name] }.join(', ')}"
|
|
62
62
|
end
|
|
@@ -153,7 +153,7 @@ module RailsAiContext
|
|
|
153
153
|
gems = context[:gems]
|
|
154
154
|
return if gems[:error]
|
|
155
155
|
|
|
156
|
-
notable = gems
|
|
156
|
+
notable = notable_gems_list(gems)
|
|
157
157
|
return if notable.empty?
|
|
158
158
|
|
|
159
159
|
lines = [ "## Notable Gems" ]
|
|
@@ -528,5 +528,32 @@ module RailsAiContext
|
|
|
528
528
|
text.to_s.gsub(MARKDOWN_SPECIAL_CHARS, '\\\\\1')
|
|
529
529
|
end
|
|
530
530
|
end
|
|
531
|
+
|
|
532
|
+
# Shared behavior for full-mode serializers (FullClaudeSerializer, FullOpencodeSerializer).
|
|
533
|
+
# Provides behavioral rules footer and architecture summary.
|
|
534
|
+
module FullSerializerBehavior
|
|
535
|
+
private
|
|
536
|
+
|
|
537
|
+
def footer
|
|
538
|
+
rules = []
|
|
539
|
+
rules << "## Behavioral Rules"
|
|
540
|
+
rules << ""
|
|
541
|
+
rules << "When working in this codebase:"
|
|
542
|
+
rules << "- Follow existing patterns and conventions detected above"
|
|
543
|
+
rules << "- Use the database schema as the source of truth for column names and types"
|
|
544
|
+
rules << "- Respect existing associations and validations when modifying models"
|
|
545
|
+
rules << "- Match the project's architecture style (#{architecture_summary})" if architecture_summary
|
|
546
|
+
test_cmd = detect_test_command
|
|
547
|
+
rules << "- Run `#{test_cmd}` after making changes to verify correctness"
|
|
548
|
+
rules << ""
|
|
549
|
+
rules << super
|
|
550
|
+
rules.join("\n")
|
|
551
|
+
end
|
|
552
|
+
|
|
553
|
+
def architecture_summary
|
|
554
|
+
arch = context.dig(:conventions, :architecture)
|
|
555
|
+
arch&.any? ? arch.join(", ") : nil
|
|
556
|
+
end
|
|
557
|
+
end
|
|
531
558
|
end
|
|
532
559
|
end
|
|
@@ -73,6 +73,8 @@ module RailsAiContext
|
|
|
73
73
|
|
|
74
74
|
# Internal: full-mode OpenCode serializer (wraps MarkdownSerializer)
|
|
75
75
|
class FullOpencodeSerializer < MarkdownSerializer
|
|
76
|
+
include FullSerializerBehavior
|
|
77
|
+
|
|
76
78
|
private
|
|
77
79
|
|
|
78
80
|
def header
|
|
@@ -87,27 +89,6 @@ module RailsAiContext
|
|
|
87
89
|
structure, patterns, and conventions.
|
|
88
90
|
MD
|
|
89
91
|
end
|
|
90
|
-
|
|
91
|
-
def footer
|
|
92
|
-
rules = []
|
|
93
|
-
rules << "## Behavioral Rules"
|
|
94
|
-
rules << ""
|
|
95
|
-
rules << "When working in this codebase:"
|
|
96
|
-
rules << "- Follow existing patterns and conventions detected above"
|
|
97
|
-
rules << "- Use the database schema as the source of truth for column names and types"
|
|
98
|
-
rules << "- Respect existing associations and validations when modifying models"
|
|
99
|
-
rules << "- Match the project's architecture style (#{architecture_summary})" if architecture_summary
|
|
100
|
-
test_cmd = detect_test_command
|
|
101
|
-
rules << "- Run `#{test_cmd}` after making changes to verify correctness"
|
|
102
|
-
rules << ""
|
|
103
|
-
rules << super
|
|
104
|
-
rules.join("\n")
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
def architecture_summary
|
|
108
|
-
arch = context.dig(:conventions, :architecture)
|
|
109
|
-
arch&.any? ? arch.join(", ") : nil
|
|
110
|
-
end
|
|
111
92
|
end
|
|
112
93
|
end
|
|
113
94
|
end
|
|
@@ -289,22 +289,9 @@ module RailsAiContext
|
|
|
289
289
|
lines
|
|
290
290
|
end
|
|
291
291
|
|
|
292
|
-
# Dense one-line-per-tool listing —
|
|
292
|
+
# Dense one-line-per-tool listing — derived from TOOL_ROWS (single source of truth)
|
|
293
293
|
def tools_name_list
|
|
294
|
-
all_tools =
|
|
295
|
-
rails_get_context rails_analyze_feature rails_search_code rails_get_controllers
|
|
296
|
-
rails_validate rails_get_schema rails_get_model_details rails_get_routes
|
|
297
|
-
rails_get_view rails_get_stimulus rails_get_test_info
|
|
298
|
-
rails_get_concern rails_get_callbacks rails_get_edit_context
|
|
299
|
-
rails_get_service_pattern rails_get_job_pattern rails_get_env
|
|
300
|
-
rails_get_partial_interface rails_get_turbo_map rails_get_helper_methods
|
|
301
|
-
rails_get_config rails_get_gems rails_get_conventions rails_security_scan
|
|
302
|
-
rails_get_component_catalog rails_performance_check rails_dependency_graph
|
|
303
|
-
rails_migration_advisor rails_get_frontend_stack rails_search_docs
|
|
304
|
-
rails_query rails_read_logs rails_generate_test rails_diagnose
|
|
305
|
-
rails_review_changes rails_onboard
|
|
306
|
-
rails_runtime_info rails_session_context
|
|
307
|
-
]
|
|
294
|
+
all_tools = TOOL_ROWS.map { |row| row[0][/^(rails_\w+)/, 1] }
|
|
308
295
|
[
|
|
309
296
|
"### All #{all_tools.size} tools",
|
|
310
297
|
"`#{all_tools.join('` `')}`",
|
|
@@ -336,6 +336,27 @@ module RailsAiContext
|
|
|
336
336
|
param_str = params.is_a?(Hash) ? params.sort_by { |k, _| k.to_s }.map { |k, v| "#{k}:#{v}" }.join(",") : params.to_s
|
|
337
337
|
"#{normalized}:#{param_str}"
|
|
338
338
|
end
|
|
339
|
+
|
|
340
|
+
# Shared utility: safe file reading with size limits.
|
|
341
|
+
def safe_read(path)
|
|
342
|
+
RailsAiContext::SafeFile.read(path)
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
# Shared utility: max file size from configuration.
|
|
346
|
+
def max_file_size
|
|
347
|
+
RailsAiContext.configuration.max_file_size
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
# Shared utility: check if a relative path matches sensitive file patterns.
|
|
351
|
+
def sensitive_file?(relative_path)
|
|
352
|
+
patterns = RailsAiContext.configuration.sensitive_patterns
|
|
353
|
+
basename = File.basename(relative_path)
|
|
354
|
+
flags = File::FNM_DOTMATCH | File::FNM_CASEFOLD
|
|
355
|
+
patterns.any? do |pattern|
|
|
356
|
+
File.fnmatch(pattern, relative_path, flags) ||
|
|
357
|
+
File.fnmatch(pattern, basename, flags)
|
|
358
|
+
end
|
|
359
|
+
end
|
|
339
360
|
end
|
|
340
361
|
end
|
|
341
362
|
end
|
|
@@ -162,7 +162,7 @@ module RailsAiContext
|
|
|
162
162
|
|
|
163
163
|
adapter = content.match(/adapter:\s*(\w+)/)&.captures&.first
|
|
164
164
|
adapter || "configured"
|
|
165
|
-
rescue
|
|
165
|
+
rescue StandardError
|
|
166
166
|
nil
|
|
167
167
|
end
|
|
168
168
|
|
|
@@ -173,7 +173,7 @@ module RailsAiContext
|
|
|
173
173
|
return nil unless service_name
|
|
174
174
|
|
|
175
175
|
service_name.to_s
|
|
176
|
-
rescue
|
|
176
|
+
rescue StandardError
|
|
177
177
|
nil
|
|
178
178
|
end
|
|
179
179
|
|
|
@@ -182,7 +182,7 @@ module RailsAiContext
|
|
|
182
182
|
return nil unless method
|
|
183
183
|
|
|
184
184
|
method.to_s
|
|
185
|
-
rescue
|
|
185
|
+
rescue StandardError
|
|
186
186
|
nil
|
|
187
187
|
end
|
|
188
188
|
end
|
|
@@ -8,10 +8,6 @@ module RailsAiContext
|
|
|
8
8
|
"Use when: you need to edit a specific method or section without reading the entire file. " \
|
|
9
9
|
"Requires file:\"app/models/user.rb\" and near:\"def activate\" to locate the code region."
|
|
10
10
|
|
|
11
|
-
def self.max_file_size
|
|
12
|
-
RailsAiContext.configuration.max_file_size
|
|
13
|
-
end
|
|
14
|
-
|
|
15
11
|
input_schema(
|
|
16
12
|
properties: {
|
|
17
13
|
file: {
|
|
@@ -32,9 +28,6 @@ module RailsAiContext
|
|
|
32
28
|
|
|
33
29
|
annotations(read_only_hint: true, destructive_hint: false, idempotent_hint: true, open_world_hint: false)
|
|
34
30
|
|
|
35
|
-
# Sensitive file patterns that should not be readable
|
|
36
|
-
SENSITIVE_PATTERNS = nil # uses configuration.sensitive_patterns
|
|
37
|
-
|
|
38
31
|
def self.call(file:, near:, context_lines: 5, server_context: nil)
|
|
39
32
|
# Reject empty parameters
|
|
40
33
|
if file.nil? || file.strip.empty?
|
|
@@ -143,15 +136,6 @@ module RailsAiContext
|
|
|
143
136
|
text_response(output.join("\n"))
|
|
144
137
|
end
|
|
145
138
|
|
|
146
|
-
private_class_method def self.sensitive_file?(relative_path)
|
|
147
|
-
patterns = RailsAiContext.configuration.sensitive_patterns
|
|
148
|
-
basename = File.basename(relative_path)
|
|
149
|
-
flags = File::FNM_DOTMATCH | File::FNM_CASEFOLD
|
|
150
|
-
patterns.any? do |pattern|
|
|
151
|
-
File.fnmatch(pattern, relative_path, flags) ||
|
|
152
|
-
File.fnmatch(pattern, basename, flags)
|
|
153
|
-
end
|
|
154
|
-
end
|
|
155
139
|
|
|
156
140
|
private_class_method def self.extract_methods(source_lines)
|
|
157
141
|
methods = []
|
|
@@ -246,7 +246,7 @@ module RailsAiContext
|
|
|
246
246
|
next unless Dir.exist?(dir)
|
|
247
247
|
Dir.glob(File.join(dir, "**", "*.rb")).each do |file|
|
|
248
248
|
next if File.size(file) > max_file_size
|
|
249
|
-
next if sensitive_file?(file,
|
|
249
|
+
next if sensitive_file?(file.sub("#{root}/", ""))
|
|
250
250
|
|
|
251
251
|
source = safe_read(file)
|
|
252
252
|
next unless source
|
|
@@ -627,26 +627,6 @@ module RailsAiContext
|
|
|
627
627
|
stripped
|
|
628
628
|
end
|
|
629
629
|
end
|
|
630
|
-
|
|
631
|
-
private_class_method def self.sensitive_file?(file, root)
|
|
632
|
-
relative = file.sub("#{root}/", "")
|
|
633
|
-
basename = File.basename(relative)
|
|
634
|
-
patterns = RailsAiContext.configuration.sensitive_patterns
|
|
635
|
-
flags = File::FNM_DOTMATCH | File::FNM_CASEFOLD
|
|
636
|
-
|
|
637
|
-
patterns.any? do |pattern|
|
|
638
|
-
File.fnmatch(pattern, relative, flags) ||
|
|
639
|
-
File.fnmatch(pattern, basename, flags)
|
|
640
|
-
end
|
|
641
|
-
end
|
|
642
|
-
|
|
643
|
-
private_class_method def self.safe_read(path)
|
|
644
|
-
RailsAiContext::SafeFile.read(path)
|
|
645
|
-
end
|
|
646
|
-
|
|
647
|
-
private_class_method def self.max_file_size
|
|
648
|
-
RailsAiContext.configuration.max_file_size
|
|
649
|
-
end
|
|
650
630
|
end
|
|
651
631
|
end
|
|
652
632
|
end
|
|
@@ -404,14 +404,6 @@ module RailsAiContext
|
|
|
404
404
|
|
|
405
405
|
enqueuers.to_a.sort.first(20)
|
|
406
406
|
end
|
|
407
|
-
|
|
408
|
-
private_class_method def self.safe_read(path)
|
|
409
|
-
RailsAiContext::SafeFile.read(path)
|
|
410
|
-
end
|
|
411
|
-
|
|
412
|
-
private_class_method def self.max_file_size
|
|
413
|
-
RailsAiContext.configuration.max_file_size
|
|
414
|
-
end
|
|
415
407
|
end
|
|
416
408
|
end
|
|
417
409
|
end
|
|
@@ -471,10 +471,6 @@ module RailsAiContext
|
|
|
471
471
|
nil
|
|
472
472
|
end
|
|
473
473
|
|
|
474
|
-
def self.max_file_size
|
|
475
|
-
RailsAiContext.configuration.max_file_size
|
|
476
|
-
end
|
|
477
|
-
|
|
478
474
|
private_class_method def self.extract_model_structure(model_name)
|
|
479
475
|
path = "app/models/#{model_name.underscore}.rb"
|
|
480
476
|
full_path = Rails.root.join(path)
|
|
@@ -470,14 +470,6 @@ module RailsAiContext
|
|
|
470
470
|
$stderr.puts "[rails-ai-context] find_available_partials failed: #{e.message}" if ENV["DEBUG"]
|
|
471
471
|
[]
|
|
472
472
|
end
|
|
473
|
-
|
|
474
|
-
private_class_method def self.safe_read(path)
|
|
475
|
-
RailsAiContext::SafeFile.read(path)
|
|
476
|
-
end
|
|
477
|
-
|
|
478
|
-
private_class_method def self.max_file_size
|
|
479
|
-
RailsAiContext.configuration.max_file_size
|
|
480
|
-
end
|
|
481
473
|
end
|
|
482
474
|
end
|
|
483
475
|
end
|
|
@@ -316,14 +316,6 @@ module RailsAiContext
|
|
|
316
316
|
|
|
317
317
|
parts.any? ? parts.join(", ") : "mixed/no dominant pattern"
|
|
318
318
|
end
|
|
319
|
-
|
|
320
|
-
private_class_method def self.safe_read(path)
|
|
321
|
-
RailsAiContext::SafeFile.read(path)
|
|
322
|
-
end
|
|
323
|
-
|
|
324
|
-
private_class_method def self.max_file_size
|
|
325
|
-
RailsAiContext.configuration.max_file_size
|
|
326
|
-
end
|
|
327
319
|
end
|
|
328
320
|
end
|
|
329
321
|
end
|
|
@@ -680,14 +680,6 @@ module RailsAiContext
|
|
|
680
680
|
$stderr.puts "[rails-ai-context] extract_class_name failed: #{e.message}" if ENV["DEBUG"]
|
|
681
681
|
nil
|
|
682
682
|
end
|
|
683
|
-
|
|
684
|
-
private_class_method def self.safe_read(path)
|
|
685
|
-
RailsAiContext::SafeFile.read(path)
|
|
686
|
-
end
|
|
687
|
-
|
|
688
|
-
private_class_method def self.max_file_size
|
|
689
|
-
RailsAiContext.configuration.max_file_size
|
|
690
|
-
end
|
|
691
683
|
end
|
|
692
684
|
end
|
|
693
685
|
end
|
|
@@ -223,10 +223,6 @@ module RailsAiContext
|
|
|
223
223
|
text_response(lines.join("\n"))
|
|
224
224
|
end
|
|
225
225
|
|
|
226
|
-
def self.max_file_size
|
|
227
|
-
RailsAiContext.configuration.max_file_size
|
|
228
|
-
end
|
|
229
|
-
|
|
230
226
|
private_class_method def self.read_view_file(path)
|
|
231
227
|
# Reject path traversal attempts before any filesystem operation
|
|
232
228
|
if path.include?("..") || path.start_with?("/")
|
|
@@ -233,10 +233,9 @@ module RailsAiContext
|
|
|
233
233
|
cmd << pattern
|
|
234
234
|
cmd << search_path
|
|
235
235
|
|
|
236
|
-
sensitive = RailsAiContext.configuration.sensitive_patterns
|
|
237
236
|
output, _status = Open3.capture2(*cmd, err: File::NULL)
|
|
238
237
|
parse_rg_output(output, root)
|
|
239
|
-
.reject { |r| sensitive_file?(r[:file]
|
|
238
|
+
.reject { |r| sensitive_file?(r[:file]) }
|
|
240
239
|
.first(max_results)
|
|
241
240
|
rescue => e
|
|
242
241
|
[ { file: "error", line_number: 0, content: e.message } ]
|
|
@@ -252,14 +251,13 @@ module RailsAiContext
|
|
|
252
251
|
extensions = RailsAiContext.configuration.search_extensions.join(",")
|
|
253
252
|
glob = file_type ? "**/*.#{file_type}" : "**/*.{#{extensions}}"
|
|
254
253
|
excluded = RailsAiContext.configuration.excluded_paths
|
|
255
|
-
sensitive = RailsAiContext.configuration.sensitive_patterns
|
|
256
254
|
test_dirs = %w[test/ spec/ features/]
|
|
257
255
|
ai_context_files = %w[CLAUDE.md AGENTS.md .claude/ .cursor/ .cursorrules .github/copilot-instructions.md .github/instructions/ .vscode/mcp.json .codex/ .mcp.json opencode.json .ai-context.json]
|
|
258
256
|
|
|
259
257
|
Dir.glob(File.join(search_path, glob)).each do |file|
|
|
260
258
|
relative = file.sub("#{root}/", "")
|
|
261
259
|
next if excluded.any? { |ex| relative.start_with?(ex) }
|
|
262
|
-
next if sensitive_file?(relative
|
|
260
|
+
next if sensitive_file?(relative)
|
|
263
261
|
next if ai_context_files.any? { |p| relative.start_with?(p) || relative == p }
|
|
264
262
|
next if exclude_tests && test_dirs.any? { |td| relative.start_with?(td) }
|
|
265
263
|
|
|
@@ -276,14 +274,6 @@ module RailsAiContext
|
|
|
276
274
|
results
|
|
277
275
|
end
|
|
278
276
|
|
|
279
|
-
private_class_method def self.sensitive_file?(relative_path, patterns)
|
|
280
|
-
basename = File.basename(relative_path)
|
|
281
|
-
flags = File::FNM_DOTMATCH | File::FNM_CASEFOLD
|
|
282
|
-
patterns.any? do |pattern|
|
|
283
|
-
File.fnmatch(pattern, relative_path, flags) ||
|
|
284
|
-
File.fnmatch(pattern, basename, flags)
|
|
285
|
-
end
|
|
286
|
-
end
|
|
287
277
|
|
|
288
278
|
# Group results by file for cleaner output
|
|
289
279
|
private_class_method def self.format_grouped(results)
|
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": "5.7.
|
|
10
|
+
"version": "5.7.1",
|
|
11
11
|
"packages": [
|
|
12
12
|
{
|
|
13
13
|
"registryType": "mcpb",
|
|
14
|
-
"identifier": "https://github.com/crisnahine/rails-ai-context/releases/download/v5.7.
|
|
14
|
+
"identifier": "https://github.com/crisnahine/rails-ai-context/releases/download/v5.7.1/rails-ai-context-mcp.mcpb",
|
|
15
15
|
"fileSha256": "0000000000000000000000000000000000000000000000000000000000000000",
|
|
16
16
|
"transport": {
|
|
17
17
|
"type": "stdio"
|