rails-ai-context 4.3.2 → 4.4.0
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 +127 -53
- data/CLAUDE.md +3 -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/cli/tool_runner.rb +1 -1
- data/lib/rails_ai_context/configuration.rb +25 -1
- data/lib/rails_ai_context/doctor.rb +4 -2
- data/lib/rails_ai_context/fingerprinter.rb +6 -1
- data/lib/rails_ai_context/introspectors/accessibility_introspector.rb +52 -1
- data/lib/rails_ai_context/introspectors/action_mailbox_introspector.rb +10 -2
- data/lib/rails_ai_context/introspectors/action_text_introspector.rb +22 -2
- data/lib/rails_ai_context/introspectors/active_storage_introspector.rb +50 -4
- data/lib/rails_ai_context/introspectors/api_introspector.rb +41 -5
- data/lib/rails_ai_context/introspectors/asset_pipeline_introspector.rb +10 -4
- data/lib/rails_ai_context/introspectors/auth_introspector.rb +62 -7
- data/lib/rails_ai_context/introspectors/component_introspector.rb +6 -0
- data/lib/rails_ai_context/introspectors/config_introspector.rb +59 -9
- data/lib/rails_ai_context/introspectors/controller_introspector.rb +45 -13
- data/lib/rails_ai_context/introspectors/convention_detector.rb +25 -2
- data/lib/rails_ai_context/introspectors/database_stats_introspector.rb +58 -4
- data/lib/rails_ai_context/introspectors/design_token_introspector.rb +27 -5
- data/lib/rails_ai_context/introspectors/devops_introspector.rb +15 -8
- data/lib/rails_ai_context/introspectors/engine_introspector.rb +12 -3
- data/lib/rails_ai_context/introspectors/frontend_framework_introspector.rb +36 -1
- data/lib/rails_ai_context/introspectors/gem_introspector.rb +47 -1
- data/lib/rails_ai_context/introspectors/i18n_introspector.rb +49 -3
- data/lib/rails_ai_context/introspectors/job_introspector.rb +48 -5
- data/lib/rails_ai_context/introspectors/middleware_introspector.rb +24 -3
- data/lib/rails_ai_context/introspectors/migration_introspector.rb +4 -1
- data/lib/rails_ai_context/introspectors/model_introspector.rb +108 -11
- data/lib/rails_ai_context/introspectors/multi_database_introspector.rb +57 -12
- data/lib/rails_ai_context/introspectors/performance_introspector.rb +34 -9
- data/lib/rails_ai_context/introspectors/rake_task_introspector.rb +12 -2
- data/lib/rails_ai_context/introspectors/route_introspector.rb +25 -8
- data/lib/rails_ai_context/introspectors/schema_introspector.rb +45 -7
- data/lib/rails_ai_context/introspectors/seeds_introspector.rb +5 -2
- data/lib/rails_ai_context/introspectors/stimulus_introspector.rb +59 -6
- data/lib/rails_ai_context/introspectors/test_introspector.rb +50 -5
- data/lib/rails_ai_context/introspectors/turbo_introspector.rb +44 -13
- data/lib/rails_ai_context/introspectors/view_introspector.rb +46 -7
- data/lib/rails_ai_context/introspectors/view_template_introspector.rb +25 -7
- data/lib/rails_ai_context/resources.rb +1 -1
- data/lib/rails_ai_context/server.rb +6 -3
- 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/base_tool.rb +1 -1
- 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/query.rb +5 -1
- data/lib/rails_ai_context/tools/read_logs.rb +3 -0
- 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
|
@@ -294,7 +294,8 @@ module RailsAiContext
|
|
|
294
294
|
end
|
|
295
295
|
|
|
296
296
|
methods
|
|
297
|
-
rescue
|
|
297
|
+
rescue => e
|
|
298
|
+
$stderr.puts "[rails-ai-context] parse_public_methods failed: #{e.message}" if ENV["DEBUG"]
|
|
298
299
|
[]
|
|
299
300
|
end
|
|
300
301
|
|
|
@@ -332,7 +333,8 @@ module RailsAiContext
|
|
|
332
333
|
end
|
|
333
334
|
|
|
334
335
|
methods
|
|
335
|
-
rescue
|
|
336
|
+
rescue => e
|
|
337
|
+
$stderr.puts "[rails-ai-context] parse_class_methods failed: #{e.message}" if ENV["DEBUG"]
|
|
336
338
|
[]
|
|
337
339
|
end
|
|
338
340
|
|
|
@@ -364,7 +366,8 @@ module RailsAiContext
|
|
|
364
366
|
end
|
|
365
367
|
|
|
366
368
|
macros
|
|
367
|
-
rescue
|
|
369
|
+
rescue => e
|
|
370
|
+
$stderr.puts "[rails-ai-context] parse_concern_macros failed: #{e.message}" if ENV["DEBUG"]
|
|
368
371
|
[]
|
|
369
372
|
end
|
|
370
373
|
|
|
@@ -379,7 +382,8 @@ module RailsAiContext
|
|
|
379
382
|
end
|
|
380
383
|
|
|
381
384
|
callbacks
|
|
382
|
-
rescue
|
|
385
|
+
rescue => e
|
|
386
|
+
$stderr.puts "[rails-ai-context] parse_concern_callbacks failed: #{e.message}" if ENV["DEBUG"]
|
|
383
387
|
[]
|
|
384
388
|
end
|
|
385
389
|
|
|
@@ -405,7 +409,8 @@ module RailsAiContext
|
|
|
405
409
|
end
|
|
406
410
|
|
|
407
411
|
result.join("\n")
|
|
408
|
-
rescue
|
|
412
|
+
rescue => e
|
|
413
|
+
$stderr.puts "[rails-ai-context] extract_method_source failed: #{e.message}" if ENV["DEBUG"]
|
|
409
414
|
nil
|
|
410
415
|
end
|
|
411
416
|
|
|
@@ -448,7 +453,8 @@ module RailsAiContext
|
|
|
448
453
|
end
|
|
449
454
|
|
|
450
455
|
includers.sort
|
|
451
|
-
rescue
|
|
456
|
+
rescue => e
|
|
457
|
+
$stderr.puts "[rails-ai-context] find_includers failed: #{e.message}" if ENV["DEBUG"]
|
|
452
458
|
[]
|
|
453
459
|
end
|
|
454
460
|
end
|
|
@@ -301,7 +301,8 @@ module RailsAiContext
|
|
|
301
301
|
next unless body
|
|
302
302
|
{ name: method_name, code: body[:code], start_line: body[:start_line], end_line: body[:end_line] }
|
|
303
303
|
end.first(5) # Limit to 5 to avoid overwhelming response
|
|
304
|
-
rescue
|
|
304
|
+
rescue => e
|
|
305
|
+
$stderr.puts "[rails-ai-context] detect_called_private_methods failed: #{e.message}" if ENV["DEBUG"]
|
|
305
306
|
[]
|
|
306
307
|
end
|
|
307
308
|
|
|
@@ -332,7 +333,8 @@ module RailsAiContext
|
|
|
332
333
|
end
|
|
333
334
|
end
|
|
334
335
|
filters
|
|
335
|
-
rescue
|
|
336
|
+
rescue => e
|
|
337
|
+
$stderr.puts "[rails-ai-context] detect_parent_filters failed: #{e.message}" if ENV["DEBUG"]
|
|
336
338
|
[]
|
|
337
339
|
end
|
|
338
340
|
|
|
@@ -359,7 +361,8 @@ module RailsAiContext
|
|
|
359
361
|
end
|
|
360
362
|
end
|
|
361
363
|
skipped
|
|
362
|
-
rescue
|
|
364
|
+
rescue => e
|
|
365
|
+
$stderr.puts "[rails-ai-context] detect_skipped_filters failed: #{e.message}" if ENV["DEBUG"]
|
|
363
366
|
[]
|
|
364
367
|
end
|
|
365
368
|
|
|
@@ -415,7 +418,8 @@ module RailsAiContext
|
|
|
415
418
|
end
|
|
416
419
|
|
|
417
420
|
{ redirects: redirects.uniq, renders: renders.uniq, side_effects: side_effects.uniq }
|
|
418
|
-
rescue
|
|
421
|
+
rescue => e
|
|
422
|
+
$stderr.puts "[rails-ai-context] extract_render_map failed: #{e.message}" if ENV["DEBUG"]
|
|
419
423
|
{ redirects: [], renders: [], side_effects: [] }
|
|
420
424
|
end
|
|
421
425
|
|
|
@@ -443,7 +447,8 @@ module RailsAiContext
|
|
|
443
447
|
start_line: start_idx + 1,
|
|
444
448
|
end_line: end_idx + 1
|
|
445
449
|
}
|
|
446
|
-
rescue
|
|
450
|
+
rescue => e
|
|
451
|
+
$stderr.puts "[rails-ai-context] extract_method_with_lines failed: #{e.message}" if ENV["DEBUG"]
|
|
447
452
|
nil
|
|
448
453
|
end
|
|
449
454
|
|
|
@@ -374,7 +374,8 @@ module RailsAiContext
|
|
|
374
374
|
end
|
|
375
375
|
|
|
376
376
|
info
|
|
377
|
-
rescue
|
|
377
|
+
rescue => e
|
|
378
|
+
$stderr.puts "[rails-ai-context] detect_locale_info failed: #{e.message}" if ENV["DEBUG"]
|
|
378
379
|
[]
|
|
379
380
|
end
|
|
380
381
|
|
|
@@ -431,7 +432,8 @@ module RailsAiContext
|
|
|
431
432
|
sections << "Detected from: #{detected_in.first(3).join(', ')}"
|
|
432
433
|
|
|
433
434
|
sections
|
|
434
|
-
rescue
|
|
435
|
+
rescue => e
|
|
436
|
+
$stderr.puts "[rails-ai-context] detect_test_pattern failed: #{e.message}" if ENV["DEBUG"]
|
|
435
437
|
[]
|
|
436
438
|
end
|
|
437
439
|
end
|
|
@@ -442,7 +442,8 @@ module RailsAiContext
|
|
|
442
442
|
end
|
|
443
443
|
|
|
444
444
|
services.uniq { |s| "#{s[:name]}:#{s[:file]}" }
|
|
445
|
-
rescue
|
|
445
|
+
rescue => e
|
|
446
|
+
$stderr.puts "[rails-ai-context] detect_http_clients failed: #{e.message}" if ENV["DEBUG"]
|
|
446
447
|
[]
|
|
447
448
|
end
|
|
448
449
|
|
|
@@ -459,7 +460,8 @@ module RailsAiContext
|
|
|
459
460
|
return nil if parts.size < 2
|
|
460
461
|
# Use the main domain part
|
|
461
462
|
parts[-2]&.capitalize
|
|
462
|
-
rescue
|
|
463
|
+
rescue => e
|
|
464
|
+
$stderr.puts "[rails-ai-context] extract_service_name_from_url failed: #{e.message}" if ENV["DEBUG"]
|
|
463
465
|
nil
|
|
464
466
|
end
|
|
465
467
|
end
|
|
@@ -484,7 +486,8 @@ module RailsAiContext
|
|
|
484
486
|
end
|
|
485
487
|
|
|
486
488
|
vars.to_a.sort
|
|
487
|
-
rescue
|
|
489
|
+
rescue => e
|
|
490
|
+
$stderr.puts "[rails-ai-context] find_env_vars_with_prefix failed: #{e.message}" if ENV["DEBUG"]
|
|
488
491
|
[]
|
|
489
492
|
end
|
|
490
493
|
|
|
@@ -639,7 +642,8 @@ module RailsAiContext
|
|
|
639
642
|
|
|
640
643
|
private_class_method def self.safe_read(path)
|
|
641
644
|
File.read(path, encoding: "UTF-8", invalid: :replace, undef: :replace)
|
|
642
|
-
rescue
|
|
645
|
+
rescue => e
|
|
646
|
+
$stderr.puts "[rails-ai-context] safe_read failed: #{e.message}" if ENV["DEBUG"]
|
|
643
647
|
nil
|
|
644
648
|
end
|
|
645
649
|
|
|
@@ -220,7 +220,8 @@ module RailsAiContext
|
|
|
220
220
|
end
|
|
221
221
|
|
|
222
222
|
methods
|
|
223
|
-
rescue
|
|
223
|
+
rescue => e
|
|
224
|
+
$stderr.puts "[rails-ai-context] parse_helper_methods failed: #{e.message}" if ENV["DEBUG"]
|
|
224
225
|
[]
|
|
225
226
|
end
|
|
226
227
|
|
|
@@ -250,7 +251,8 @@ module RailsAiContext
|
|
|
250
251
|
end
|
|
251
252
|
|
|
252
253
|
references
|
|
253
|
-
rescue
|
|
254
|
+
rescue => e
|
|
255
|
+
$stderr.puts "[rails-ai-context] find_view_references failed: #{e.message}" if ENV["DEBUG"]
|
|
254
256
|
{}
|
|
255
257
|
end
|
|
256
258
|
|
|
@@ -303,7 +305,8 @@ module RailsAiContext
|
|
|
303
305
|
end
|
|
304
306
|
|
|
305
307
|
detected
|
|
306
|
-
rescue
|
|
308
|
+
rescue => e
|
|
309
|
+
$stderr.puts "[rails-ai-context] detect_framework_helpers failed: #{e.message}" if ENV["DEBUG"]
|
|
307
310
|
{}
|
|
308
311
|
end
|
|
309
312
|
end
|
|
@@ -407,7 +407,8 @@ module RailsAiContext
|
|
|
407
407
|
|
|
408
408
|
private_class_method def self.safe_read(path)
|
|
409
409
|
File.read(path, encoding: "UTF-8", invalid: :replace, undef: :replace)
|
|
410
|
-
rescue
|
|
410
|
+
rescue => e
|
|
411
|
+
$stderr.puts "[rails-ai-context] safe_read failed: #{e.message}" if ENV["DEBUG"]
|
|
411
412
|
nil
|
|
412
413
|
end
|
|
413
414
|
|
|
@@ -393,7 +393,8 @@ module RailsAiContext
|
|
|
393
393
|
end
|
|
394
394
|
end
|
|
395
395
|
bodies
|
|
396
|
-
rescue
|
|
396
|
+
rescue => e
|
|
397
|
+
$stderr.puts "[rails-ai-context] extract_custom_validate_bodies failed: #{e.message}" if ENV["DEBUG"]
|
|
397
398
|
{}
|
|
398
399
|
end
|
|
399
400
|
|
|
@@ -414,7 +415,8 @@ module RailsAiContext
|
|
|
414
415
|
end
|
|
415
416
|
|
|
416
417
|
methods.empty? ? nil : methods
|
|
417
|
-
rescue
|
|
418
|
+
rescue => e
|
|
419
|
+
$stderr.puts "[rails-ai-context] extract_source_defined_methods failed: #{e.message}" if ENV["DEBUG"]
|
|
418
420
|
nil
|
|
419
421
|
end
|
|
420
422
|
|
|
@@ -439,7 +441,8 @@ module RailsAiContext
|
|
|
439
441
|
end
|
|
440
442
|
|
|
441
443
|
signatures
|
|
442
|
-
rescue
|
|
444
|
+
rescue => e
|
|
445
|
+
$stderr.puts "[rails-ai-context] extract_method_signatures failed: #{e.message}" if ENV["DEBUG"]
|
|
443
446
|
nil
|
|
444
447
|
end
|
|
445
448
|
|
|
@@ -469,7 +472,8 @@ module RailsAiContext
|
|
|
469
472
|
end
|
|
470
473
|
|
|
471
474
|
methods.empty? ? nil : methods
|
|
472
|
-
rescue
|
|
475
|
+
rescue => e
|
|
476
|
+
$stderr.puts "[rails-ai-context] extract_concern_methods failed: #{e.message}" if ENV["DEBUG"]
|
|
473
477
|
nil
|
|
474
478
|
end
|
|
475
479
|
|
|
@@ -512,7 +516,8 @@ module RailsAiContext
|
|
|
512
516
|
sections << { start: current_start, end: source_lines.size, label: current_section } if current_section
|
|
513
517
|
|
|
514
518
|
{ path: path, total_lines: source_lines.size, sections: sections }
|
|
515
|
-
rescue
|
|
519
|
+
rescue => e
|
|
520
|
+
$stderr.puts "[rails-ai-context] extract_model_structure failed: #{e.message}" if ENV["DEBUG"]
|
|
516
521
|
nil
|
|
517
522
|
end
|
|
518
523
|
end
|
|
@@ -267,7 +267,8 @@ module RailsAiContext
|
|
|
267
267
|
end
|
|
268
268
|
|
|
269
269
|
locals.uniq
|
|
270
|
-
rescue
|
|
270
|
+
rescue => e
|
|
271
|
+
$stderr.puts "[rails-ai-context] extract_magic_comment_locals failed: #{e.message}" if ENV["DEBUG"]
|
|
271
272
|
[]
|
|
272
273
|
end
|
|
273
274
|
|
|
@@ -324,7 +325,8 @@ module RailsAiContext
|
|
|
324
325
|
|
|
325
326
|
# Filter out things that are clearly method definitions or blocks
|
|
326
327
|
locals.reject { |l| l.match?(/\A(each|map|select|reject|find|collect|do|end)\z/) }.to_a.sort
|
|
327
|
-
rescue
|
|
328
|
+
rescue => e
|
|
329
|
+
$stderr.puts "[rails-ai-context] extract_local_variable_references failed: #{e.message}" if ENV["DEBUG"]
|
|
328
330
|
[]
|
|
329
331
|
end
|
|
330
332
|
|
|
@@ -387,7 +389,8 @@ module RailsAiContext
|
|
|
387
389
|
end
|
|
388
390
|
|
|
389
391
|
sites
|
|
390
|
-
rescue
|
|
392
|
+
rescue => e
|
|
393
|
+
$stderr.puts "[rails-ai-context] find_render_sites failed: #{e.message}" if ENV["DEBUG"]
|
|
391
394
|
[]
|
|
392
395
|
end
|
|
393
396
|
|
|
@@ -414,7 +417,8 @@ module RailsAiContext
|
|
|
414
417
|
end
|
|
415
418
|
|
|
416
419
|
locals.uniq
|
|
417
|
-
rescue
|
|
420
|
+
rescue => e
|
|
421
|
+
$stderr.puts "[rails-ai-context] extract_locals_from_render failed: #{e.message}" if ENV["DEBUG"]
|
|
418
422
|
[]
|
|
419
423
|
end
|
|
420
424
|
|
|
@@ -443,7 +447,8 @@ module RailsAiContext
|
|
|
443
447
|
end
|
|
444
448
|
|
|
445
449
|
calls
|
|
446
|
-
rescue
|
|
450
|
+
rescue => e
|
|
451
|
+
$stderr.puts "[rails-ai-context] extract_method_calls_on_locals failed: #{e.message}" if ENV["DEBUG"]
|
|
447
452
|
{}
|
|
448
453
|
end
|
|
449
454
|
|
|
@@ -456,13 +461,15 @@ module RailsAiContext
|
|
|
456
461
|
parts[-1] = parts[-1].delete_prefix("_").sub(/\..*\z/, "")
|
|
457
462
|
parts.join("/")
|
|
458
463
|
end.sort.first(30)
|
|
459
|
-
rescue
|
|
464
|
+
rescue => e
|
|
465
|
+
$stderr.puts "[rails-ai-context] find_available_partials failed: #{e.message}" if ENV["DEBUG"]
|
|
460
466
|
[]
|
|
461
467
|
end
|
|
462
468
|
|
|
463
469
|
private_class_method def self.safe_read(path)
|
|
464
470
|
File.read(path, encoding: "UTF-8", invalid: :replace, undef: :replace)
|
|
465
|
-
rescue
|
|
471
|
+
rescue => e
|
|
472
|
+
$stderr.puts "[rails-ai-context] safe_read failed: #{e.message}" if ENV["DEBUG"]
|
|
466
473
|
nil
|
|
467
474
|
end
|
|
468
475
|
|
|
@@ -205,7 +205,8 @@ module RailsAiContext
|
|
|
205
205
|
return [] unless models.is_a?(Hash)
|
|
206
206
|
|
|
207
207
|
models.select { |_, d| d.is_a?(Hash) && d[:table_name] == table_name }.keys
|
|
208
|
-
rescue
|
|
208
|
+
rescue => e
|
|
209
|
+
$stderr.puts "[rails-ai-context] models_for_table failed: #{e.message}" if ENV["DEBUG"]
|
|
209
210
|
[]
|
|
210
211
|
end
|
|
211
212
|
|
|
@@ -319,7 +319,8 @@ module RailsAiContext
|
|
|
319
319
|
|
|
320
320
|
private_class_method def self.safe_read(path)
|
|
321
321
|
File.read(path, encoding: "UTF-8", invalid: :replace, undef: :replace)
|
|
322
|
-
rescue
|
|
322
|
+
rescue => e
|
|
323
|
+
$stderr.puts "[rails-ai-context] safe_read failed: #{e.message}" if ENV["DEBUG"]
|
|
323
324
|
nil
|
|
324
325
|
end
|
|
325
326
|
|
|
@@ -236,7 +236,8 @@ module RailsAiContext
|
|
|
236
236
|
next unless content.include?(alt_pattern)
|
|
237
237
|
path.sub("#{Rails.root}/app/views/", "")
|
|
238
238
|
end.first(10)
|
|
239
|
-
rescue
|
|
239
|
+
rescue => e
|
|
240
|
+
$stderr.puts "[rails-ai-context] find_views_using failed: #{e.message}" if ENV["DEBUG"]
|
|
240
241
|
[]
|
|
241
242
|
end
|
|
242
243
|
|
|
@@ -333,7 +333,8 @@ module RailsAiContext
|
|
|
333
333
|
end
|
|
334
334
|
|
|
335
335
|
lines
|
|
336
|
-
rescue
|
|
336
|
+
rescue => e
|
|
337
|
+
$stderr.puts "[rails-ai-context] generate_test_template failed: #{e.message}" if ENV["DEBUG"]
|
|
337
338
|
[]
|
|
338
339
|
end
|
|
339
340
|
|
|
@@ -367,7 +368,8 @@ module RailsAiContext
|
|
|
367
368
|
end
|
|
368
369
|
|
|
369
370
|
lines.any? ? lines.join("\n") : nil
|
|
370
|
-
rescue
|
|
371
|
+
rescue => e
|
|
372
|
+
$stderr.puts "[rails-ai-context] parse_factory_details failed: #{e.message}" if ENV["DEBUG"]
|
|
371
373
|
nil
|
|
372
374
|
end
|
|
373
375
|
|
|
@@ -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|
|
|
@@ -249,8 +249,12 @@ module RailsAiContext
|
|
|
249
249
|
columns = result.columns
|
|
250
250
|
rows = result.rows
|
|
251
251
|
|
|
252
|
+
# Match both real column names and aliases that end with sensitive suffixes
|
|
253
|
+
sensitive_suffixes = %w[password secret token key digest hash].freeze
|
|
252
254
|
redacted_indices = columns.each_with_index.filter_map { |col, i|
|
|
253
|
-
|
|
255
|
+
col_down = col.downcase
|
|
256
|
+
i if redacted_cols.include?(col_down) ||
|
|
257
|
+
sensitive_suffixes.any? { |suffix| col_down.end_with?(suffix) || col_down.include?("password") || col_down.include?("secret") || col_down.include?("token") }
|
|
254
258
|
}
|
|
255
259
|
|
|
256
260
|
return result if redacted_indices.empty?
|
|
@@ -55,6 +55,9 @@ module RailsAiContext
|
|
|
55
55
|
/(?<=cookie:\s)\S+/i,
|
|
56
56
|
/(?<=session_id=)\S+/i,
|
|
57
57
|
/(?<=_session=)\S+/i,
|
|
58
|
+
/\bAKIA[0-9A-Z]{16}\b/, # AWS access key IDs
|
|
59
|
+
/\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/, # JWT tokens
|
|
60
|
+
/-----BEGIN\s+(RSA|DSA|EC|OPENSSH)?\s*PRIVATE KEY-----/, # SSH/TLS private keys
|
|
58
61
|
/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z]{2,}\b/i
|
|
59
62
|
].freeze
|
|
60
63
|
|
|
@@ -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
|