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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +72 -53
- data/CLAUDE.md +1 -1
- data/README.md +268 -197
- data/demo-trace.gif +0 -0
- data/demo-trace.tape +21 -0
- data/demo.gif +0 -0
- data/demo.tape +33 -0
- data/docs/GUIDE.md +9 -9
- data/lib/generators/rails_ai_context/install/install_generator.rb +2 -1
- data/lib/rails_ai_context/configuration.rb +1 -1
- data/lib/rails_ai_context/doctor.rb +4 -2
- data/lib/rails_ai_context/fingerprinter.rb +2 -1
- data/lib/rails_ai_context/introspectors/accessibility_introspector.rb +2 -1
- data/lib/rails_ai_context/introspectors/action_mailbox_introspector.rb +2 -1
- data/lib/rails_ai_context/introspectors/action_text_introspector.rb +2 -1
- data/lib/rails_ai_context/introspectors/active_storage_introspector.rb +6 -3
- data/lib/rails_ai_context/introspectors/api_introspector.rb +8 -4
- data/lib/rails_ai_context/introspectors/asset_pipeline_introspector.rb +6 -3
- data/lib/rails_ai_context/introspectors/auth_introspector.rb +14 -7
- data/lib/rails_ai_context/introspectors/config_introspector.rb +12 -6
- data/lib/rails_ai_context/introspectors/controller_introspector.rb +20 -10
- data/lib/rails_ai_context/introspectors/convention_detector.rb +2 -1
- data/lib/rails_ai_context/introspectors/design_token_introspector.rb +8 -4
- data/lib/rails_ai_context/introspectors/devops_introspector.rb +6 -3
- data/lib/rails_ai_context/introspectors/engine_introspector.rb +4 -2
- data/lib/rails_ai_context/introspectors/frontend_framework_introspector.rb +2 -1
- data/lib/rails_ai_context/introspectors/i18n_introspector.rb +2 -1
- data/lib/rails_ai_context/introspectors/job_introspector.rb +8 -4
- data/lib/rails_ai_context/introspectors/middleware_introspector.rb +4 -2
- data/lib/rails_ai_context/introspectors/migration_introspector.rb +2 -1
- data/lib/rails_ai_context/introspectors/model_introspector.rb +20 -10
- data/lib/rails_ai_context/introspectors/multi_database_introspector.rb +12 -6
- data/lib/rails_ai_context/introspectors/performance_introspector.rb +6 -3
- data/lib/rails_ai_context/introspectors/route_introspector.rb +4 -2
- data/lib/rails_ai_context/introspectors/schema_introspector.rb +14 -7
- data/lib/rails_ai_context/introspectors/seeds_introspector.rb +2 -1
- data/lib/rails_ai_context/introspectors/stimulus_introspector.rb +8 -4
- data/lib/rails_ai_context/introspectors/test_introspector.rb +8 -4
- data/lib/rails_ai_context/introspectors/turbo_introspector.rb +22 -11
- data/lib/rails_ai_context/introspectors/view_introspector.rb +8 -4
- data/lib/rails_ai_context/introspectors/view_template_introspector.rb +10 -5
- data/lib/rails_ai_context/tasks/rails_ai_context.rake +8 -4
- data/lib/rails_ai_context/tools/analyze_feature.rb +66 -19
- data/lib/rails_ai_context/tools/diagnose.rb +4 -2
- data/lib/rails_ai_context/tools/get_callbacks.rb +4 -2
- data/lib/rails_ai_context/tools/get_concern.rb +12 -6
- data/lib/rails_ai_context/tools/get_controllers.rb +10 -5
- data/lib/rails_ai_context/tools/get_conventions.rb +4 -2
- data/lib/rails_ai_context/tools/get_design_system.rb +2 -1
- data/lib/rails_ai_context/tools/get_env.rb +8 -4
- data/lib/rails_ai_context/tools/get_helper_methods.rb +6 -3
- data/lib/rails_ai_context/tools/get_job_pattern.rb +2 -1
- data/lib/rails_ai_context/tools/get_model_details.rb +10 -5
- data/lib/rails_ai_context/tools/get_partial_interface.rb +14 -7
- data/lib/rails_ai_context/tools/get_schema.rb +2 -1
- data/lib/rails_ai_context/tools/get_service_pattern.rb +2 -1
- data/lib/rails_ai_context/tools/get_stimulus.rb +2 -1
- data/lib/rails_ai_context/tools/get_test_info.rb +4 -2
- data/lib/rails_ai_context/tools/get_turbo_map.rb +22 -11
- data/lib/rails_ai_context/tools/get_view.rb +6 -3
- data/lib/rails_ai_context/tools/migration_advisor.rb +2 -1
- data/lib/rails_ai_context/tools/onboard.rb +2 -1
- data/lib/rails_ai_context/tools/performance_check.rb +2 -1
- data/lib/rails_ai_context/tools/runtime_info.rb +10 -5
- data/lib/rails_ai_context/tools/search_code.rb +8 -4
- data/lib/rails_ai_context/tools/search_docs.rb +2 -1
- data/lib/rails_ai_context/tools/session_context.rb +2 -1
- data/lib/rails_ai_context/tools/validate.rb +16 -8
- data/lib/rails_ai_context/version.rb +1 -1
- metadata +5 -1
|
@@ -490,7 +490,8 @@ module RailsAiContext
|
|
|
490
490
|
match = line.match(/broadcasts_refreshes_to\s+:?(\w+)/)
|
|
491
491
|
match ? match[1] : nil
|
|
492
492
|
end
|
|
493
|
-
rescue
|
|
493
|
+
rescue => e
|
|
494
|
+
$stderr.puts "[rails-ai-context] extract_stream_name_from_macro failed: #{e.message}" if ENV["DEBUG"]
|
|
494
495
|
nil
|
|
495
496
|
end
|
|
496
497
|
|
|
@@ -515,7 +516,8 @@ module RailsAiContext
|
|
|
515
516
|
pattern = /#{Regexp.escape(method)}\s*\(?\s*:?["']?(\w+)["']?/
|
|
516
517
|
match = line.match(pattern)
|
|
517
518
|
match ? match[1] : "(dynamic)"
|
|
518
|
-
rescue
|
|
519
|
+
rescue => e
|
|
520
|
+
$stderr.puts "[rails-ai-context] extract_stream_from_broadcast failed: #{e.message}" if ENV["DEBUG"]
|
|
519
521
|
"(dynamic)"
|
|
520
522
|
end
|
|
521
523
|
|
|
@@ -523,7 +525,8 @@ module RailsAiContext
|
|
|
523
525
|
private_class_method def self.extract_target_from_broadcast(line)
|
|
524
526
|
match = line.match(/target:\s*["'](\w+)["']/)
|
|
525
527
|
match ? match[1] : nil
|
|
526
|
-
rescue
|
|
528
|
+
rescue => e
|
|
529
|
+
$stderr.puts "[rails-ai-context] extract_target_from_broadcast failed: #{e.message}" if ENV["DEBUG"]
|
|
527
530
|
nil
|
|
528
531
|
end
|
|
529
532
|
|
|
@@ -531,7 +534,8 @@ module RailsAiContext
|
|
|
531
534
|
private_class_method def self.extract_partial_from_broadcast(line)
|
|
532
535
|
match = line.match(/partial:\s*["']([^"']+)["']/)
|
|
533
536
|
match ? match[1] : nil
|
|
534
|
-
rescue
|
|
537
|
+
rescue => e
|
|
538
|
+
$stderr.puts "[rails-ai-context] extract_partial_from_broadcast failed: #{e.message}" if ENV["DEBUG"]
|
|
535
539
|
nil
|
|
536
540
|
end
|
|
537
541
|
|
|
@@ -559,7 +563,8 @@ module RailsAiContext
|
|
|
559
563
|
|
|
560
564
|
# Clean up and return meaningful stream name
|
|
561
565
|
args.gsub(/["']/, "").gsub(/\s*,\s*/, ", ").strip
|
|
562
|
-
rescue
|
|
566
|
+
rescue => e
|
|
567
|
+
$stderr.puts "[rails-ai-context] extract_stream_from_subscription failed: #{e.message}" if ENV["DEBUG"]
|
|
563
568
|
"(dynamic)"
|
|
564
569
|
end
|
|
565
570
|
|
|
@@ -570,7 +575,8 @@ module RailsAiContext
|
|
|
570
575
|
# turbo_frame_tag dom_id(@model)
|
|
571
576
|
match = line.match(/turbo_frame_tag\s+["':]*([^"',\s)]+)/)
|
|
572
577
|
match ? match[1] : "(dynamic)"
|
|
573
|
-
rescue
|
|
578
|
+
rescue => e
|
|
579
|
+
$stderr.puts "[rails-ai-context] extract_frame_id failed: #{e.message}" if ENV["DEBUG"]
|
|
574
580
|
"(dynamic)"
|
|
575
581
|
end
|
|
576
582
|
|
|
@@ -578,7 +584,8 @@ module RailsAiContext
|
|
|
578
584
|
private_class_method def self.extract_frame_src(line)
|
|
579
585
|
match = line.match(/src:\s*["']?([^"',\s)]+)["']?/)
|
|
580
586
|
match ? match[1] : nil
|
|
581
|
-
rescue
|
|
587
|
+
rescue => e
|
|
588
|
+
$stderr.puts "[rails-ai-context] extract_frame_src failed: #{e.message}" if ENV["DEBUG"]
|
|
582
589
|
nil
|
|
583
590
|
end
|
|
584
591
|
|
|
@@ -618,7 +625,8 @@ module RailsAiContext
|
|
|
618
625
|
end
|
|
619
626
|
|
|
620
627
|
warnings.sort
|
|
621
|
-
rescue
|
|
628
|
+
rescue => e
|
|
629
|
+
$stderr.puts "[rails-ai-context] detect_mismatches failed: #{e.message}" if ENV["DEBUG"]
|
|
622
630
|
[]
|
|
623
631
|
end
|
|
624
632
|
|
|
@@ -660,20 +668,23 @@ module RailsAiContext
|
|
|
660
668
|
end
|
|
661
669
|
|
|
662
670
|
wiring.sort_by { |k, _| k }.to_h
|
|
663
|
-
rescue
|
|
671
|
+
rescue => e
|
|
672
|
+
$stderr.puts "[rails-ai-context] build_stream_wiring failed: #{e.message}" if ENV["DEBUG"]
|
|
664
673
|
{}
|
|
665
674
|
end
|
|
666
675
|
|
|
667
676
|
private_class_method def self.extract_class_name(source)
|
|
668
677
|
match = source.match(/class\s+([\w:]+)/)
|
|
669
678
|
match[1] if match
|
|
670
|
-
rescue
|
|
679
|
+
rescue => e
|
|
680
|
+
$stderr.puts "[rails-ai-context] extract_class_name failed: #{e.message}" if ENV["DEBUG"]
|
|
671
681
|
nil
|
|
672
682
|
end
|
|
673
683
|
|
|
674
684
|
private_class_method def self.safe_read(path)
|
|
675
685
|
File.read(path, encoding: "UTF-8", invalid: :replace, undef: :replace)
|
|
676
|
-
rescue
|
|
686
|
+
rescue => e
|
|
687
|
+
$stderr.puts "[rails-ai-context] safe_read failed: #{e.message}" if ENV["DEBUG"]
|
|
677
688
|
nil
|
|
678
689
|
end
|
|
679
690
|
|
|
@@ -280,7 +280,8 @@ module RailsAiContext
|
|
|
280
280
|
private_class_method def self.read_view_content(relative_path)
|
|
281
281
|
full_path = Rails.root.join("app", "views", relative_path)
|
|
282
282
|
File.exist?(full_path) ? File.read(full_path) : "(file not found)"
|
|
283
|
-
rescue
|
|
283
|
+
rescue => e
|
|
284
|
+
$stderr.puts "[rails-ai-context] read_view_content failed: #{e.message}" if ENV["DEBUG"]
|
|
284
285
|
"(error reading file)"
|
|
285
286
|
end
|
|
286
287
|
|
|
@@ -311,7 +312,8 @@ module RailsAiContext
|
|
|
311
312
|
end
|
|
312
313
|
|
|
313
314
|
result
|
|
314
|
-
rescue
|
|
315
|
+
rescue => e
|
|
316
|
+
$stderr.puts "[rails-ai-context] extract_view_metadata failed: #{e.message}" if ENV["DEBUG"]
|
|
315
317
|
{ ivars: [], turbo: [], components: [], helpers: [] }
|
|
316
318
|
end
|
|
317
319
|
|
|
@@ -361,7 +363,8 @@ module RailsAiContext
|
|
|
361
363
|
end
|
|
362
364
|
|
|
363
365
|
locals.to_a.sort
|
|
364
|
-
rescue
|
|
366
|
+
rescue => e
|
|
367
|
+
$stderr.puts "[rails-ai-context] extract_partial_locals failed: #{e.message}" if ENV["DEBUG"]
|
|
365
368
|
[]
|
|
366
369
|
end
|
|
367
370
|
|
|
@@ -638,7 +638,8 @@ module RailsAiContext
|
|
|
638
638
|
name = File.basename(path, ".rb").camelize
|
|
639
639
|
name unless name == "ApplicationService" || name == "BaseService"
|
|
640
640
|
end
|
|
641
|
-
rescue
|
|
641
|
+
rescue => e
|
|
642
|
+
$stderr.puts "[rails-ai-context] extract_service_names failed: #{e.message}" if ENV["DEBUG"]
|
|
642
643
|
[]
|
|
643
644
|
end
|
|
644
645
|
|
|
@@ -115,7 +115,8 @@ module RailsAiContext
|
|
|
115
115
|
filter_lower = model_filter.downcase
|
|
116
116
|
table_form = begin
|
|
117
117
|
model_filter.underscore.pluralize.downcase
|
|
118
|
-
rescue
|
|
118
|
+
rescue => e
|
|
119
|
+
$stderr.puts "[rails-ai-context] filter_items failed: #{e.message}" if ENV["DEBUG"]
|
|
119
120
|
filter_lower
|
|
120
121
|
end
|
|
121
122
|
items.select { |i|
|
|
@@ -144,7 +144,8 @@ module RailsAiContext
|
|
|
144
144
|
begin
|
|
145
145
|
result = conn.select_all("SELECT name, SUM(pgsize) AS bytes FROM dbstat GROUP BY name ORDER BY bytes DESC")
|
|
146
146
|
return result.map { |r| { name: r["name"], bytes: r["bytes"].to_i } } if result.any?
|
|
147
|
-
rescue
|
|
147
|
+
rescue => e
|
|
148
|
+
$stderr.puts "[rails-ai-context] gather_table_sizes failed: #{e.message}" if ENV["DEBUG"]
|
|
148
149
|
nil
|
|
149
150
|
end
|
|
150
151
|
# Fallback: whole database size
|
|
@@ -156,7 +157,8 @@ module RailsAiContext
|
|
|
156
157
|
else
|
|
157
158
|
nil
|
|
158
159
|
end
|
|
159
|
-
rescue
|
|
160
|
+
rescue => e
|
|
161
|
+
$stderr.puts "[rails-ai-context] gather_table_sizes failed: #{e.message}" if ENV["DEBUG"]
|
|
160
162
|
nil
|
|
161
163
|
end
|
|
162
164
|
|
|
@@ -171,7 +173,8 @@ module RailsAiContext
|
|
|
171
173
|
ActiveRecord::Migrator.new(:up, context.migrations).pending_migrations
|
|
172
174
|
end
|
|
173
175
|
pending.map { |m| "#{m.version} — #{m.name}" }
|
|
174
|
-
rescue
|
|
176
|
+
rescue => e
|
|
177
|
+
$stderr.puts "[rails-ai-context] gather_pending_migrations failed: #{e.message}" if ENV["DEBUG"]
|
|
175
178
|
nil
|
|
176
179
|
end
|
|
177
180
|
|
|
@@ -183,7 +186,8 @@ module RailsAiContext
|
|
|
183
186
|
else
|
|
184
187
|
nil
|
|
185
188
|
end
|
|
186
|
-
rescue
|
|
189
|
+
rescue => e
|
|
190
|
+
$stderr.puts "[rails-ai-context] gather_index_usage failed: #{e.message}" if ENV["DEBUG"]
|
|
187
191
|
nil
|
|
188
192
|
end
|
|
189
193
|
|
|
@@ -228,7 +232,8 @@ module RailsAiContext
|
|
|
228
232
|
adapter_name = begin
|
|
229
233
|
name = ActiveJob::Base.queue_adapter_name
|
|
230
234
|
name.empty? ? "not configured" : name
|
|
231
|
-
rescue
|
|
235
|
+
rescue => e
|
|
236
|
+
$stderr.puts "[rails-ai-context] gather_jobs failed: #{e.message}" if ENV["DEBUG"]
|
|
232
237
|
"not available"
|
|
233
238
|
end
|
|
234
239
|
lines << "**Adapter:** #{adapter_name}"
|
|
@@ -454,7 +454,8 @@ module RailsAiContext
|
|
|
454
454
|
end
|
|
455
455
|
end
|
|
456
456
|
nil
|
|
457
|
-
rescue
|
|
457
|
+
rescue => e
|
|
458
|
+
$stderr.puts "[rails-ai-context] extract_class_context failed: #{e.message}" if ENV["DEBUG"]
|
|
458
459
|
nil
|
|
459
460
|
end
|
|
460
461
|
|
|
@@ -474,7 +475,8 @@ module RailsAiContext
|
|
|
474
475
|
end
|
|
475
476
|
end
|
|
476
477
|
methods
|
|
477
|
-
rescue
|
|
478
|
+
rescue => e
|
|
479
|
+
$stderr.puts "[rails-ai-context] extract_sibling_methods failed: #{e.message}" if ENV["DEBUG"]
|
|
478
480
|
[]
|
|
479
481
|
end
|
|
480
482
|
|
|
@@ -499,7 +501,8 @@ module RailsAiContext
|
|
|
499
501
|
return nil unless ctrl_routes&.any?
|
|
500
502
|
# Show the first 2 routes as hints
|
|
501
503
|
ctrl_routes.first(2).map { |r| "`#{r[:verb]} #{r[:path]}`" }.join(", ")
|
|
502
|
-
rescue
|
|
504
|
+
rescue => e
|
|
505
|
+
$stderr.puts "[rails-ai-context] find_routes_for_controller failed: #{e.message}" if ENV["DEBUG"]
|
|
503
506
|
nil
|
|
504
507
|
end
|
|
505
508
|
|
|
@@ -521,7 +524,8 @@ module RailsAiContext
|
|
|
521
524
|
end
|
|
522
525
|
|
|
523
526
|
result.join("\n")
|
|
524
|
-
rescue
|
|
527
|
+
rescue => e
|
|
528
|
+
$stderr.puts "[rails-ai-context] extract_method_body failed: #{e.message}" if ENV["DEBUG"]
|
|
525
529
|
nil
|
|
526
530
|
end
|
|
527
531
|
end
|
|
@@ -146,7 +146,8 @@ module RailsAiContext
|
|
|
146
146
|
return matches.first.sub("#{Rails.root}/", "") if matches.any?
|
|
147
147
|
|
|
148
148
|
nil
|
|
149
|
-
rescue
|
|
149
|
+
rescue => e
|
|
150
|
+
$stderr.puts "[rails-ai-context] find_file_suggestion failed: #{e.message}" if ENV["DEBUG"]
|
|
150
151
|
nil
|
|
151
152
|
end
|
|
152
153
|
|
|
@@ -460,7 +461,8 @@ module RailsAiContext
|
|
|
460
461
|
visitor = RailsSemanticVisitor.new
|
|
461
462
|
result.value.accept(visitor)
|
|
462
463
|
visitor
|
|
463
|
-
rescue
|
|
464
|
+
rescue => e
|
|
465
|
+
$stderr.puts "[rails-ai-context] parse_and_visit failed: #{e.message}" if ENV["DEBUG"]
|
|
464
466
|
nil
|
|
465
467
|
end
|
|
466
468
|
|
|
@@ -900,7 +902,8 @@ module RailsAiContext
|
|
|
900
902
|
warnings << "@#{ivar} used in view but not set in #{ctrl_class}. Fix: add `@#{ivar} = ...` to action"
|
|
901
903
|
end
|
|
902
904
|
warnings
|
|
903
|
-
rescue
|
|
905
|
+
rescue => e
|
|
906
|
+
$stderr.puts "[rails-ai-context] check_instance_variable_usage failed: #{e.message}" if ENV["DEBUG"]
|
|
904
907
|
[]
|
|
905
908
|
end
|
|
906
909
|
|
|
@@ -934,7 +937,8 @@ module RailsAiContext
|
|
|
934
937
|
end
|
|
935
938
|
end
|
|
936
939
|
warnings
|
|
937
|
-
rescue
|
|
940
|
+
rescue => e
|
|
941
|
+
$stderr.puts "[rails-ai-context] check_turbo_stream_channels failed: #{e.message}" if ENV["DEBUG"]
|
|
938
942
|
[]
|
|
939
943
|
end
|
|
940
944
|
|
|
@@ -959,7 +963,8 @@ module RailsAiContext
|
|
|
959
963
|
warnings << "#{file} uses turbo_stream_from but #{turbo_template} doesn't exist (Turbo Stream updates may need this)"
|
|
960
964
|
end
|
|
961
965
|
warnings
|
|
962
|
-
rescue
|
|
966
|
+
rescue => e
|
|
967
|
+
$stderr.puts "[rails-ai-context] check_respond_to_template_existence failed: #{e.message}" if ENV["DEBUG"]
|
|
963
968
|
[]
|
|
964
969
|
end
|
|
965
970
|
|
|
@@ -984,7 +989,8 @@ module RailsAiContext
|
|
|
984
989
|
end
|
|
985
990
|
end
|
|
986
991
|
warnings.first(3) # cap at 3 to avoid noise
|
|
987
|
-
rescue
|
|
992
|
+
rescue => e
|
|
993
|
+
$stderr.puts "[rails-ai-context] check_memory_loading failed: #{e.message}" if ENV["DEBUG"]
|
|
988
994
|
[]
|
|
989
995
|
end
|
|
990
996
|
|
|
@@ -1013,7 +1019,8 @@ module RailsAiContext
|
|
|
1013
1019
|
end
|
|
1014
1020
|
|
|
1015
1021
|
warnings.first(5)
|
|
1016
|
-
rescue
|
|
1022
|
+
rescue => e
|
|
1023
|
+
$stderr.puts "[rails-ai-context] check_performance_warnings failed: #{e.message}" if ENV["DEBUG"]
|
|
1017
1024
|
[]
|
|
1018
1025
|
end
|
|
1019
1026
|
|
|
@@ -1044,7 +1051,8 @@ module RailsAiContext
|
|
|
1044
1051
|
loc = w.line ? "#{w.file.relative}:#{w.line}" : w.file.relative
|
|
1045
1052
|
"[#{w.confidence_name}] #{w.warning_type} — #{loc}: #{w.message}"
|
|
1046
1053
|
end
|
|
1047
|
-
rescue
|
|
1054
|
+
rescue => e
|
|
1055
|
+
$stderr.puts "[rails-ai-context] check_brakeman_security failed: #{e.message}" if ENV["DEBUG"]
|
|
1048
1056
|
[]
|
|
1049
1057
|
end
|
|
1050
1058
|
|
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: 4.3.
|
|
4
|
+
version: 4.3.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- crisnahine
|
|
@@ -193,6 +193,10 @@ files:
|
|
|
193
193
|
- README.md
|
|
194
194
|
- Rakefile
|
|
195
195
|
- SECURITY.md
|
|
196
|
+
- demo-trace.gif
|
|
197
|
+
- demo-trace.tape
|
|
198
|
+
- demo.gif
|
|
199
|
+
- demo.tape
|
|
196
200
|
- docs/GUIDE.md
|
|
197
201
|
- docs/token-comparison.jpeg
|
|
198
202
|
- exe/rails-ai-context
|