rails-ai-context 0.10.1 → 0.10.2

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: 41d6a7f273bd4630ef25d299a4379609336714a021d77bcbb5128235a62bd830
4
- data.tar.gz: 64b3c29bbf29126d6f8aaf76e1f063140ad7ea3684e15ca392a2275d2fe35110
3
+ metadata.gz: 68c0816e248242dd0b6b6c122f8a5538295823a4da7386746aa3d3ea8c3a8ee0
4
+ data.tar.gz: 178f97d3d8557621dbe0cc163e75e83afed3156ca1ea87d185e29ca380567580
5
5
  SHA512:
6
- metadata.gz: 90003df73a6d12bec5e205343ffc4615a6f59061f32bdba71f344dfcacf046de339836b871d1e6e85353bff3951673a5fa2f2c2b0bd3b950c9b0d62872760bc2
7
- data.tar.gz: eaad1515c31ee3d6d3cb61a402991d92aa6107770011d70338a096d8dc23a809423e77ba3194d7813cbb3df2ea3cadf772ebdf4f7b939afe0c82940471b7b7a3
6
+ metadata.gz: 953fcec85a05ec05862157ae70a8715f0daad9d1b4f1fba075c8f1ef16a13de90eaf81e3906efd5790fb4ed32106bb5838668ff0d41533a569a7e6443f63b141
7
+ data.tar.gz: eade81b4fa9597317981d8f17a6fccdc6d9872adae3b543dd18cf9449d6746072584f754ded5031c2376b33d30aded7164c03f7253513e1c2f2c7b9c4c35d225
data/README.md CHANGED
@@ -21,22 +21,49 @@ The AI doesn't know your schema, your Devise setup, your Sidekiq jobs, or that `
21
21
 
22
22
  ---
23
23
 
24
- ## Proof: 35% Token Savings (Real Benchmark)
24
+ ## Proof: 37% Token Savings (Real Benchmark)
25
25
 
26
- We ran the same feature task — *"Add status and date range filters to the Cooks index page"* — across 4 scenarios in parallel on a real Rails app:
26
+ Same task — *"Add status and date range filters to the Cooks index page"* — 4 scenarios in parallel, same Rails app:
27
27
 
28
- | Scenario | MCP Tools | CLAUDE.md | Tokens Used | Savings |
29
- |----------|-----------|-----------|-------------|---------|
30
- | **MCP + CLAUDE.md** | Yes | Yes | **25,884** | **35% saved** |
31
- | MCP only | Yes | No | 27,822 | 31% saved |
32
- | CLAUDE.md only | No | Yes | 32,699 | 19% saved |
33
- | Zero (nothing) | No | No | 40,129 | baseline |
28
+ | Setup | Tokens | Saved | What it knows |
29
+ |-------|--------|-------|---------------|
30
+ | **rails-ai-context (full)** | **28,834** | **37%** | 11 MCP tools + generated docs + rules |
31
+ | rails-ai-context CLAUDE.md only | 33,106 | 27% | Generated docs + rules, no MCP tools |
32
+ | Normal Claude `/init` | 40,700 | 11% | Generic CLAUDE.md only |
33
+ | No rails-ai-context at all | 45,477 | baseline | Nothing — discovers everything from scratch |
34
34
 
35
- All 4 produced the same working feature. The only difference was how many tokens were burned getting there.
35
+ ```
36
+ No rails-ai-context 45,477 tk █████████████████████████████████████████████
37
+ Normal Claude /init 40,700 tk █████████████████████████████████████████ -11%
38
+ rails-ai-context CLAUDE.md 33,106 tk █████████████████████████████████ -27%
39
+ rails-ai-context (full) 28,834 tk █████████████████████████████ -37%
40
+ ```
41
+
42
+ https://github.com/user-attachments/assets/14476243-1210-4e62-9dc5-9d4aa9caef7e
43
+
44
+
45
+ **What each layer gives you:**
46
+
47
+ | | Normal `/init` | rails-ai-context CLAUDE.md | rails-ai-context full |
48
+ |---|---|---|---|
49
+ | Knows it's Rails + Tailwind | Yes | Yes | Yes |
50
+ | Knows model names, columns, associations | No | Yes | Yes |
51
+ | Knows controller actions, filters | No | Yes | Yes |
52
+ | Discovery overhead | ~8 calls | 0 calls | 0 calls |
53
+ | Structured MCP queries | No | No | Yes — 5 MCP calls replace file reads |
54
+
55
+ **~16,600 fewer tokens per task** vs no gem at all.
56
+
57
+ > **This was a simple task on a small 5-model app.** Real-world tasks are 3-10x more complex.
58
+ > A feature touching auth + payments + mailers + tests on a 50-model app? Without the gem, Claude reads `db/schema.rb` (2,000+ lines), every model file, every controller, every view — easily 200K+ tokens per session. With rails-ai-context, MCP tools return only what's needed: `rails_get_schema(table:"users")` returns 25 lines instead of 2,000. **The bigger your app and the harder the task, the more you save.**
36
59
 
37
- https://github.com/user-attachments/assets/171f52ae-bd30-43f6-a44f-bcfdda7fc139
60
+ | App size | Without gem | With rails-ai-context | Savings |
61
+ |----------|-------------|----------------------|---------|
62
+ | Small (5 models) | 45K tokens | 29K tokens | 37% |
63
+ | Medium (30 models) | ~150K tokens | ~60K tokens | ~60% |
64
+ | Large (100+ models) | ~500K+ tokens | ~100K tokens | ~80% |
38
65
 
39
- MCP tools give the AI structured, filtered access to your codebase instead of reading entire files. On this small 5-model app, that saved 35%. **On larger projects, the savings compound significantly.**
66
+ *Medium/large estimates based on schema.rb scaling (40 lines/table), model file scaling, and MCP summary-first workflow eliminating full-file reads.*
40
67
 
41
68
  ---
42
69
 
@@ -60,10 +87,10 @@ The install generator creates `.mcp.json` for auto-discovery — Claude Code and
60
87
 
61
88
  ![Token Comparison](https://raw.githubusercontent.com/crisnahine/rails-ai-context/main/docs/token-comparison.jpeg)
62
89
 
63
- - Compact context files load ≤150 lines instead of thousands
64
- - MCP tools return `detail:"summary"` first (~55 tokens for schema overview), then drill into specifics
65
- - Specific lookups (`table:`, `model:`, `controller:`) return only what's needed
66
- - Pagination prevents dumping hundreds of tables/routes at once
90
+ - `/init` saves 11% knows the framework but wastes tokens discovering models and tables
91
+ - **CLAUDE.md saves 27%** complete Rails-specific map, zero discovery overhead
92
+ - **Full MCP saves 37%** structured queries replace expensive full-file reads
93
+ - MCP tools return `detail:"summary"` first (~55 tokens), then drill into specifics
67
94
  - Split rule files only activate in relevant directories
68
95
 
69
96
  ---
data/demo_script.sh CHANGED
@@ -8,7 +8,7 @@ echo 'Fetching gem metadata from https://rubygems.org...'
8
8
  sleep 0.3
9
9
  echo 'Resolving dependencies...'
10
10
  sleep 0.3
11
- echo 'Installing rails-ai-context 0.10.1'
11
+ echo 'Installing rails-ai-context 0.10.2'
12
12
  echo ''
13
13
  sleep 1
14
14
 
@@ -169,8 +169,8 @@ module RailsAiContext
169
169
  macros = {}
170
170
 
171
171
  macros[:has_secure_password] = true if source.match?(/\bhas_secure_password\b/)
172
- macros[:encrypts] = source.scan(/\bencrypts\s+(.+)/).flat_map { |m| m[0].scan(/:(\w+)/).flatten } if source.match?(/\bencrypts\s+:/)
173
- macros[:normalizes] = source.scan(/\bnormalizes\s+(.+)/).flat_map { |m| m[0].scan(/:(\w+)/).flatten } if source.match?(/\bnormalizes\s+:/)
172
+ macros[:encrypts] = source.scan(/\bencrypts\s+(.+?)$/).flat_map { |m| m[0].scan(/:(\w+)/).flatten } if source.match?(/\bencrypts\s+:/)
173
+ macros[:normalizes] = source.scan(/\bnormalizes\s+(.+?)$/).flat_map { |m| m[0].scan(/:(\w+)/).flatten } if source.match?(/\bnormalizes\s+:/)
174
174
  macros[:has_one_attached] = source.scan(/\bhas_one_attached\s+:(\w+)/).flatten if source.match?(/\bhas_one_attached\s+:/)
175
175
  macros[:has_many_attached] = source.scan(/\bhas_many_attached\s+:(\w+)/).flatten if source.match?(/\bhas_many_attached\s+:/)
176
176
  macros[:has_rich_text] = source.scan(/\bhas_rich_text\s+:(\w+)/).flatten if source.match?(/\bhas_rich_text\s+:/)
@@ -180,7 +180,7 @@ module RailsAiContext
180
180
  macros[:store] = source.scan(/\bstore(?:_accessor)?\s+:(\w+)/).flatten if source.match?(/\bstore(?:_accessor)?\s+:/)
181
181
 
182
182
  # Delegations
183
- delegations = source.scan(/\bdelegate\s+(.+?),\s*to:\s*:(\w+)/).map do |methods_str, target|
183
+ delegations = source.scan(/\bdelegate\s+(.+?),\s*to:\s*:(\w+)/m).map do |methods_str, target|
184
184
  { methods: methods_str.scan(/:(\w+)/).flatten, to: target }
185
185
  end
186
186
  macros[:delegations] = delegations if delegations.any?
@@ -92,6 +92,8 @@ module RailsAiContext
92
92
  end
93
93
  end
94
94
 
95
+ MAX_FILE_SIZE = 2_000_000 # 2MB safety limit
96
+
95
97
  private_class_method def self.read_view_file(path)
96
98
  views_dir = Rails.root.join("app", "views")
97
99
  full_path = views_dir.join(path)
@@ -103,6 +105,9 @@ module RailsAiContext
103
105
  unless File.exist?(full_path)
104
106
  return text_response("View not found: #{path}")
105
107
  end
108
+ if File.size(full_path) > MAX_FILE_SIZE
109
+ return text_response("File too large: #{path} (#{File.size(full_path)} bytes)")
110
+ end
106
111
 
107
112
  content = File.read(full_path)
108
113
  text_response("# #{path}\n\n```erb\n#{content}\n```")
@@ -106,7 +106,11 @@ module RailsAiContext
106
106
 
107
107
  private_class_method def self.search_with_ruby(pattern, search_path, file_type, max_results, root)
108
108
  results = []
109
- regex = Regexp.new(pattern, Regexp::IGNORECASE)
109
+ begin
110
+ regex = Regexp.new(pattern, Regexp::IGNORECASE, timeout: 2)
111
+ rescue RegexpError => e
112
+ return [ { file: "error", line_number: 0, content: "Invalid regex: #{e.message}" } ]
113
+ end
110
114
  glob = file_type ? "**/*.#{file_type}" : "**/*.{rb,js,erb,yml,yaml,json}"
111
115
  excluded = RailsAiContext.configuration.excluded_paths
112
116
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsAiContext
4
- VERSION = "0.10.1"
4
+ VERSION = "0.10.2"
5
5
  end
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": "0.10.1",
10
+ "version": "0.10.2",
11
11
  "packages": [
12
12
  {
13
13
  "registryType": "mcpb",
14
- "identifier": "https://github.com/crisnahine/rails-ai-context/releases/download/v0.10.1/rails-ai-context-mcp.mcpb",
14
+ "identifier": "https://github.com/crisnahine/rails-ai-context/releases/download/v0.10.2/rails-ai-context-mcp.mcpb",
15
15
  "fileSha256": "dd711a0ad6c4de943ae4da94eaf59a6dc9494b9d57f726e24649ed4e2f156990",
16
16
  "transport": {
17
17
  "type": "stdio"
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: 0.10.1
4
+ version: 0.10.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - crisnahine