rails-ai-context 4.2.3 → 4.3.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.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +54 -0
  3. data/CLAUDE.md +4 -4
  4. data/CONTRIBUTING.md +1 -1
  5. data/README.md +7 -7
  6. data/SECURITY.md +2 -1
  7. data/docs/GUIDE.md +3 -3
  8. data/lib/generators/rails_ai_context/install/install_generator.rb +2 -2
  9. data/lib/rails_ai_context/configuration.rb +4 -2
  10. data/lib/rails_ai_context/doctor.rb +6 -1
  11. data/lib/rails_ai_context/fingerprinter.rb +24 -0
  12. data/lib/rails_ai_context/introspectors/component_introspector.rb +122 -7
  13. data/lib/rails_ai_context/introspectors/performance_introspector.rb +18 -10
  14. data/lib/rails_ai_context/introspectors/schema_introspector.rb +183 -6
  15. data/lib/rails_ai_context/introspectors/view_introspector.rb +2 -2
  16. data/lib/rails_ai_context/introspectors/view_template_introspector.rb +61 -8
  17. data/lib/rails_ai_context/serializers/claude_rules_serializer.rb +10 -19
  18. data/lib/rails_ai_context/serializers/claude_serializer.rb +42 -11
  19. data/lib/rails_ai_context/serializers/context_file_serializer.rb +14 -3
  20. data/lib/rails_ai_context/serializers/cursor_rules_serializer.rb +1 -1
  21. data/lib/rails_ai_context/serializers/design_system_helper.rb +8 -1
  22. data/lib/rails_ai_context/serializers/opencode_serializer.rb +5 -2
  23. data/lib/rails_ai_context/serializers/tool_guide_helper.rb +165 -64
  24. data/lib/rails_ai_context/server.rb +12 -1
  25. data/lib/rails_ai_context/tools/base_tool.rb +63 -1
  26. data/lib/rails_ai_context/tools/diagnose.rb +436 -0
  27. data/lib/rails_ai_context/tools/generate_test.rb +571 -0
  28. data/lib/rails_ai_context/tools/get_callbacks.rb +27 -4
  29. data/lib/rails_ai_context/tools/get_component_catalog.rb +11 -2
  30. data/lib/rails_ai_context/tools/get_context.rb +70 -8
  31. data/lib/rails_ai_context/tools/get_conventions.rb +59 -0
  32. data/lib/rails_ai_context/tools/get_design_system.rb +45 -7
  33. data/lib/rails_ai_context/tools/get_edit_context.rb +3 -2
  34. data/lib/rails_ai_context/tools/get_env.rb +51 -24
  35. data/lib/rails_ai_context/tools/get_frontend_stack.rb +100 -9
  36. data/lib/rails_ai_context/tools/get_model_details.rb +19 -0
  37. data/lib/rails_ai_context/tools/get_partial_interface.rb +1 -1
  38. data/lib/rails_ai_context/tools/get_stimulus.rb +13 -7
  39. data/lib/rails_ai_context/tools/get_turbo_map.rb +35 -2
  40. data/lib/rails_ai_context/tools/get_view.rb +65 -9
  41. data/lib/rails_ai_context/tools/migration_advisor.rb +4 -0
  42. data/lib/rails_ai_context/tools/onboard.rb +755 -0
  43. data/lib/rails_ai_context/tools/query.rb +4 -2
  44. data/lib/rails_ai_context/tools/read_logs.rb +4 -1
  45. data/lib/rails_ai_context/tools/review_changes.rb +299 -0
  46. data/lib/rails_ai_context/tools/runtime_info.rb +289 -0
  47. data/lib/rails_ai_context/tools/search_code.rb +23 -4
  48. data/lib/rails_ai_context/tools/security_scan.rb +7 -1
  49. data/lib/rails_ai_context/tools/session_context.rb +132 -0
  50. data/lib/rails_ai_context/version.rb +1 -1
  51. metadata +10 -4
@@ -123,7 +123,13 @@ module RailsAiContext
123
123
 
124
124
  if warnings.empty?
125
125
  scope = files&.any? ? " in #{files.join(', ')}" : ""
126
- return text_response("No security warnings found#{scope}. (#{checks_run} checks run)")
126
+ # Summarize what categories were checked for transparency
127
+ check_names = tracker.checks.checks_run.map do |c|
128
+ c.to_s.sub(/\ABrakeman::Checks::Check/, "").gsub(/([a-z])([A-Z])/, '\1 \2')
129
+ end
130
+ categories = check_names.first(6).join(", ")
131
+ categories += ", ..." if check_names.size > 6
132
+ return text_response("No security warnings found#{scope}. (#{checks_run} checks run: #{categories})")
127
133
  end
128
134
 
129
135
  case detail
@@ -0,0 +1,132 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsAiContext
4
+ module Tools
5
+ class SessionContext < BaseTool
6
+ tool_name "rails_session_context"
7
+ description "Track what you've already queried to avoid redundant calls. " \
8
+ "Use action:\"status\" to see what tools you've called, action:\"summary\" for a compressed recap, " \
9
+ "action:\"reset\" to clear session, or mark:\"tool:param\" to record a query. " \
10
+ "Helps maintain focus during long development sessions."
11
+
12
+ input_schema(
13
+ properties: {
14
+ action: {
15
+ type: "string",
16
+ enum: %w[status summary reset],
17
+ description: "status: list queried tools with timestamps. summary: compressed recap. reset: clear session."
18
+ },
19
+ mark: {
20
+ type: "string",
21
+ description: "Mark a tool+params as already queried (e.g., 'get_schema:users', 'get_model_details:User')."
22
+ }
23
+ }
24
+ )
25
+
26
+ annotations(read_only_hint: true, destructive_hint: false, idempotent_hint: false, open_world_hint: false)
27
+
28
+ def self.call(action: nil, mark: nil, server_context: nil)
29
+ unless action || mark
30
+ return text_response("Provide `action` (status/summary/reset) or `mark` (tool:param to record).")
31
+ end
32
+
33
+ if mark
34
+ tool, params = parse_mark(mark)
35
+ session_record(tool, params)
36
+ return text_response("Marked `#{tool}` with params `#{params}` as queried.")
37
+ end
38
+
39
+ case action
40
+ when "status"
41
+ render_status
42
+ when "summary"
43
+ render_summary
44
+ when "reset"
45
+ session_reset!
46
+ text_response("Session cleared. All query records removed.")
47
+ else
48
+ text_response("Unknown action: #{action}. Use status, summary, or reset.")
49
+ end
50
+ rescue => e
51
+ text_response("Session context error: #{e.message}")
52
+ end
53
+
54
+ class << self
55
+ private
56
+
57
+ def parse_mark(mark_string)
58
+ parts = mark_string.split(":", 2)
59
+ tool = parts[0]&.strip
60
+ params = parts[1]&.strip || ""
61
+ [ tool, params ]
62
+ end
63
+
64
+ def render_status
65
+ queries = session_queries
66
+ if queries.empty?
67
+ return text_response("# Session Context\n\nNo queries recorded yet. Tools will be tracked as you use them.\n\n_Use `mark:\"tool:params\"` to manually record a query._\n_Note: CLI (`rails ai:tool`) runs each call in a separate process — session tracking only works via MCP._")
68
+ end
69
+
70
+ lines = [ "# Session Context (#{queries.size} queries)", "" ]
71
+ lines << "| Tool | Params | When |"
72
+ lines << "|------|--------|------|"
73
+
74
+ queries.sort_by { |q| q[:timestamp] }.each do |q|
75
+ ago = time_ago(q[:timestamp])
76
+ params_str = q[:params].is_a?(Hash) ? q[:params].map { |k, v| "#{k}:#{v}" }.join(", ") : q[:params].to_s
77
+ params_display = params_str.empty? ? "-" : params_str.truncate(40)
78
+ lines << "| `#{q[:tool]}` | #{params_display} | #{ago} |"
79
+ end
80
+
81
+ lines << ""
82
+ lines << "_Use `action:\"reset\"` to clear, or `action:\"summary\"` for a compressed recap._"
83
+ lines << "_Note: CLI (`rails ai:tool`) runs each call in a separate process — session tracking only works via MCP._"
84
+ text_response(lines.join("\n"))
85
+ end
86
+
87
+ def render_summary
88
+ queries = session_queries
89
+ if queries.empty?
90
+ return text_response("No queries recorded yet.")
91
+ end
92
+
93
+ lines = [ "# Session Summary", "" ]
94
+ lines << "You have queried #{queries.size} tool(s) in this session:"
95
+ lines << ""
96
+
97
+ # Group by tool name
98
+ by_tool = queries.group_by { |q| q[:tool] }
99
+ by_tool.each do |tool, calls|
100
+ params_list = calls.map { |c|
101
+ p = c[:params]
102
+ p.is_a?(Hash) ? p.map { |k, v| "#{k}:#{v}" }.join(", ") : p.to_s
103
+ }.reject(&:empty?)
104
+
105
+ if params_list.any?
106
+ lines << "- **#{tool}** (#{calls.size}x): #{params_list.uniq.join('; ')}"
107
+ else
108
+ lines << "- **#{tool}** (#{calls.size}x)"
109
+ end
110
+ end
111
+
112
+ lines << ""
113
+ lines << "_Avoid re-querying these. Use `action:\"status\"` for timestamps._"
114
+ text_response(lines.join("\n"))
115
+ end
116
+
117
+ def time_ago(iso_timestamp)
118
+ diff = Time.now - Time.parse(iso_timestamp)
119
+ if diff < 60
120
+ "#{diff.to_i}s ago"
121
+ elsif diff < 3600
122
+ "#{(diff / 60).to_i}m ago"
123
+ else
124
+ "#{(diff / 3600).to_i}h ago"
125
+ end
126
+ rescue
127
+ iso_timestamp
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsAiContext
4
- VERSION = "4.2.3"
4
+ VERSION = "4.3.1"
5
5
  end
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.2.3
4
+ version: 4.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - crisnahine
@@ -170,7 +170,7 @@ dependencies:
170
170
  description: |
171
171
  rails-ai-context gives AI coding agents a complete mental model of your Rails
172
172
  app — not just files, but how schema, models, routes, controllers, views, and
173
- conventions connect. 33 live tools (via MCP server or CLI) let agents query
173
+ conventions connect. 39 live tools (via MCP server or CLI) let agents query
174
174
  structure on demand with semantic validation that catches cross-file errors
175
175
  (wrong columns, missing partials, broken routes) before code runs.
176
176
  Auto-generates context files for Claude Code, Cursor, GitHub Copilot, and
@@ -262,6 +262,8 @@ files:
262
262
  - lib/rails_ai_context/tools/analyze_feature.rb
263
263
  - lib/rails_ai_context/tools/base_tool.rb
264
264
  - lib/rails_ai_context/tools/dependency_graph.rb
265
+ - lib/rails_ai_context/tools/diagnose.rb
266
+ - lib/rails_ai_context/tools/generate_test.rb
265
267
  - lib/rails_ai_context/tools/get_callbacks.rb
266
268
  - lib/rails_ai_context/tools/get_component_catalog.rb
267
269
  - lib/rails_ai_context/tools/get_concern.rb
@@ -286,12 +288,16 @@ files:
286
288
  - lib/rails_ai_context/tools/get_turbo_map.rb
287
289
  - lib/rails_ai_context/tools/get_view.rb
288
290
  - lib/rails_ai_context/tools/migration_advisor.rb
291
+ - lib/rails_ai_context/tools/onboard.rb
289
292
  - lib/rails_ai_context/tools/performance_check.rb
290
293
  - lib/rails_ai_context/tools/query.rb
291
294
  - lib/rails_ai_context/tools/read_logs.rb
295
+ - lib/rails_ai_context/tools/review_changes.rb
296
+ - lib/rails_ai_context/tools/runtime_info.rb
292
297
  - lib/rails_ai_context/tools/search_code.rb
293
298
  - lib/rails_ai_context/tools/search_docs.rb
294
299
  - lib/rails_ai_context/tools/security_scan.rb
300
+ - lib/rails_ai_context/tools/session_context.rb
295
301
  - lib/rails_ai_context/tools/validate.rb
296
302
  - lib/rails_ai_context/version.rb
297
303
  - lib/rails_ai_context/watcher.rb
@@ -311,7 +317,7 @@ post_install_message: |
311
317
  rails-ai-context installed! Quick start:
312
318
  rails generate rails_ai_context:install
313
319
  rails ai:context # generate context files
314
- rails 'ai:tool[schema]' # run any of the 33 tools from CLI
320
+ rails 'ai:tool[schema]' # run any of the 39 tools from CLI
315
321
  rails ai:serve # start MCP server (optional)
316
322
  rdoc_options: []
317
323
  require_paths:
@@ -329,6 +335,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
329
335
  requirements: []
330
336
  rubygems_version: 3.6.9
331
337
  specification_version: 4
332
- summary: Give AI agents a complete mental model of your Rails app — 33 tools via MCP
338
+ summary: Give AI agents a complete mental model of your Rails app — 39 tools via MCP
333
339
  or CLI. Zero config.
334
340
  test_files: []