rails_claude 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: cc6cc5ba06b613ea5acd963515c72379e70a66b44a3630516eb6d7c0024f3fba
4
+ data.tar.gz: e63ce9f4d1bb3463bc2bfe5cdeb26d58deff4a89cd5a5adfd71a1f481312de59
5
+ SHA512:
6
+ metadata.gz: ff92166206f737689fe2e8c9a7344affeb03583c7bc367796709fbf298cfa0ed2b88a664564ccf7f4d6ebab592d1aa8f52ad3f49c851bd4d531759fcdc8dba0b
7
+ data.tar.gz: c2f7df20a83a1a292204bf4cb456a62f37fc94cf467f94fa93fe31c3a8796a776b241d775096320383dc1906d575301e4447a383b90c46e4c8f9d45383370679
data/LICENSE.txt ADDED
@@ -0,0 +1,17 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Nick Pendery
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
data/README.md ADDED
@@ -0,0 +1,270 @@
1
+ # RailsClaude
2
+
3
+ Chat with Claude AI directly inside your Rails console, with automatic Rails context.
4
+
5
+ RailsClaude drops an AI assistant into `rails c` that already knows your app's models, environment, and Ruby/Rails versions. Ask questions in plain English, get back ActiveRecord queries, debugging help, and code you can auto-execute — all without leaving the REPL.
6
+
7
+ ## Installation
8
+
9
+ Add the gem to your development group:
10
+
11
+ ```ruby
12
+ group :development do
13
+ gem "rails_claude"
14
+ end
15
+ ```
16
+
17
+ Then run:
18
+
19
+ ```bash
20
+ bundle install
21
+ ```
22
+
23
+ ### Requirements
24
+
25
+ - Ruby 3.0+
26
+ - Rails 6.0+
27
+ - An [Anthropic API key](https://console.anthropic.com/)
28
+
29
+ ## Configuration
30
+
31
+ Set your API key as an environment variable:
32
+
33
+ ```bash
34
+ export ANTHROPIC_API_KEY=sk-ant-...
35
+ ```
36
+
37
+ ### Optional Configuration
38
+
39
+ Create an initializer at `config/initializers/rails_claude.rb` to customize behavior:
40
+
41
+ ```ruby
42
+ RailsClaude.configure do |config|
43
+ config.api_key = ENV["ANTHROPIC_API_KEY"] # default
44
+ config.model = "claude-opus-4-6" # default
45
+ config.max_tokens = 1024 # default
46
+ config.safe_mode = Rails.env.production? # default
47
+ config.system_prompt = "Custom system prompt..." # auto-generated by default
48
+ end
49
+ ```
50
+
51
+ | Option | Default | Description |
52
+ |--------|---------|-------------|
53
+ | `api_key` | `ENV["ANTHROPIC_API_KEY"]` | Your Anthropic API key |
54
+ | `model` | `"claude-opus-4-6"` | Claude model to use for requests |
55
+ | `max_tokens` | `1024` | Maximum tokens per response |
56
+ | `safe_mode` | `true` in production, `false` otherwise | Wrap code execution in a rolled-back transaction |
57
+ | `system_prompt` | Auto-generated | System prompt with Rails context (see below) |
58
+
59
+ #### Auto-generated System Prompt
60
+
61
+ By default, RailsClaude builds a system prompt that includes:
62
+
63
+ - Your application name
64
+ - All detected model classes (ApplicationRecord descendants)
65
+ - Current Rails environment
66
+ - Ruby and Rails versions
67
+
68
+ This gives Claude immediate awareness of your app's structure without any manual setup.
69
+
70
+ ## Usage
71
+
72
+ When you start `rails c`, RailsClaude loads automatically and prints available commands:
73
+
74
+ ```
75
+ ✦ RailsClaude ready. (safe mode)
76
+ claude "question" — chat
77
+ claude_run! "question" — chat + auto-eval code
78
+ claude_load_model User — load a model for analysis
79
+ claude_load_file "path/to/f" — load any file for analysis
80
+ claude_safe_mode! / claude_unsafe_mode!
81
+ claude_history / claude_reset!
82
+ ```
83
+
84
+ ### `claude` — Ask a Question
85
+
86
+ Send a message to Claude and get a response. Conversation history is maintained across calls, so follow-up questions work naturally.
87
+
88
+ ```ruby
89
+ claude "find users who signed up in the last 7 days"
90
+ claude "now filter those to only verified accounts"
91
+ claude "what indexes would speed that query up?"
92
+ ```
93
+
94
+ ### `claude_run!` — Ask and Auto-Execute Code
95
+
96
+ Like `claude`, but automatically extracts Ruby code blocks from Claude's response, executes them in the console, and feeds the result back. Runs up to 3 iterations by default (configurable via `max_iterations`).
97
+
98
+ ```ruby
99
+ claude_run! "how many orders are in pending state?"
100
+ # Claude responds with: Order.where(status: "pending").count
101
+ # ⚡ Running: Order.where(status: "pending").count
102
+ # ⮕ Result: 42
103
+
104
+ claude_run! "show me the 5 most recent users", max_iterations: 1
105
+ ```
106
+
107
+ Code is displayed in yellow before execution, and results appear in green. If the executed code raises an error, the error is captured and sent back to Claude for debugging context.
108
+
109
+ ### `claude_load_model` — Load a Model for Analysis
110
+
111
+ Inject a model's full source code into the conversation so Claude can analyze it.
112
+
113
+ ```ruby
114
+ claude_load_model User
115
+ claude_load_model "Post" # string names work too
116
+
117
+ claude "what validations does this model have?"
118
+ claude "find any N+1 query risks in the associations"
119
+ ```
120
+
121
+ The gem finds the source file via `source_location` on the model's instance methods, falling back to `app/models/<name>.rb`.
122
+
123
+ ### `claude_load_file` — Load Any File for Analysis
124
+
125
+ Inject any file in your project into the conversation context.
126
+
127
+ ```ruby
128
+ claude_load_file "app/services/billing_service.rb"
129
+ claude_load_file "config/routes.rb"
130
+
131
+ claude "walk me through the billing flow"
132
+ ```
133
+
134
+ Paths are resolved relative to `Rails.root`.
135
+
136
+ ### `claude_history` — View Conversation History
137
+
138
+ Display all messages in the current session. User messages appear in cyan, Claude's responses in magenta.
139
+
140
+ ```ruby
141
+ claude_history
142
+ ```
143
+
144
+ ### `claude_safe_mode!` / `claude_unsafe_mode!` — Toggle Safe Mode
145
+
146
+ Switch between safe and unrestricted modes during a session without restarting the console.
147
+
148
+ ```ruby
149
+ claude_unsafe_mode!
150
+ # ⚠ Safe mode disabled — code will execute with full write access.
151
+
152
+ claude_run! "create a test user" # this will persist
153
+
154
+ claude_safe_mode!
155
+ # 🔒 Safe mode enabled — code runs in rolled-back transactions.
156
+ ```
157
+
158
+ `claude_safe_mode!` also accepts a boolean: `claude_safe_mode!(false)` is equivalent to `claude_unsafe_mode!`.
159
+
160
+ ### `claude_reset!` — Clear History
161
+
162
+ Start a fresh conversation. Clears all message history while keeping your configuration.
163
+
164
+ ```ruby
165
+ claude_reset!
166
+ ```
167
+
168
+ ### `claude_session` — Access the Session Object
169
+
170
+ For advanced usage, access the underlying `RailsClaude::Session` instance directly.
171
+
172
+ ```ruby
173
+ session = claude_session
174
+ session.history # inspect raw conversation history
175
+ ```
176
+
177
+ ## Examples
178
+
179
+ ### Exploring Data
180
+
181
+ ```ruby
182
+ claude_run! "how many users signed up this month?"
183
+ claude_run! "show me the top 10 by order count"
184
+ claude_run! "what's the average order value for those users?"
185
+ ```
186
+
187
+ ### Debugging a Model
188
+
189
+ ```ruby
190
+ claude_load_model Order
191
+ claude "what happens when status transitions from pending to fulfilled?"
192
+ claude "are there any callbacks that could cause side effects?"
193
+ ```
194
+
195
+ ### Analyzing a Service
196
+
197
+ ```ruby
198
+ claude_load_file "app/services/payment_service.rb"
199
+ claude_load_file "app/models/payment.rb"
200
+ claude "what error cases does the payment service handle?"
201
+ claude_run! "show me an example of calling the main method"
202
+ ```
203
+
204
+ ### Multi-Step Investigation
205
+
206
+ ```ruby
207
+ claude "are there any orders stuck in processing for more than 24 hours?"
208
+ claude_run! "find them"
209
+ claude_run! "show me the associated user for the oldest one"
210
+ claude "what should I check to debug this?"
211
+ ```
212
+
213
+ ## Safe Mode
214
+
215
+ Safe mode prevents `claude_run!` from making any persistent changes to your database. When enabled, all auto-executed code runs inside a database transaction that is **always rolled back** after the result is captured. Read queries work normally; writes are silently undone.
216
+
217
+ Safe mode is **on by default in production** and off in development/test. You'll see the current mode in the startup banner:
218
+
219
+ ```
220
+ ✦ RailsClaude ready. (safe mode)
221
+ ```
222
+
223
+ or:
224
+
225
+ ```
226
+ ✦ RailsClaude ready. (unrestricted)
227
+ ```
228
+
229
+ The system prompt also instructs Claude to only generate read-only code when safe mode is active.
230
+
231
+ ### Overriding Safe Mode
232
+
233
+ ```ruby
234
+ # Force safe mode on in development
235
+ RailsClaude.configure do |config|
236
+ config.safe_mode = true
237
+ end
238
+
239
+ # Disable safe mode in production (use with caution)
240
+ RailsClaude.configure do |config|
241
+ config.safe_mode = false
242
+ end
243
+ ```
244
+
245
+ ### What Safe Mode Protects Against
246
+
247
+ - `INSERT`, `UPDATE`, `DELETE` statements — rolled back after execution
248
+ - `ActiveRecord` create/update/destroy calls — rolled back after execution
249
+ - Claude is prompted to avoid generating destructive code entirely
250
+
251
+ ### What Safe Mode Does Not Protect Against
252
+
253
+ - Non-database side effects (file I/O, HTTP requests, system commands)
254
+ - Schema changes (`ALTER TABLE`, migrations) — these may auto-commit depending on your database
255
+
256
+ For full isolation in production, consider restricting the database user's permissions as well.
257
+
258
+ ## How It Works
259
+
260
+ RailsClaude uses a Rails [Railtie](https://api.rubyonrails.org/classes/Rails/Railtie.html) to hook into console startup. When `rails c` loads:
261
+
262
+ 1. **Eager loads** the application to discover all model classes
263
+ 2. **Creates a session** with an Anthropic API client and auto-generated system prompt
264
+ 3. **Defines helper methods** (`claude`, `claude_run!`, etc.) on `Object` so they're available as top-level console commands
265
+
266
+ Each call to `claude` or `claude_run!` sends the full conversation history to the Claude API, maintaining context across turns. `claude_run!` additionally extracts fenced code blocks (`` ```ruby `` or `` ``` ``) from responses, evaluates them in the console context, and loops the result back for up to `max_iterations` rounds.
267
+
268
+ ## License
269
+
270
+ The gem is available as open source under the terms of the [MIT License](LICENSE.txt).
@@ -0,0 +1,55 @@
1
+ module RailsClaude
2
+ class Configuration
3
+ attr_accessor :api_key, :model, :max_tokens, :system_prompt, :safe_mode
4
+
5
+ def initialize
6
+ @api_key = ENV["ANTHROPIC_API_KEY"]
7
+ @model = "claude-opus-4-6"
8
+ @max_tokens = 1024
9
+ @safe_mode = defined?(Rails) ? Rails.env.production? : true
10
+ @system_prompt = nil # deferred until first access so safe_mode is settled
11
+ end
12
+
13
+ def system_prompt
14
+ @system_prompt || default_system_prompt
15
+ end
16
+
17
+ def safe_mode?
18
+ !!@safe_mode
19
+ end
20
+
21
+ private
22
+
23
+ def default_system_prompt
24
+ app_name = defined?(Rails) ? Rails.application.class.module_parent_name : "Rails"
25
+ models = defined?(ApplicationRecord) ? ApplicationRecord.descendants.map(&:name).join(", ") : "unknown"
26
+
27
+ prompt = <<~PROMPT
28
+ You are a Rails developer assistant embedded inside a live Rails console for the #{app_name} app.
29
+
30
+ You help the user write ActiveRecord queries, debug issues, and explore the app.
31
+
32
+ Known models: #{models}
33
+ Rails environment: #{Rails.env}
34
+ Ruby version: #{RUBY_VERSION}
35
+ Rails version: #{Rails.version}
36
+
37
+ Keep responses concise and practical. When suggesting code, prefer single-line expressions
38
+ that work well in a REPL context. Remind the user if they need to run something manually.
39
+ PROMPT
40
+
41
+ if safe_mode?
42
+ prompt += <<~SAFE
43
+
44
+ IMPORTANT: Safe mode is ON. All executed code runs inside a read-only transaction
45
+ that is automatically rolled back. Only generate read-only code — SELECT queries,
46
+ inspections, and counts. Do NOT generate code that creates, updates, or deletes records,
47
+ runs migrations, modifies files, or executes system commands. Any database writes will
48
+ be rolled back and the user will be warned.
49
+ SAFE
50
+ end
51
+
52
+ prompt
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,28 @@
1
+ module RailsClaude
2
+ class Railtie < Rails::Railtie
3
+ console do
4
+ Rails.application.eager_load!
5
+
6
+ session = RailsClaude::Session.new
7
+
8
+ Object.define_method(:claude) { |msg| session.ask(msg) }
9
+ Object.define_method(:claude_run!) { |msg, **opts| session.ask_and_run(msg, **opts) }
10
+ Object.define_method(:claude_load_model) { |model| session.load_model(model) }
11
+ Object.define_method(:claude_load_file) { |path| session.load_file(path) }
12
+ Object.define_method(:claude_reset!) { session.reset! }
13
+ Object.define_method(:claude_history) { session.show_history }
14
+ Object.define_method(:claude_session) { session }
15
+ Object.define_method(:claude_safe_mode!) { |enabled = true| session.set_safe_mode(enabled) }
16
+ Object.define_method(:claude_unsafe_mode!) { session.set_safe_mode(false) }
17
+
18
+ mode = RailsClaude.configuration.safe_mode? ? "\e[32m(safe mode)\e[0m" : "\e[33m(unrestricted)\e[0m"
19
+ puts "\e[35m✦ RailsClaude ready.\e[0m #{mode}"
20
+ puts " \e[36mclaude\e[0m \"question\" — chat"
21
+ puts " \e[36mclaude_run!\e[0m \"question\" — chat + auto-eval code"
22
+ puts " \e[36mclaude_load_model\e[0m User — load a model for analysis"
23
+ puts " \e[36mclaude_load_file\e[0m \"path/to/f\" — load any file for analysis"
24
+ puts " \e[36mclaude_safe_mode!\e[0m / \e[36mclaude_unsafe_mode!\e[0m"
25
+ puts " \e[36mclaude_history\e[0m / \e[36mclaude_reset!\e[0m\n\n"
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,149 @@
1
+ require "anthropic"
2
+
3
+ module RailsClaude
4
+ class Session
5
+ attr_reader :history
6
+
7
+ def initialize
8
+ @config = RailsClaude.configuration
9
+ @client = Anthropic::Client.new(api_key: @config.api_key)
10
+ @history = []
11
+ end
12
+
13
+ def ask(message)
14
+ @history << { role: "user", content: message }
15
+
16
+ response = @client.messages.create(
17
+ model: @config.model,
18
+ max_tokens: @config.max_tokens,
19
+ system: @config.system_prompt,
20
+ messages: @history
21
+ )
22
+
23
+ reply = response.content.first.text
24
+ @history << { role: "assistant", content: reply }
25
+ pretty_print(reply)
26
+ nil
27
+ end
28
+
29
+ def ask_and_run(message, max_iterations: 3)
30
+ @history << { role: "user", content: message }
31
+
32
+ max_iterations.times do
33
+ response = @client.messages.create(
34
+ model: @config.model,
35
+ max_tokens: @config.max_tokens,
36
+ system: @config.system_prompt,
37
+ messages: @history
38
+ )
39
+
40
+ reply = response.content.first.text
41
+ @history << { role: "assistant", content: reply }
42
+ pretty_print(reply)
43
+
44
+ code = extract_code(reply)
45
+ break unless code
46
+
47
+ run_label = @config.safe_mode? ? "\e[33m🔒 Running (safe mode):\e[0m" : "\e[33m⚡ Running:\e[0m"
48
+ puts "#{run_label}\n#{code}\n"
49
+ result = safe_eval(code)
50
+ puts "\e[32m⮕ Result:\e[0m #{result}\n\n"
51
+
52
+ @history << { role: "user", content: "Result of running that code: #{result}" }
53
+ end
54
+
55
+ nil
56
+ end
57
+
58
+ def load_model(model)
59
+ klass = model.is_a?(Class) ? model : model.to_s.constantize
60
+ path = source_path_for(klass)
61
+ raise "Could not find source file for #{klass}" unless path && File.exist?(path)
62
+ inject_file(path, label: "Model: #{klass}")
63
+ end
64
+
65
+ def load_file(path)
66
+ full_path = Rails.root.join(path)
67
+ raise "File not found: #{full_path}" unless File.exist?(full_path)
68
+ inject_file(full_path, label: path)
69
+ end
70
+
71
+ def set_safe_mode(enabled)
72
+ @config.safe_mode = enabled
73
+ if enabled
74
+ puts "\e[32m🔒 Safe mode enabled — code runs in rolled-back transactions.\e[0m"
75
+ else
76
+ puts "\e[33m⚠ Safe mode disabled — code will execute with full write access.\e[0m"
77
+ end
78
+ nil
79
+ end
80
+
81
+ def reset!
82
+ @history = []
83
+ puts "→ Conversation history cleared."
84
+ nil
85
+ end
86
+
87
+ def show_history
88
+ if @history.empty?
89
+ puts "No conversation history yet."
90
+ else
91
+ @history.each do |msg|
92
+ label = msg[:role] == "user" ? "\e[36mYou\e[0m" : "\e[35mClaude\e[0m"
93
+ puts "\n#{label}: #{msg[:content]}"
94
+ end
95
+ end
96
+ nil
97
+ end
98
+
99
+ private
100
+
101
+ def inject_file(path, label:)
102
+ content = File.read(path)
103
+ notice = "I'm sharing this file for context — #{label}:\n\n```ruby\n#{content}\n```"
104
+ @history << { role: "user", content: notice }
105
+ puts "\e[36m→ Loaded #{label} into conversation context.\e[0m"
106
+ puts " Ask Claude about it: claude \"explain this model\" or claude \"find N+1 issues\"\n\n"
107
+ nil
108
+ end
109
+
110
+ def extract_code(text)
111
+ text[/```ruby\n(.*?)```/m, 1] || text[/```\n(.*?)```/m, 1]
112
+ end
113
+
114
+ def safe_eval(code)
115
+ if @config.safe_mode?
116
+ safe_eval_readonly(code)
117
+ else
118
+ result = eval(code) # rubocop:disable Security/Eval
119
+ result.inspect
120
+ end
121
+ rescue StandardError => e
122
+ err = "#{e.class}: #{e.message}"
123
+ @history << { role: "user", content: "That code raised an error: #{err}" }
124
+ "\e[31mError — #{err}\e[0m"
125
+ end
126
+
127
+ def safe_eval_readonly(code)
128
+ output = nil
129
+ ActiveRecord::Base.transaction do
130
+ output = eval(code).inspect # rubocop:disable Security/Eval
131
+ raise ActiveRecord::Rollback
132
+ end
133
+ output
134
+ end
135
+
136
+ def source_path_for(klass)
137
+ m = klass.instance_methods(false).first
138
+ if m
139
+ file, = klass.instance_method(m).source_location
140
+ return file if file
141
+ end
142
+ Rails.root.join("app", "models", "#{klass.name.underscore}.rb").to_s
143
+ end
144
+
145
+ def pretty_print(text)
146
+ puts "\n\e[35mClaude:\e[0m #{text}\n\n"
147
+ end
148
+ end
149
+ end
@@ -0,0 +1,3 @@
1
+ module RailsClaude
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,16 @@
1
+ require "rails_claude/version"
2
+ require "rails_claude/configuration"
3
+ require "rails_claude/session"
4
+ require "rails_claude/railtie" if defined?(Rails)
5
+
6
+ module RailsClaude
7
+ class << self
8
+ def configuration
9
+ @configuration ||= Configuration.new
10
+ end
11
+
12
+ def configure
13
+ yield(configuration)
14
+ end
15
+ end
16
+ end
metadata ADDED
@@ -0,0 +1,79 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rails_claude
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Nick Pendery
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2026-04-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: anthropic
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 0.3.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 0.3.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: railties
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '6.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '6.0'
41
+ description: Provides an interactive Claude AI session directly in rails c, with Rails-aware
42
+ context.
43
+ email:
44
+ - npendery@homebot.ai
45
+ executables: []
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - LICENSE.txt
50
+ - README.md
51
+ - lib/rails_claude.rb
52
+ - lib/rails_claude/configuration.rb
53
+ - lib/rails_claude/railtie.rb
54
+ - lib/rails_claude/session.rb
55
+ - lib/rails_claude/version.rb
56
+ homepage: https://github.com/npendery/rails-claude-console
57
+ licenses:
58
+ - MIT
59
+ metadata: {}
60
+ post_install_message:
61
+ rdoc_options: []
62
+ require_paths:
63
+ - lib
64
+ required_ruby_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ required_rubygems_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ requirements: []
75
+ rubygems_version: 3.3.26
76
+ signing_key:
77
+ specification_version: 4
78
+ summary: Chat with Claude inside your Rails console
79
+ test_files: []