rails-ai-context 4.3.2 → 4.3.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.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +72 -53
  3. data/CLAUDE.md +1 -1
  4. data/README.md +268 -197
  5. data/demo-trace.gif +0 -0
  6. data/demo-trace.tape +21 -0
  7. data/demo.gif +0 -0
  8. data/demo.tape +33 -0
  9. data/docs/GUIDE.md +9 -9
  10. data/lib/generators/rails_ai_context/install/install_generator.rb +2 -1
  11. data/lib/rails_ai_context/configuration.rb +1 -1
  12. data/lib/rails_ai_context/doctor.rb +4 -2
  13. data/lib/rails_ai_context/fingerprinter.rb +2 -1
  14. data/lib/rails_ai_context/introspectors/accessibility_introspector.rb +2 -1
  15. data/lib/rails_ai_context/introspectors/action_mailbox_introspector.rb +2 -1
  16. data/lib/rails_ai_context/introspectors/action_text_introspector.rb +2 -1
  17. data/lib/rails_ai_context/introspectors/active_storage_introspector.rb +6 -3
  18. data/lib/rails_ai_context/introspectors/api_introspector.rb +8 -4
  19. data/lib/rails_ai_context/introspectors/asset_pipeline_introspector.rb +6 -3
  20. data/lib/rails_ai_context/introspectors/auth_introspector.rb +14 -7
  21. data/lib/rails_ai_context/introspectors/config_introspector.rb +12 -6
  22. data/lib/rails_ai_context/introspectors/controller_introspector.rb +20 -10
  23. data/lib/rails_ai_context/introspectors/convention_detector.rb +2 -1
  24. data/lib/rails_ai_context/introspectors/design_token_introspector.rb +8 -4
  25. data/lib/rails_ai_context/introspectors/devops_introspector.rb +6 -3
  26. data/lib/rails_ai_context/introspectors/engine_introspector.rb +4 -2
  27. data/lib/rails_ai_context/introspectors/frontend_framework_introspector.rb +2 -1
  28. data/lib/rails_ai_context/introspectors/i18n_introspector.rb +2 -1
  29. data/lib/rails_ai_context/introspectors/job_introspector.rb +8 -4
  30. data/lib/rails_ai_context/introspectors/middleware_introspector.rb +4 -2
  31. data/lib/rails_ai_context/introspectors/migration_introspector.rb +2 -1
  32. data/lib/rails_ai_context/introspectors/model_introspector.rb +20 -10
  33. data/lib/rails_ai_context/introspectors/multi_database_introspector.rb +12 -6
  34. data/lib/rails_ai_context/introspectors/performance_introspector.rb +6 -3
  35. data/lib/rails_ai_context/introspectors/route_introspector.rb +4 -2
  36. data/lib/rails_ai_context/introspectors/schema_introspector.rb +14 -7
  37. data/lib/rails_ai_context/introspectors/seeds_introspector.rb +2 -1
  38. data/lib/rails_ai_context/introspectors/stimulus_introspector.rb +8 -4
  39. data/lib/rails_ai_context/introspectors/test_introspector.rb +8 -4
  40. data/lib/rails_ai_context/introspectors/turbo_introspector.rb +22 -11
  41. data/lib/rails_ai_context/introspectors/view_introspector.rb +8 -4
  42. data/lib/rails_ai_context/introspectors/view_template_introspector.rb +10 -5
  43. data/lib/rails_ai_context/tasks/rails_ai_context.rake +8 -4
  44. data/lib/rails_ai_context/tools/analyze_feature.rb +66 -19
  45. data/lib/rails_ai_context/tools/diagnose.rb +4 -2
  46. data/lib/rails_ai_context/tools/get_callbacks.rb +4 -2
  47. data/lib/rails_ai_context/tools/get_concern.rb +12 -6
  48. data/lib/rails_ai_context/tools/get_controllers.rb +10 -5
  49. data/lib/rails_ai_context/tools/get_conventions.rb +4 -2
  50. data/lib/rails_ai_context/tools/get_design_system.rb +2 -1
  51. data/lib/rails_ai_context/tools/get_env.rb +8 -4
  52. data/lib/rails_ai_context/tools/get_helper_methods.rb +6 -3
  53. data/lib/rails_ai_context/tools/get_job_pattern.rb +2 -1
  54. data/lib/rails_ai_context/tools/get_model_details.rb +10 -5
  55. data/lib/rails_ai_context/tools/get_partial_interface.rb +14 -7
  56. data/lib/rails_ai_context/tools/get_schema.rb +2 -1
  57. data/lib/rails_ai_context/tools/get_service_pattern.rb +2 -1
  58. data/lib/rails_ai_context/tools/get_stimulus.rb +2 -1
  59. data/lib/rails_ai_context/tools/get_test_info.rb +4 -2
  60. data/lib/rails_ai_context/tools/get_turbo_map.rb +22 -11
  61. data/lib/rails_ai_context/tools/get_view.rb +6 -3
  62. data/lib/rails_ai_context/tools/migration_advisor.rb +2 -1
  63. data/lib/rails_ai_context/tools/onboard.rb +2 -1
  64. data/lib/rails_ai_context/tools/performance_check.rb +2 -1
  65. data/lib/rails_ai_context/tools/runtime_info.rb +10 -5
  66. data/lib/rails_ai_context/tools/search_code.rb +8 -4
  67. data/lib/rails_ai_context/tools/search_docs.rb +2 -1
  68. data/lib/rails_ai_context/tools/session_context.rb +2 -1
  69. data/lib/rails_ai_context/tools/validate.rb +16 -8
  70. data/lib/rails_ai_context/version.rb +1 -1
  71. metadata +5 -1
@@ -65,7 +65,8 @@ module RailsAiContext
65
65
  name = middleware.name || middleware.klass.to_s
66
66
  { name: name, category: categorize_middleware(name) }
67
67
  end
68
- rescue
68
+ rescue => e
69
+ $stderr.puts "[rails-ai-context] extract_middleware_stack failed: #{e.message}" if ENV["DEBUG"]
69
70
  []
70
71
  end
71
72
 
@@ -74,7 +75,8 @@ module RailsAiContext
74
75
  total: app.middleware.size,
75
76
  custom: custom.size
76
77
  }
77
- rescue
78
+ rescue => e
79
+ $stderr.puts "[rails-ai-context] middleware_count failed: #{e.message}" if ENV["DEBUG"]
78
80
  {}
79
81
  end
80
82
 
@@ -93,7 +93,8 @@ module RailsAiContext
93
93
  content = File.read(schema_path)
94
94
  match = content.match(/version:\s*([\d_]+)/)
95
95
  match ? match[1].delete("_") : nil
96
- rescue
96
+ rescue => e
97
+ $stderr.puts "[rails-ai-context] current_schema_version failed: #{e.message}" if ENV["DEBUG"]
97
98
  nil
98
99
  end
99
100
 
@@ -39,7 +39,8 @@ module RailsAiContext
39
39
  else
40
40
  Rails.application.eager_load!
41
41
  end
42
- rescue
42
+ rescue => e
43
+ $stderr.puts "[rails-ai-context] eager_load_models! failed: #{e.message}" if ENV["DEBUG"]
43
44
  # In some environments (CI, Claude Code) eager_load may partially fail
44
45
  nil
45
46
  end
@@ -135,7 +136,8 @@ module RailsAiContext
135
136
  source.scan(/^\s*scope\s+:(\w+)\s*,\s*->\s*(?:\([^)]*\)\s*)?\{([^}]*)\}/m).map do |name, body|
136
137
  { name: name, body: body.strip }
137
138
  end
138
- rescue
139
+ rescue => e
140
+ $stderr.puts "[rails-ai-context] extract_scopes failed: #{e.message}" if ENV["DEBUG"]
139
141
  []
140
142
  end
141
143
 
@@ -146,7 +148,8 @@ module RailsAiContext
146
148
  return [] unless source_path && File.exist?(source_path)
147
149
 
148
150
  File.read(source_path).scan(/^\s*validate\s+:(\w+)/).flatten
149
- rescue
151
+ rescue => e
152
+ $stderr.puts "[rails-ai-context] extract_custom_validates failed: #{e.message}" if ENV["DEBUG"]
150
153
  []
151
154
  end
152
155
 
@@ -185,7 +188,8 @@ module RailsAiContext
185
188
  # If reflection returned nothing, fall back to source parsing
186
189
  return result if result.any?
187
190
  extract_callbacks_from_source(model)
188
- rescue
191
+ rescue => e
192
+ $stderr.puts "[rails-ai-context] extract_callbacks failed: #{e.message}" if ENV["DEBUG"]
189
193
  extract_callbacks_from_source(model)
190
194
  end
191
195
 
@@ -204,7 +208,8 @@ module RailsAiContext
204
208
  end
205
209
  end
206
210
  callbacks
207
- rescue
211
+ rescue => e
212
+ $stderr.puts "[rails-ai-context] extract_callbacks_from_source failed: #{e.message}" if ENV["DEBUG"]
208
213
  {}
209
214
  end
210
215
 
@@ -276,7 +281,8 @@ module RailsAiContext
276
281
  in_class_methods = false if in_class_methods && line.match?(/\A\s*end\s*$/) && !line.match?(/def/)
277
282
  end
278
283
  methods.uniq
279
- rescue
284
+ rescue => e
285
+ $stderr.puts "[rails-ai-context] extract_source_class_methods failed: #{e.message}" if ENV["DEBUG"]
280
286
  []
281
287
  end
282
288
 
@@ -332,7 +338,8 @@ module RailsAiContext
332
338
  end
333
339
  end
334
340
  methods.uniq
335
- rescue
341
+ rescue => e
342
+ $stderr.puts "[rails-ai-context] extract_source_instance_methods failed: #{e.message}" if ENV["DEBUG"]
336
343
  []
337
344
  end
338
345
 
@@ -350,7 +357,8 @@ module RailsAiContext
350
357
  ])
351
358
  end
352
359
  methods
353
- rescue
360
+ rescue => e
361
+ $stderr.puts "[rails-ai-context] generated_association_methods failed: #{e.message}" if ENV["DEBUG"]
354
362
  []
355
363
  end
356
364
 
@@ -390,7 +398,8 @@ module RailsAiContext
390
398
 
391
399
  # Remove empty arrays
392
400
  macros.reject { |_, v| v.is_a?(Array) && v.empty? }
393
- rescue
401
+ rescue => e
402
+ $stderr.puts "[rails-ai-context] extract_source_macros failed: #{e.message}" if ENV["DEBUG"]
394
403
  {}
395
404
  end
396
405
 
@@ -443,7 +452,8 @@ module RailsAiContext
443
452
  macros[:token_generation] = tokens if tokens.any?
444
453
 
445
454
  macros
446
- rescue
455
+ rescue => e
456
+ $stderr.puts "[rails-ai-context] extract_detailed_macros failed: #{e.message}" if ENV["DEBUG"]
447
457
  {}
448
458
  end
449
459
 
@@ -43,7 +43,8 @@ module RailsAiContext
43
43
  else
44
44
  parse_database_yml
45
45
  end
46
- rescue
46
+ rescue => e
47
+ $stderr.puts "[rails-ai-context] discover_databases failed: #{e.message}" if ENV["DEBUG"]
47
48
  parse_database_yml
48
49
  end
49
50
 
@@ -56,7 +57,8 @@ module RailsAiContext
56
57
  else
57
58
  []
58
59
  end
59
- rescue
60
+ rescue => e
61
+ $stderr.puts "[rails-ai-context] discover_replicas failed: #{e.message}" if ENV["DEBUG"]
60
62
  []
61
63
  end
62
64
 
@@ -66,7 +68,8 @@ module RailsAiContext
66
68
 
67
69
  content = File.read(database_yml)
68
70
  { detected: true, note: "Sharding configuration found in database.yml" } if content.match?(/shard/i)
69
- rescue
71
+ rescue => e
72
+ $stderr.puts "[rails-ai-context] detect_sharding failed: #{e.message}" if ENV["DEBUG"]
70
73
  nil
71
74
  end
72
75
 
@@ -90,7 +93,8 @@ module RailsAiContext
90
93
  if content.match?(/connected_to\b/)
91
94
  connections << { model: model_name, uses_connected_to: true } unless connections.any? { |c| c[:model] == model_name }
92
95
  end
93
- rescue
96
+ rescue => e
97
+ $stderr.puts "[rails-ai-context] detect_model_connections failed: #{e.message}" if ENV["DEBUG"]
94
98
  next
95
99
  end
96
100
 
@@ -124,7 +128,8 @@ module RailsAiContext
124
128
  end
125
129
 
126
130
  databases
127
- rescue
131
+ rescue => e
132
+ $stderr.puts "[rails-ai-context] parse_database_yml failed: #{e.message}" if ENV["DEBUG"]
128
133
  []
129
134
  end
130
135
 
@@ -136,7 +141,8 @@ module RailsAiContext
136
141
  else
137
142
  name
138
143
  end
139
- rescue
144
+ rescue => e
145
+ $stderr.puts "[rails-ai-context] anonymize_db_name failed: #{e.message}" if ENV["DEBUG"]
140
146
  "external"
141
147
  end
142
148
  end
@@ -91,7 +91,8 @@ module RailsAiContext
91
91
  scopes_with_includes: content.scan(/scope\s+:\w+.*\.includes\(/).any?,
92
92
  content: content
93
93
  }
94
- rescue
94
+ rescue => e
95
+ $stderr.puts "[rails-ai-context] load_model_data failed: #{e.message}" if ENV["DEBUG"]
95
96
  nil
96
97
  end
97
98
  end
@@ -218,7 +219,8 @@ module RailsAiContext
218
219
  content = File.read(path)
219
220
  match = content.match(/class\s+(\w+)\s*<\s*ApplicationRecord/)
220
221
  match[1] if match
221
- rescue
222
+ rescue => e
223
+ $stderr.puts "[rails-ai-context] detect_model_all_in_controllers failed: #{e.message}" if ENV["DEBUG"]
222
224
  nil
223
225
  end
224
226
  else
@@ -270,7 +272,8 @@ module RailsAiContext
270
272
  associations: has_many_assocs,
271
273
  suggestion: "Consider eager loading when rendering #{class_name} with associations: #{has_many_assocs.join(", ")}"
272
274
  }
273
- rescue
275
+ rescue => e
276
+ $stderr.puts "[rails-ai-context] detect_eager_load_candidates failed: #{e.message}" if ENV["DEBUG"]
274
277
  next
275
278
  end
276
279
 
@@ -47,7 +47,8 @@ module RailsAiContext
47
47
  def extract_constraints(route)
48
48
  constraints = route.constraints.to_s
49
49
  constraints.empty? ? nil : constraints
50
- rescue
50
+ rescue => e
51
+ $stderr.puts "[rails-ai-context] extract_constraints failed: #{e.message}" if ENV["DEBUG"]
51
52
  nil
52
53
  end
53
54
 
@@ -77,7 +78,8 @@ module RailsAiContext
77
78
  engine: engine_class.name,
78
79
  path: r.path.spec.to_s
79
80
  }
80
- rescue
81
+ rescue => e
82
+ $stderr.puts "[rails-ai-context] detect_mounted_engines failed: #{e.message}" if ENV["DEBUG"]
81
83
  nil
82
84
  end
83
85
  end
@@ -33,13 +33,15 @@ module RailsAiContext
33
33
 
34
34
  def active_record_connected?
35
35
  defined?(ActiveRecord::Base) && ActiveRecord::Base.connected?
36
- rescue
36
+ rescue => e
37
+ $stderr.puts "[rails-ai-context] active_record_connected? failed: #{e.message}" if ENV["DEBUG"]
37
38
  false
38
39
  end
39
40
 
40
41
  def adapter_name
41
42
  ActiveRecord::Base.connection.adapter_name
42
- rescue
43
+ rescue => e
44
+ $stderr.puts "[rails-ai-context] adapter_name failed: #{e.message}" if ENV["DEBUG"]
43
45
  "unknown"
44
46
  end
45
47
 
@@ -106,7 +108,8 @@ module RailsAiContext
106
108
  on_update: fk.on_update
107
109
  }.compact
108
110
  end
109
- rescue
111
+ rescue => e
112
+ $stderr.puts "[rails-ai-context] extract_foreign_keys failed: #{e.message}" if ENV["DEBUG"]
110
113
  [] # Some adapters don't support foreign_keys
111
114
  end
112
115
 
@@ -136,7 +139,8 @@ module RailsAiContext
136
139
  end
137
140
 
138
141
  defaults
139
- rescue
142
+ rescue => e
143
+ $stderr.puts "[rails-ai-context] parse_schema_defaults_for_table failed: #{e.message}" if ENV["DEBUG"]
140
144
  {}
141
145
  end
142
146
 
@@ -333,7 +337,8 @@ module RailsAiContext
333
337
  end
334
338
 
335
339
  constraints
336
- rescue
340
+ rescue => e
341
+ $stderr.puts "[rails-ai-context] parse_check_constraints failed: #{e.message}" if ENV["DEBUG"]
337
342
  []
338
343
  end
339
344
 
@@ -352,7 +357,8 @@ module RailsAiContext
352
357
  end
353
358
 
354
359
  enums
355
- rescue
360
+ rescue => e
361
+ $stderr.puts "[rails-ai-context] parse_enum_types failed: #{e.message}" if ENV["DEBUG"]
356
362
  []
357
363
  end
358
364
 
@@ -382,7 +388,8 @@ module RailsAiContext
382
388
  end
383
389
 
384
390
  columns
385
- rescue
391
+ rescue => e
392
+ $stderr.puts "[rails-ai-context] parse_generated_columns failed: #{e.message}" if ENV["DEBUG"]
386
393
  []
387
394
  end
388
395
 
@@ -78,7 +78,8 @@ module RailsAiContext
78
78
  model_name = match[0]
79
79
  models << model_name unless non_models.include?(model_name)
80
80
  end
81
- rescue
81
+ rescue => e
82
+ $stderr.puts "[rails-ai-context] detect_seeded_models failed: #{e.message}" if ENV["DEBUG"]
82
83
  next
83
84
  end
84
85
 
@@ -127,7 +127,8 @@ module RailsAiContext
127
127
  end
128
128
  end
129
129
  imports
130
- rescue
130
+ rescue => e
131
+ $stderr.puts "[rails-ai-context] extract_import_graph failed: #{e.message}" if ENV["DEBUG"]
131
132
  []
132
133
  end
133
134
 
@@ -138,14 +139,16 @@ module RailsAiContext
138
139
  methods = content.scan(/^\s+(?:async\s+)?(\w+)\s*\([^)]*\)\s*\{/).flatten
139
140
  method_count = methods.count { |m| !JS_KEYWORDS.include?(m) }
140
141
  { loc: loc, method_count: method_count }
141
- rescue
142
+ rescue => e
143
+ $stderr.puts "[rails-ai-context] extract_complexity failed: #{e.message}" if ENV["DEBUG"]
142
144
  { loc: 0, method_count: 0 }
143
145
  end
144
146
 
145
147
  def extract_turbo_event_listeners(content)
146
148
  events = content.scan(/["']turbo:([\w:-]+)["']/).flatten.uniq
147
149
  events.map { |e| "turbo:#{e}" }
148
- rescue
150
+ rescue => e
151
+ $stderr.puts "[rails-ai-context] extract_turbo_event_listeners failed: #{e.message}" if ENV["DEBUG"]
149
152
  []
150
153
  end
151
154
 
@@ -166,7 +169,8 @@ module RailsAiContext
166
169
  end
167
170
 
168
171
  compositions.uniq
169
- rescue
172
+ rescue => e
173
+ $stderr.puts "[rails-ai-context] extract_cross_controller_composition failed: #{e.message}" if ENV["DEBUG"]
170
174
  []
171
175
  end
172
176
  end
@@ -113,7 +113,8 @@ module RailsAiContext
113
113
  file = path.sub("#{root}/", "")
114
114
  factories = File.read(path).scan(/factory\s+:(\w+)/).flatten
115
115
  names[file] = factories if factories.any?
116
- rescue
116
+ rescue => e
117
+ $stderr.puts "[rails-ai-context] detect_factory_names failed: #{e.message}" if ENV["DEBUG"]
117
118
  next
118
119
  end
119
120
  return names if names.any?
@@ -200,7 +201,8 @@ module RailsAiContext
200
201
  content = File.read(gemfile_lock)
201
202
  return "simplecov" if content.include?("simplecov (")
202
203
  nil
203
- rescue
204
+ rescue => e
205
+ $stderr.puts "[rails-ai-context] detect_coverage failed: #{e.message}" if ENV["DEBUG"]
204
206
  nil
205
207
  end
206
208
 
@@ -219,7 +221,8 @@ module RailsAiContext
219
221
  return traits if traits.any?
220
222
  end
221
223
  nil
222
- rescue
224
+ rescue => e
225
+ $stderr.puts "[rails-ai-context] detect_factory_traits failed: #{e.message}" if ENV["DEBUG"]
223
226
  nil
224
227
  end
225
228
 
@@ -234,7 +237,8 @@ module RailsAiContext
234
237
  end
235
238
  end
236
239
  counts
237
- rescue
240
+ rescue => e
241
+ $stderr.puts "[rails-ai-context] detect_test_count_by_category failed: #{e.message}" if ENV["DEBUG"]
238
242
  {}
239
243
  end
240
244
  end
@@ -49,7 +49,8 @@ module RailsAiContext
49
49
  end
50
50
 
51
51
  frames.sort_by { |f| f[:id] }
52
- rescue
52
+ rescue => e
53
+ $stderr.puts "[rails-ai-context] extract_turbo_frames failed: #{e.message}" if ENV["DEBUG"]
53
54
  []
54
55
  end
55
56
 
@@ -77,7 +78,8 @@ module RailsAiContext
77
78
  end
78
79
 
79
80
  broadcasts.sort_by { |b| b[:model] }
80
- rescue
81
+ rescue => e
82
+ $stderr.puts "[rails-ai-context] extract_model_broadcasts failed: #{e.message}" if ENV["DEBUG"]
81
83
  []
82
84
  end
83
85
 
@@ -89,7 +91,8 @@ module RailsAiContext
89
91
  content = File.read(path) rescue next
90
92
  content.include?('name="turbo-refresh-method"') && content.include?('content="morph"')
91
93
  end
92
- rescue
94
+ rescue => e
95
+ $stderr.puts "[rails-ai-context] detect_morph_meta failed: #{e.message}" if ENV["DEBUG"]
93
96
  false
94
97
  end
95
98
 
@@ -122,7 +125,8 @@ module RailsAiContext
122
125
  end
123
126
 
124
127
  elements.uniq
125
- rescue
128
+ rescue => e
129
+ $stderr.puts "[rails-ai-context] extract_permanent_elements failed: #{e.message}" if ENV["DEBUG"]
126
130
  []
127
131
  end
128
132
 
@@ -146,7 +150,8 @@ module RailsAiContext
146
150
  end
147
151
 
148
152
  counts
149
- rescue
153
+ rescue => e
154
+ $stderr.puts "[rails-ai-context] extract_turbo_drive_settings failed: #{e.message}" if ENV["DEBUG"]
150
155
  { "data-turbo-false": 0, "data-turbo-action": 0, "data-turbo-preload": 0 }
151
156
  end
152
157
 
@@ -159,7 +164,8 @@ module RailsAiContext
159
164
  native_navigation: detect_native_navigation(controllers_dir),
160
165
  native_conditionals: detect_native_conditionals
161
166
  }
162
- rescue
167
+ rescue => e
168
+ $stderr.puts "[rails-ai-context] detect_turbo_native failed: #{e.message}" if ENV["DEBUG"]
163
169
  { detected: false, native_helpers: [], native_navigation: [], native_conditionals: 0 }
164
170
  end
165
171
 
@@ -170,7 +176,8 @@ module RailsAiContext
170
176
  content = File.read(path) rescue next
171
177
  content.match?(/include\s+Turbo::Native::Navigation/)
172
178
  end
173
- rescue
179
+ rescue => e
180
+ $stderr.puts "[rails-ai-context] detect_native_include failed: #{e.message}" if ENV["DEBUG"]
174
181
  false
175
182
  end
176
183
 
@@ -183,7 +190,8 @@ module RailsAiContext
183
190
  path.sub("#{root}/", "")
184
191
  end
185
192
  end.sort
186
- rescue
193
+ rescue => e
194
+ $stderr.puts "[rails-ai-context] detect_native_helpers failed: #{e.message}" if ENV["DEBUG"]
187
195
  []
188
196
  end
189
197
 
@@ -207,7 +215,8 @@ module RailsAiContext
207
215
  end
208
216
 
209
217
  results.sort_by { |r| [ r[:file], r[:method] ] }
210
- rescue
218
+ rescue => e
219
+ $stderr.puts "[rails-ai-context] detect_native_navigation failed: #{e.message}" if ENV["DEBUG"]
211
220
  []
212
221
  end
213
222
 
@@ -221,7 +230,8 @@ module RailsAiContext
221
230
  end
222
231
 
223
232
  count
224
- rescue
233
+ rescue => e
234
+ $stderr.puts "[rails-ai-context] detect_native_conditionals failed: #{e.message}" if ENV["DEBUG"]
225
235
  0
226
236
  end
227
237
 
@@ -248,7 +258,8 @@ module RailsAiContext
248
258
  end
249
259
 
250
260
  responses.uniq.sort_by { |r| [ r[:controller], r[:action] ] }
251
- rescue
261
+ rescue => e
262
+ $stderr.puts "[rails-ai-context] extract_turbo_stream_responses failed: #{e.message}" if ENV["DEBUG"]
252
263
  []
253
264
  end
254
265
  end
@@ -98,7 +98,8 @@ module RailsAiContext
98
98
  file: relative,
99
99
  methods: methods
100
100
  }
101
- rescue
101
+ rescue => e
102
+ $stderr.puts "[rails-ai-context] extract_helpers failed: #{e.message}" if ENV["DEBUG"]
102
103
  nil
103
104
  end.sort_by { |h| h[:file] }
104
105
  end
@@ -150,7 +151,8 @@ module RailsAiContext
150
151
  end
151
152
 
152
153
  counts.sort_by { |_, v| -v }.to_h
153
- rescue
154
+ rescue => e
155
+ $stderr.puts "[rails-ai-context] detect_form_builders failed: #{e.message}" if ENV["DEBUG"]
154
156
  {}
155
157
  end
156
158
 
@@ -168,7 +170,8 @@ module RailsAiContext
168
170
  end
169
171
 
170
172
  components.to_a.sort
171
- rescue
173
+ rescue => e
174
+ $stderr.puts "[rails-ai-context] detect_component_usage failed: #{e.message}" if ENV["DEBUG"]
172
175
  []
173
176
  end
174
177
 
@@ -183,7 +186,8 @@ module RailsAiContext
183
186
  name = basename.sub(/\.(html|xml|json)\.(erb|haml|slim)\z/, "").sub(/\.(erb|haml|slim)\z/, "")
184
187
  name
185
188
  end.uniq.sort
186
- rescue
189
+ rescue => e
190
+ $stderr.puts "[rails-ai-context] extract_layout_mapping failed: #{e.message}" if ENV["DEBUG"]
187
191
  []
188
192
  end
189
193
  end
@@ -569,7 +569,8 @@ module RailsAiContext
569
569
  builders[:simple_form_for] = content.scan(/\bsimple_form_for\b/).size
570
570
  builders[:formtastic] = content.scan(/\bsemantic_form_for\b/).size
571
571
  builders.reject { |_, v| v == 0 }
572
- rescue
572
+ rescue => e
573
+ $stderr.puts "[rails-ai-context] extract_form_builders failed: #{e.message}" if ENV["DEBUG"]
573
574
  {}
574
575
  end
575
576
 
@@ -580,7 +581,8 @@ module RailsAiContext
580
581
  tags[tag.to_sym] = count if count > 0
581
582
  end
582
583
  tags
583
- rescue
584
+ rescue => e
585
+ $stderr.puts "[rails-ai-context] extract_semantic_html failed: #{e.message}" if ENV["DEBUG"]
584
586
  {}
585
587
  end
586
588
 
@@ -593,7 +595,8 @@ module RailsAiContext
593
595
  sr_only_count = content.scan(/\bsr-only\b/).size
594
596
  patterns[:sr_only] = sr_only_count if sr_only_count > 0
595
597
  patterns
596
- rescue
598
+ rescue => e
599
+ $stderr.puts "[rails-ai-context] extract_accessibility_patterns failed: #{e.message}" if ENV["DEBUG"]
597
600
  {}
598
601
  end
599
602
 
@@ -636,7 +639,8 @@ module RailsAiContext
636
639
  end
637
640
 
638
641
  examples.values.map { |e| e.except(:score) }.first(5)
639
- rescue
642
+ rescue => e
643
+ $stderr.puts "[rails-ai-context] extract_canonical_examples failed: #{e.message}" if ENV["DEBUG"]
640
644
  []
641
645
  end
642
646
 
@@ -697,7 +701,8 @@ module RailsAiContext
697
701
  description = infer_partial_description(name, content)
698
702
  { name: name, lines: content.lines.size, description: description }
699
703
  end
700
- rescue
704
+ rescue => e
705
+ $stderr.puts "[rails-ai-context] discover_shared_partials failed: #{e.message}" if ENV["DEBUG"]
701
706
  []
702
707
  end
703
708
 
@@ -91,7 +91,8 @@ def save_tool_mode_to_initializer(mode)
91
91
  end
92
92
 
93
93
  File.write(init_path, content)
94
- rescue
94
+ rescue => e
95
+ $stderr.puts "[rails-ai-context] save_tool_mode_to_initializer failed: #{e.message}" if ENV["DEBUG"]
95
96
  nil
96
97
  end unless defined?(save_tool_mode_to_initializer)
97
98
 
@@ -113,7 +114,8 @@ def tool_mode_configured?
113
114
  content = File.read(init_path)
114
115
  # Check for uncommented tool_mode line (not just a comment)
115
116
  content.match?(/^\s*config\.tool_mode\s*=/)
116
- rescue
117
+ rescue => e
118
+ $stderr.puts "[rails-ai-context] tool_mode_configured? failed: #{e.message}" if ENV["DEBUG"]
117
119
  false
118
120
  end unless defined?(tool_mode_configured?)
119
121
 
@@ -136,7 +138,8 @@ def save_ai_tools_to_initializer(tools)
136
138
 
137
139
  File.write(init_path, content)
138
140
  puts "💾 Saved to config/initializers/rails_ai_context.rb"
139
- rescue
141
+ rescue => e
142
+ $stderr.puts "[rails-ai-context] save_ai_tools_to_initializer failed: #{e.message}" if ENV["DEBUG"]
140
143
  nil
141
144
  end unless defined?(save_ai_tools_to_initializer)
142
145
 
@@ -165,7 +168,8 @@ def add_ai_tool_to_initializer(format)
165
168
  File.write(init_path, content)
166
169
  puts "💾 Set config.ai_tools = %i[#{format_sym}]"
167
170
  end
168
- rescue
171
+ rescue => e
172
+ $stderr.puts "[rails-ai-context] add_ai_tool_to_initializer failed: #{e.message}" if ENV["DEBUG"]
169
173
  nil
170
174
  end unless defined?(add_ai_tool_to_initializer)
171
175