code_healer 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 +7 -0
- data/CHANGELOG.md +70 -0
- data/GEM_SUMMARY.md +307 -0
- data/README.md +281 -0
- data/code_healer.gemspec +77 -0
- data/config/code_healer.yml.example +104 -0
- data/docs/INSTALLATION.md +439 -0
- data/examples/basic_usage.rb +160 -0
- data/exe/code_healer-setup +7 -0
- data/lib/code_healer/application_job.rb +7 -0
- data/lib/code_healer/business_context_analyzer.rb +464 -0
- data/lib/code_healer/business_context_loader.rb +273 -0
- data/lib/code_healer/business_context_manager.rb +297 -0
- data/lib/code_healer/business_logic_generator.rb +94 -0
- data/lib/code_healer/business_rule_applier.rb +54 -0
- data/lib/code_healer/claude_code_evolution_handler.rb +224 -0
- data/lib/code_healer/claude_error_monitor.rb +48 -0
- data/lib/code_healer/config_manager.rb +275 -0
- data/lib/code_healer/context_aware_prompt_builder.rb +153 -0
- data/lib/code_healer/core.rb +513 -0
- data/lib/code_healer/error_handler.rb +141 -0
- data/lib/code_healer/evolution_job.rb +99 -0
- data/lib/code_healer/global_handler.rb +130 -0
- data/lib/code_healer/healing_job.rb +167 -0
- data/lib/code_healer/mcp.rb +108 -0
- data/lib/code_healer/mcp_prompts.rb +111 -0
- data/lib/code_healer/mcp_server.rb +389 -0
- data/lib/code_healer/mcp_tools.rb +2364 -0
- data/lib/code_healer/pull_request_creator.rb +143 -0
- data/lib/code_healer/setup.rb +390 -0
- data/lib/code_healer/simple_evolution.rb +737 -0
- data/lib/code_healer/simple_global_handler.rb +122 -0
- data/lib/code_healer/simple_healer.rb +515 -0
- data/lib/code_healer/terminal_integration.rb +87 -0
- data/lib/code_healer/usage_analyzer.rb +92 -0
- data/lib/code_healer/version.rb +5 -0
- data/lib/code_healer.rb +67 -0
- metadata +411 -0
@@ -0,0 +1,143 @@
|
|
1
|
+
require 'octokit'
|
2
|
+
|
3
|
+
module CodeHealer
|
4
|
+
class PullRequestCreator
|
5
|
+
class << self
|
6
|
+
def create_pull_request(branch_name, class_name, method_name, error, fix_description, file_path)
|
7
|
+
puts "🔍 PR Creation Debug:"
|
8
|
+
puts " - Auto create PR: #{ConfigManager.auto_create_pr?}"
|
9
|
+
puts " - PR enabled: #{ConfigManager.pull_request_settings['enabled']}"
|
10
|
+
|
11
|
+
return false unless ConfigManager.auto_create_pr?
|
12
|
+
return false unless ConfigManager.pull_request_settings['enabled']
|
13
|
+
|
14
|
+
begin
|
15
|
+
client = create_github_client
|
16
|
+
if client.nil?
|
17
|
+
puts "❌ Failed to create GitHub client - GitHub token not configured"
|
18
|
+
puts "💡 To enable PR creation, set GITHUB_TOKEN in your .env file"
|
19
|
+
puts " Run: ./setup_github_token.sh"
|
20
|
+
return false
|
21
|
+
end
|
22
|
+
|
23
|
+
title = generate_title(class_name, method_name, error)
|
24
|
+
body = generate_body(class_name, method_name, error, fix_description, file_path)
|
25
|
+
labels = ConfigManager.pull_request_settings['labels'] || []
|
26
|
+
|
27
|
+
puts "Creating pull request for branch: #{branch_name}"
|
28
|
+
|
29
|
+
# Get target branch from configuration
|
30
|
+
target_branch = ConfigManager.pr_target_branch || 'main'
|
31
|
+
puts "📋 Target branch for PR: #{target_branch}"
|
32
|
+
|
33
|
+
pr = client.create_pull_request(
|
34
|
+
repository_name,
|
35
|
+
target_branch,
|
36
|
+
branch_name,
|
37
|
+
title,
|
38
|
+
body,
|
39
|
+
labels: labels
|
40
|
+
)
|
41
|
+
|
42
|
+
puts "✅ Pull request created successfully!"
|
43
|
+
puts "🔗 PR URL: #{pr.html_url}"
|
44
|
+
|
45
|
+
# Store PR info for tracking
|
46
|
+
store_pr_info(pr.number, branch_name, class_name, method_name, error)
|
47
|
+
|
48
|
+
return pr.html_url
|
49
|
+
rescue => e
|
50
|
+
puts "❌ Failed to create pull request: #{e.message}"
|
51
|
+
Rails.logger.error "Pull request creation failed: #{e.message}"
|
52
|
+
return false
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def create_github_client
|
59
|
+
# Try environment variable first
|
60
|
+
token = ENV['GITHUB_TOKEN']
|
61
|
+
|
62
|
+
# Fallback to Rails credentials
|
63
|
+
if token.nil? && defined?(Rails.application.credentials)
|
64
|
+
token = Rails.application.credentials.dig(:github, :token)
|
65
|
+
end
|
66
|
+
|
67
|
+
return nil unless token
|
68
|
+
|
69
|
+
Octokit::Client.new(access_token: token)
|
70
|
+
rescue => e
|
71
|
+
puts "❌ Failed to create GitHub client: #{e.message}"
|
72
|
+
nil
|
73
|
+
end
|
74
|
+
|
75
|
+
def repository_name
|
76
|
+
# Extract from git remote
|
77
|
+
remote_url = `git config --get remote.origin.url`.strip
|
78
|
+
if remote_url =~ /github\.com[:\/]([^\/]+\/[^\/]+?)(?:\.git)?$/
|
79
|
+
$1
|
80
|
+
else
|
81
|
+
'deepan-g2/patchbot' # fallback
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def generate_title(class_name, method_name, error)
|
86
|
+
template = ConfigManager.pull_request_settings['title_template'] ||
|
87
|
+
'Fix \{class_name\}##\{method_name\}: Handle \{error_type\}'
|
88
|
+
|
89
|
+
template.gsub('\{class_name\}', class_name.to_s)
|
90
|
+
.gsub('\{method_name\}', method_name.to_s)
|
91
|
+
.gsub('\{error_type\}', error.class.name.to_s)
|
92
|
+
end
|
93
|
+
|
94
|
+
def generate_body(class_name, method_name, error, fix_description, file_path)
|
95
|
+
template = ConfigManager.pull_request_settings['body_template'] || default_body_template
|
96
|
+
|
97
|
+
template.gsub('{class_name}', class_name.to_s)
|
98
|
+
.gsub('{method_name}', method_name.to_s)
|
99
|
+
.gsub('{error_type}', error.class.name.to_s)
|
100
|
+
.gsub('{error_message}', error.message.to_s)
|
101
|
+
.gsub('{file_path}', file_path.to_s)
|
102
|
+
.gsub('{fix_description}', fix_description.to_s)
|
103
|
+
end
|
104
|
+
|
105
|
+
def default_body_template
|
106
|
+
# Simple string with placeholders - no interpolation
|
107
|
+
'## Auto-generated fix for {error_type}
|
108
|
+
|
109
|
+
**Error:** {error_message}
|
110
|
+
**Method:** {class_name}##{method_name}
|
111
|
+
**File:** {file_path}
|
112
|
+
|
113
|
+
### Changes Made:
|
114
|
+
{fix_description}
|
115
|
+
|
116
|
+
### Testing:
|
117
|
+
- [x] Error case handled gracefully
|
118
|
+
- [x] Normal functionality preserved
|
119
|
+
- [x] Tests generated automatically
|
120
|
+
|
121
|
+
Generated by Self-Evolving Ruby System 🤖'
|
122
|
+
end
|
123
|
+
|
124
|
+
def store_pr_info(pr_number, branch_name, class_name, method_name, error)
|
125
|
+
# Store PR information for tracking
|
126
|
+
pr_info = {
|
127
|
+
pr_number: pr_number,
|
128
|
+
branch_name: branch_name,
|
129
|
+
class_name: class_name,
|
130
|
+
method_name: method_name,
|
131
|
+
error_type: error.class.name,
|
132
|
+
created_at: Time.current,
|
133
|
+
status: 'open'
|
134
|
+
}
|
135
|
+
|
136
|
+
# Could store in database or cache
|
137
|
+
Rails.cache.write("pr_#{pr_number}", pr_info, expires_in: 30.days)
|
138
|
+
|
139
|
+
puts "📊 PR ##{pr_number} stored for tracking"
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
@@ -0,0 +1,390 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# CodeHealer Interactive Setup Script
|
5
|
+
# This script helps users configure CodeHealer in their Rails applications
|
6
|
+
|
7
|
+
require 'fileutils'
|
8
|
+
require 'yaml'
|
9
|
+
require 'optparse'
|
10
|
+
|
11
|
+
# Parse command line options
|
12
|
+
options = {}
|
13
|
+
OptionParser.new do |opts|
|
14
|
+
opts.banner = "Usage: code_healer-setup [options]"
|
15
|
+
|
16
|
+
opts.on("-h", "--help", "Show this help message") do
|
17
|
+
puts opts
|
18
|
+
puts
|
19
|
+
puts "🏥 CodeHealer Setup Script"
|
20
|
+
puts "This script helps you configure CodeHealer for your Rails application."
|
21
|
+
puts
|
22
|
+
puts "Examples:"
|
23
|
+
puts " code_healer-setup # Interactive setup"
|
24
|
+
puts " code_healer-setup --help # Show this help"
|
25
|
+
puts " code_healer-setup --dry-run # Show what would be created"
|
26
|
+
puts
|
27
|
+
exit 0
|
28
|
+
end
|
29
|
+
|
30
|
+
opts.on("--dry-run", "Show what would be created without making changes") do
|
31
|
+
options[:dry_run] = true
|
32
|
+
end
|
33
|
+
|
34
|
+
opts.on("--version", "Show version information") do
|
35
|
+
puts "CodeHealer Setup Script v1.0.0"
|
36
|
+
exit 0
|
37
|
+
end
|
38
|
+
end.parse!
|
39
|
+
|
40
|
+
# Helper methods for user interaction
|
41
|
+
def ask_for_input(prompt, default: nil)
|
42
|
+
print "#{prompt} "
|
43
|
+
input = gets.chomp.strip
|
44
|
+
|
45
|
+
if input.empty? && default
|
46
|
+
puts "Using default: #{default}"
|
47
|
+
return default
|
48
|
+
end
|
49
|
+
|
50
|
+
input
|
51
|
+
end
|
52
|
+
|
53
|
+
def ask_for_yes_no(prompt, default: true)
|
54
|
+
print "#{prompt} (#{default ? 'Y/n' : 'y/N'}) "
|
55
|
+
input = gets.chomp.strip.downcase
|
56
|
+
|
57
|
+
case input
|
58
|
+
when 'y', 'yes'
|
59
|
+
true
|
60
|
+
when 'n', 'no'
|
61
|
+
false
|
62
|
+
when ''
|
63
|
+
default
|
64
|
+
else
|
65
|
+
puts "Please enter 'y' or 'n'"
|
66
|
+
ask_for_yes_no(prompt, default)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def create_file_with_content(file_path, content, dry_run: false)
|
71
|
+
if dry_run
|
72
|
+
puts "📝 Would create #{file_path}"
|
73
|
+
puts " Content preview:"
|
74
|
+
puts " " + content.lines.first.strip + "..."
|
75
|
+
return
|
76
|
+
end
|
77
|
+
|
78
|
+
FileUtils.mkdir_p(File.dirname(file_path))
|
79
|
+
File.write(file_path, content)
|
80
|
+
puts "✅ Created #{file_path}"
|
81
|
+
end
|
82
|
+
|
83
|
+
def file_exists?(file_path)
|
84
|
+
File.exist?(file_path)
|
85
|
+
end
|
86
|
+
|
87
|
+
def read_file_content(file_path)
|
88
|
+
File.read(file_path) if file_exists?(file_path)
|
89
|
+
end
|
90
|
+
|
91
|
+
# Main setup logic
|
92
|
+
puts "🏥 Welcome to CodeHealer Setup! 🚀"
|
93
|
+
puts "=" * 50
|
94
|
+
puts "This will help you configure CodeHealer for your Rails application."
|
95
|
+
puts
|
96
|
+
|
97
|
+
# Check if we're in a Rails app
|
98
|
+
unless file_exists?('Gemfile') && file_exists?('config/application.rb')
|
99
|
+
puts "❌ Error: This doesn't appear to be a Rails application."
|
100
|
+
puts "Please run this script from your Rails application root directory."
|
101
|
+
exit 1
|
102
|
+
end
|
103
|
+
|
104
|
+
puts "✅ Rails application detected!"
|
105
|
+
puts
|
106
|
+
|
107
|
+
# Step 1: Add to Gemfile
|
108
|
+
puts "📦 Step 1: Adding CodeHealer to Gemfile..."
|
109
|
+
gemfile_path = 'Gemfile'
|
110
|
+
gemfile_content = read_file_content(gemfile_path)
|
111
|
+
|
112
|
+
if gemfile_content.include?("gem 'code_healer'")
|
113
|
+
puts "✅ CodeHealer already in Gemfile"
|
114
|
+
else
|
115
|
+
# Add the gem to the Gemfile
|
116
|
+
new_gemfile_content = gemfile_content + "\n# CodeHealer - AI-powered code healing\ngem 'code_healer'\n"
|
117
|
+
|
118
|
+
if options[:dry_run]
|
119
|
+
puts "📝 Would add 'code_healer' to Gemfile"
|
120
|
+
else
|
121
|
+
File.write(gemfile_path, new_gemfile_content)
|
122
|
+
puts "✅ Added 'code_healer' to Gemfile"
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
puts
|
127
|
+
|
128
|
+
# Step 2: Configuration Setup
|
129
|
+
puts "🔧 Step 2: Configuration Setup"
|
130
|
+
puts
|
131
|
+
|
132
|
+
# OpenAI Configuration
|
133
|
+
puts "🤖 OpenAI Configuration:"
|
134
|
+
puts "You'll need an OpenAI API key for AI-powered code healing."
|
135
|
+
puts "Get one at: https://platform.openai.com/api-keys"
|
136
|
+
puts
|
137
|
+
|
138
|
+
openai_key = ask_for_input("Enter your OpenAI API key (or press Enter to skip for now):")
|
139
|
+
|
140
|
+
# GitHub Configuration
|
141
|
+
puts
|
142
|
+
puts "🐙 GitHub Configuration:"
|
143
|
+
puts "You'll need a GitHub personal access token for Git operations."
|
144
|
+
puts "Get one at: https://github.com/settings/tokens"
|
145
|
+
puts
|
146
|
+
|
147
|
+
github_token = ask_for_input("Enter your GitHub personal access token (or press Enter to skip for now):")
|
148
|
+
github_repo = ask_for_input("Enter your GitHub repository (username/repo):")
|
149
|
+
|
150
|
+
# Git Branch Configuration
|
151
|
+
puts
|
152
|
+
puts "🌿 Git Branch Configuration:"
|
153
|
+
branch_prefix = ask_for_input("Enter branch prefix for healing branches (default: evolve):", default: "evolve")
|
154
|
+
pr_target_branch = ask_for_input("Enter target branch for pull requests (default: main):", default: "main")
|
155
|
+
|
156
|
+
# Business Context
|
157
|
+
puts
|
158
|
+
puts "💼 Business Context Setup:"
|
159
|
+
create_business_context = ask_for_yes_no("Would you like to create a business context file?", default: true)
|
160
|
+
|
161
|
+
# Evolution Strategy Configuration
|
162
|
+
puts
|
163
|
+
puts "🧠 Evolution Strategy Configuration:"
|
164
|
+
puts "Choose how CodeHealer should fix your code:"
|
165
|
+
puts "1. API - Use OpenAI API (recommended for most users)"
|
166
|
+
puts "2. Claude Code Terminal - Use local Claude installation"
|
167
|
+
puts "3. Hybrid - Try Claude first, fallback to API"
|
168
|
+
puts
|
169
|
+
|
170
|
+
evolution_method = ask_for_input("Enter evolution method (1/2/3 or api/claude/hybrid):", default: "api")
|
171
|
+
evolution_method = case evolution_method.downcase
|
172
|
+
when "1", "api"
|
173
|
+
"api"
|
174
|
+
when "2", "claude"
|
175
|
+
"claude_code_terminal"
|
176
|
+
when "3", "hybrid"
|
177
|
+
"hybrid"
|
178
|
+
else
|
179
|
+
"api"
|
180
|
+
end
|
181
|
+
|
182
|
+
fallback_to_api = ask_for_yes_no("Fallback to API if Claude Code fails?", default: true)
|
183
|
+
|
184
|
+
# Create configuration files
|
185
|
+
puts
|
186
|
+
puts "📝 Step 3: Creating Configuration Files"
|
187
|
+
puts
|
188
|
+
|
189
|
+
# Create actual .env file (will be ignored by git)
|
190
|
+
env_content = <<~ENV
|
191
|
+
# CodeHealer Configuration
|
192
|
+
# OpenAI Configuration
|
193
|
+
OPENAI_API_KEY=#{openai_key}
|
194
|
+
|
195
|
+
# GitHub Configuration
|
196
|
+
GITHUB_TOKEN=#{github_token}
|
197
|
+
GITHUB_REPOSITORY=#{github_repo}
|
198
|
+
|
199
|
+
# Optional: Redis Configuration
|
200
|
+
REDIS_URL=redis://localhost:6379/0
|
201
|
+
ENV
|
202
|
+
|
203
|
+
create_file_with_content('.env', env_content, dry_run: options[:dry_run])
|
204
|
+
|
205
|
+
# Create code_healer.yml
|
206
|
+
config_content = <<~YAML
|
207
|
+
# CodeHealer Configuration
|
208
|
+
enabled: true
|
209
|
+
|
210
|
+
# Allowed classes for healing (customize as needed)
|
211
|
+
allowed_classes:
|
212
|
+
- User
|
213
|
+
- Order
|
214
|
+
- PaymentProcessor
|
215
|
+
- OrderProcessor
|
216
|
+
|
217
|
+
# Excluded classes (never touch these)
|
218
|
+
excluded_classes:
|
219
|
+
- ApplicationController
|
220
|
+
- ApplicationRecord
|
221
|
+
- ApplicationJob
|
222
|
+
- ApplicationMailer
|
223
|
+
- ApplicationHelper
|
224
|
+
|
225
|
+
# Allowed error types for healing
|
226
|
+
allowed_error_types:
|
227
|
+
- ZeroDivisionError
|
228
|
+
- NoMethodError
|
229
|
+
- ArgumentError
|
230
|
+
- TypeError
|
231
|
+
- NameError
|
232
|
+
- ValidationError
|
233
|
+
|
234
|
+
# Evolution Strategy Configuration
|
235
|
+
evolution_strategy:
|
236
|
+
method: #{evolution_method} # Options: api, claude_code_terminal, hybrid
|
237
|
+
fallback_to_api: #{fallback_to_api} # If Claude Code fails, fall back to API
|
238
|
+
|
239
|
+
# Claude Code Terminal Configuration
|
240
|
+
claude_code:
|
241
|
+
enabled: #{evolution_method == 'claude_code_terminal' || evolution_method == 'hybrid'}
|
242
|
+
timeout: 300 # Timeout in seconds
|
243
|
+
max_file_changes: 10
|
244
|
+
include_tests: true
|
245
|
+
command_template: "claude --print '{prompt}' --output-format text --permission-mode acceptEdits --allowedTools Edit"
|
246
|
+
business_context_sources:
|
247
|
+
- "config/business_rules.yml"
|
248
|
+
- "docs/business_logic.md"
|
249
|
+
- "spec/business_context_specs.rb"
|
250
|
+
|
251
|
+
# Business Context Configuration
|
252
|
+
business_context:
|
253
|
+
enabled: true
|
254
|
+
sources:
|
255
|
+
- "docs/business_rules.md"
|
256
|
+
|
257
|
+
# OpenAI API configuration
|
258
|
+
api:
|
259
|
+
provider: openai
|
260
|
+
model: gpt-4
|
261
|
+
max_tokens: 2000
|
262
|
+
temperature: 0.1
|
263
|
+
|
264
|
+
# Git operations
|
265
|
+
git:
|
266
|
+
auto_commit: true
|
267
|
+
auto_push: true
|
268
|
+
branch_prefix: "#{branch_prefix}"
|
269
|
+
commit_message_template: 'Fix {{class_name}}\#\#{{method_name}}: {{error_type}}'
|
270
|
+
pr_target_branch: "#{pr_target_branch}"
|
271
|
+
|
272
|
+
# Pull Request Configuration
|
273
|
+
pull_request:
|
274
|
+
enabled: true
|
275
|
+
auto_create: true
|
276
|
+
labels:
|
277
|
+
- "auto-fix"
|
278
|
+
- "self-evolving"
|
279
|
+
- "bug-fix"
|
280
|
+
|
281
|
+
# Safety Configuration
|
282
|
+
safety:
|
283
|
+
backup_before_evolution: true
|
284
|
+
rollback_on_syntax_error: true
|
285
|
+
|
286
|
+
# Evolution Limits
|
287
|
+
max_evolutions_per_day: 10
|
288
|
+
|
289
|
+
# Notification Configuration (optional)
|
290
|
+
notifications:
|
291
|
+
enabled: false
|
292
|
+
slack_webhook: ""
|
293
|
+
email_notifications: false
|
294
|
+
|
295
|
+
# Performance Configuration
|
296
|
+
performance:
|
297
|
+
max_concurrent_healing: 3
|
298
|
+
healing_timeout: 300
|
299
|
+
retry_attempts: 3
|
300
|
+
YAML
|
301
|
+
|
302
|
+
create_file_with_content('config/code_healer.yml', config_content, dry_run: options[:dry_run])
|
303
|
+
|
304
|
+
# Create business context file if requested
|
305
|
+
if create_business_context
|
306
|
+
business_context_content = <<~MARKDOWN
|
307
|
+
# Business Rules and Context
|
308
|
+
|
309
|
+
## Error Handling
|
310
|
+
- All errors should be logged for audit purposes
|
311
|
+
- User-facing errors should be user-friendly
|
312
|
+
- Critical errors should trigger alerts
|
313
|
+
|
314
|
+
## Data Validation
|
315
|
+
- All user inputs must be validated
|
316
|
+
- Business rules must be enforced
|
317
|
+
- Invalid data should be rejected with clear messages
|
318
|
+
|
319
|
+
## Security
|
320
|
+
- Authentication required for sensitive operations
|
321
|
+
- Input sanitization mandatory
|
322
|
+
- Rate limiting for API endpoints
|
323
|
+
|
324
|
+
## Business Logic
|
325
|
+
- Follow domain-specific business rules
|
326
|
+
- Maintain data consistency
|
327
|
+
- Log all business-critical operations
|
328
|
+
MARKDOWN
|
329
|
+
|
330
|
+
create_file_with_content('docs/business_rules.md', business_context_content, dry_run: options[:dry_run])
|
331
|
+
end
|
332
|
+
|
333
|
+
# Create Sidekiq configuration
|
334
|
+
puts
|
335
|
+
puts "⚡ Step 4: Sidekiq Configuration"
|
336
|
+
puts
|
337
|
+
|
338
|
+
sidekiq_config_content = <<~YAML
|
339
|
+
:concurrency: 5
|
340
|
+
:queues:
|
341
|
+
- [healing, 2]
|
342
|
+
- [default, 1]
|
343
|
+
|
344
|
+
:redis:
|
345
|
+
:url: <%= ENV['REDIS_URL'] || 'redis://localhost:6379/0' %>
|
346
|
+
|
347
|
+
:logfile: log/sidekiq.log
|
348
|
+
:pidfile: tmp/pids/sidekiq.pid
|
349
|
+
YAML
|
350
|
+
|
351
|
+
create_file_with_content('config/sidekiq.yml', sidekiq_config_content, dry_run: options[:dry_run])
|
352
|
+
|
353
|
+
# Final instructions
|
354
|
+
puts
|
355
|
+
if options[:dry_run]
|
356
|
+
puts "🔍 Dry Run Complete! 🔍"
|
357
|
+
puts "=" * 50
|
358
|
+
puts "This is what would be created. Run without --dry-run to actually create the files."
|
359
|
+
else
|
360
|
+
puts "🎉 Setup Complete! 🎉"
|
361
|
+
puts "=" * 50
|
362
|
+
puts "Next steps:"
|
363
|
+
puts "1. Install dependencies: bundle install"
|
364
|
+
puts "2. Start Redis: redis-server"
|
365
|
+
puts "3. Start Sidekiq: bundle exec sidekiq"
|
366
|
+
puts "4. Start your Rails server: rails s"
|
367
|
+
puts
|
368
|
+
puts "🔒 Security Notes:"
|
369
|
+
puts " - .env file contains your actual API keys and is ignored by git"
|
370
|
+
puts " - .env.example is safe to commit and shows the required format"
|
371
|
+
puts " - Never commit .env files with real secrets to version control"
|
372
|
+
puts
|
373
|
+
puts "⚙️ Configuration:"
|
374
|
+
puts " - code_healer.yml contains comprehensive settings with sensible defaults"
|
375
|
+
puts " - Customize the configuration file as needed for your project"
|
376
|
+
puts " - All features are pre-configured and ready to use"
|
377
|
+
puts
|
378
|
+
puts "🌍 Environment Variables:"
|
379
|
+
puts " - Add 'gem \"dotenv-rails\"' to your Gemfile for automatic .env loading"
|
380
|
+
puts " - Or export variables manually: export GITHUB_TOKEN=your_token"
|
381
|
+
puts " - Or load .env file in your application.rb: load '.env' if File.exist?('.env')"
|
382
|
+
puts
|
383
|
+
puts "CodeHealer will now automatically detect and heal errors in your application!"
|
384
|
+
end
|
385
|
+
|
386
|
+
puts
|
387
|
+
puts "📚 For more information, visit: https://github.com/deepan-g2/code-healer"
|
388
|
+
puts "📧 Support: support@code-healer.com"
|
389
|
+
puts
|
390
|
+
puts "Happy coding! 🚀"
|