code_healer 0.1.15 → 0.1.17

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a0eb37a96fca96ae0321a1ee24addb93e3dee8d0755ca5df8934c04420ef3548
4
- data.tar.gz: b49f5a80ae6cc86b5bc0cd1ccd798a7279ea5d444be32894fb5514599cd13482
3
+ metadata.gz: 87529c94cd83d16eef532144bb5d03d7f9ac588fdbf8cfe89ae167e6722cf329
4
+ data.tar.gz: b0d57d027ebf3e59e1e5515d27148aa5887c4ed6110a5b4de6af57e1785105f7
5
5
  SHA512:
6
- metadata.gz: 98e5125e4f561073f31a8f263b5aba7b4ec62dba1d7a9c6b3dca818aa412c5f4578a55ff28dc95dd27768aa86dc61353050c43960ed29d8cc2499790bccef987
7
- data.tar.gz: 52611005c0b0e47e16e86fb6f0d62ff0aea6a338e42de0b725e5de7a1d77713f3e89494db821d5f06c350283bf6027d629c859a3515e8dcb7cdb0cda113823f7
6
+ metadata.gz: 7e543125b2ac69159ca0a244ea7249c2fcc38c5947acaf6ff82b3955aec7b35dbf425adcb5bcb3ac89766ec3b01ba2d5668d44ced1c57741d8407e9af8af921d
7
+ data.tar.gz: d67d88d8c80f0ddb0b712131cb7841e7903055cc8db86e1ce46ee18bbfb8a3b5de18e78221b12234577b77bf927588c5a78716f548833ec1146635b661843c95
data/CHANGELOG.md CHANGED
@@ -5,6 +5,33 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [Unreleased]
9
+
10
+ ## [0.1.17] - 2025-08-21
11
+
12
+ ### Added
13
+ - **Interactive Demo Mode Setup**: Added comprehensive demo mode configuration options to the interactive setup script.
14
+ - **Demo Mode Features**: Timeout reduction (60s), sticky workspace, Claude session persistence, and conditional test/PR skipping.
15
+ - **Setup Script Enhancements**: Better user guidance for demo mode configuration and performance optimization.
16
+
17
+ ### Changed
18
+ - **Setup Script**: Enhanced with demo mode questions and configuration generation.
19
+ - **Configuration Generation**: Automatically generates optimized settings for conference demonstrations.
20
+
21
+ ## [0.1.16] - 2025-08-21
22
+
23
+ ### Added
24
+ - Processing state: dashboard shows in-flight healings as "processing" (no longer treated as failed)
25
+ - API metrics payload now includes `status` and timezone-aware `created_at`
26
+
27
+ ### Changed
28
+ - API endpoints default to JSON (`/code_healer/api/...`) to avoid template lookup
29
+ - Compact metrics JSON for dashboard list rendering
30
+
31
+ ### Fixed
32
+ - Timezone correctness: all metrics timestamps use `Time.zone`
33
+ - Daily trend counts computed with timezone-aware day buckets
34
+
8
35
  ## [0.1.15] - 2025-08-21
9
36
 
10
37
  ### Fixed
data/config/routes.rb CHANGED
@@ -5,8 +5,8 @@ CodeHealer::Engine.routes.draw do
5
5
  get '/dashboard/performance', to: 'dashboard#performance'
6
6
  get '/dashboard/healing/:healing_id', to: 'dashboard#healing_details'
7
7
 
8
- # API endpoints (JSON only)
9
- namespace :api do
8
+ # API endpoints (JSON only) - default to JSON format
9
+ scope path: '/api', defaults: { format: :json } do
10
10
  get '/dashboard/summary', to: 'dashboard#summary'
11
11
  get '/dashboard/metrics', to: 'dashboard#metrics'
12
12
  get '/dashboard/trends', to: 'dashboard#trends'
@@ -11,10 +11,16 @@ module CodeHealer
11
11
  puts "File: #{file_path}"
12
12
 
13
13
  begin
14
- # Build comprehensive prompt
14
+ # Build concise, demo-optimized prompt (no repo-wide scan, no tests)
15
15
  prompt = BusinessContextManager.build_claude_code_prompt(
16
16
  error, class_name, method_name, file_path
17
17
  )
18
+ prompt << "\n\nStrict instructions:" \
19
+ "\n- Do NOT scan the entire codebase." \
20
+ "\n- Work only with the provided file/method context and backtrace." \
21
+ "\n- Return a unified diff (no prose)." \
22
+ "\n- Keep changes minimal and safe." \
23
+ "\n- Do NOT create or run tests." if CodeHealer::ConfigManager.demo_mode?
18
24
 
19
25
  # Execute Claude Code command
20
26
  success = execute_claude_code_fix(prompt, class_name, method_name)
@@ -111,8 +117,10 @@ module CodeHealer
111
117
  command = command_template.gsub('{prompt}', escaped_prompt)
112
118
 
113
119
  # Add additional options if configured
114
- if config['include_tests']
120
+ if config['include_tests'] && !CodeHealer::ConfigManager.demo_mode?
115
121
  command += " --append-system-prompt 'Include tests when fixing the code'"
122
+ else
123
+ command += " --append-system-prompt 'Do NOT create or modify tests'"
116
124
  end
117
125
 
118
126
  if config['max_file_changes']
@@ -122,8 +130,8 @@ module CodeHealer
122
130
  # Add file editing permissions
123
131
  command += " --permission-mode acceptEdits --allowedTools Edit"
124
132
 
125
- # Add current directory access
126
- command += " --add-dir ."
133
+ # Add current directory access but advise not to scan everything
134
+ command += " --add-dir . --append-system-prompt 'Do not scan the whole repo; open only files explicitly referenced.'"
127
135
 
128
136
  command
129
137
  end
@@ -0,0 +1,66 @@
1
+ require 'open3'
2
+
3
+ module CodeHealer
4
+ # Manages a persistent Claude Code Terminal session and one-time preload
5
+ class ClaudeSession
6
+ class << self
7
+ def start!
8
+ return if @started
9
+ return unless CodeHealer::ConfigManager.claude_code_enabled?
10
+
11
+ @started = true
12
+ preload_workspace
13
+ preload_context
14
+ rescue => e
15
+ @started = false
16
+ puts "⚠️ Failed to start Claude session preload: #{e.message}"
17
+ end
18
+
19
+ def with_session
20
+ start!
21
+ yield self
22
+ end
23
+
24
+ private
25
+
26
+ def preload_workspace
27
+ base = CodeHealer::ConfigManager.code_heal_directory_path
28
+ path = CodeHealer::ConfigManager.sticky_workspace? ? File.join(base, 'session_workspace') : base
29
+ @workspace_path = path
30
+
31
+ FileUtils.mkdir_p(base)
32
+ unless Dir.exist?(@workspace_path)
33
+ # First run: create empty workspace folder; HealingWorkspaceManager will clone on demand
34
+ FileUtils.mkdir_p(@workspace_path)
35
+ end
36
+ end
37
+
38
+ def preload_context
39
+ # Build a compact code map for the entire repo, excluding ignored paths
40
+ repo_root = Rails.root.to_s
41
+ ignore = CodeHealer::ConfigManager.claude_ignore_paths
42
+
43
+ files = Dir.chdir(repo_root) do
44
+ Dir.glob("**/*", File::FNM_DOTMATCH)
45
+ .select { |f| File.file?(f) }
46
+ .reject do |f|
47
+ # Skip current/parent, VCS metadata, and ignored dirs/files
48
+ f == '.' || f == '..' ||
49
+ ignore.any? { |ig| f == ig || f.start_with?("#{ig}/") || f.include?("/#{ig}/") }
50
+ end
51
+ end
52
+
53
+ map = files.map do |f|
54
+ { file: f, size: File.size?(File.join(repo_root, f)) || 0 }
55
+ end
56
+
57
+ cache_dir = Rails.root.join('tmp')
58
+ FileUtils.mkdir_p(cache_dir)
59
+ File.write(cache_dir.join('code_healer_context.json'), JSON.pretty_generate(map))
60
+ puts "🧠 Claude preload: indexed #{map.size} files (excluding ignores)"
61
+ end
62
+ end
63
+ end
64
+ end
65
+
66
+
@@ -82,6 +82,22 @@ module CodeHealer
82
82
  config['claude_code'] || {}
83
83
  end
84
84
 
85
+ def claude_persist_session?
86
+ claude_code_settings['persist_session'] == true
87
+ end
88
+
89
+ def claude_preload_paths
90
+ claude_code_settings['preload_paths'] || [
91
+ 'app', 'lib', 'config', 'Gemfile', 'Gemfile.lock'
92
+ ]
93
+ end
94
+
95
+ def claude_ignore_paths
96
+ claude_code_settings['ignore'] || [
97
+ '.git', 'tmp', 'log', 'storage', 'node_modules', 'vendor', 'public', 'packs', '.bundle', 'bootsnap', 'cache'
98
+ ]
99
+ end
100
+
85
101
  # Business Context Configuration
86
102
  def business_context_enabled?
87
103
  config.dig('business_context', 'enabled') == true
@@ -96,6 +112,23 @@ module CodeHealer
96
112
  config['api'] || {}
97
113
  end
98
114
 
115
+ # Demo Configuration
116
+ def demo_settings
117
+ config['demo'] || {}
118
+ end
119
+
120
+ def demo_mode?
121
+ demo_settings['enabled'] == true
122
+ end
123
+
124
+ def demo_skip_tests?
125
+ demo_mode? && demo_settings['skip_tests'] != false
126
+ end
127
+
128
+ def demo_skip_pr?
129
+ demo_mode? && demo_settings['skip_pr'] != false
130
+ end
131
+
99
132
  def git_settings
100
133
  config['git'] || {}
101
134
  end
@@ -108,6 +141,11 @@ module CodeHealer
108
141
  def code_heal_directory_path
109
142
  code_heal_directory_config['path'] || '/tmp/code_healer_workspaces'
110
143
  end
144
+
145
+ def sticky_workspace?
146
+ cfg = code_heal_directory_config
147
+ cfg['sticky_workspace'] == true || cfg[:sticky_workspace] == true
148
+ end
111
149
 
112
150
  def auto_cleanup_workspaces?
113
151
  code_heal_directory_config['auto_cleanup'] != false
@@ -273,6 +311,11 @@ module CodeHealer
273
311
  'max_tokens' => 2000,
274
312
  'temperature' => 0.1
275
313
  },
314
+ 'demo' => {
315
+ 'enabled' => false,
316
+ 'skip_tests' => true,
317
+ 'skip_pr' => true
318
+ },
276
319
  'git' => {
277
320
  'auto_commit' => true,
278
321
  'auto_push' => true,
@@ -21,10 +21,27 @@ module CodeHealer
21
21
  @metrics = @metrics.by_evolution_method(params[:evolution_method]) if params[:evolution_method].present?
22
22
  @metrics = @metrics.by_ai_provider(params[:ai_provider]) if params[:ai_provider].present?
23
23
  @metrics = @metrics.recent(params[:days].to_i) if params[:days].present?
24
+ @metrics = @metrics.limit(params[:limit].to_i) if params[:limit].present?
24
25
 
26
+ # Render compact JSON suitable for dashboard list
27
+ payload = @metrics.map do |m|
28
+ {
29
+ healing_id: m.healing_id,
30
+ class_name: m.class_name,
31
+ method_name: m.method_name,
32
+ error_class: m.error_class,
33
+ error_message: m.error_message,
34
+ healing_successful: m.healing_successful,
35
+ status: m.display_status,
36
+ created_at: m.created_at.in_time_zone(Time.zone),
37
+ healing_branch: m.healing_branch,
38
+ pull_request_url: m.pull_request_url
39
+ }
40
+ end
41
+
25
42
  respond_to do |format|
26
- format.html { render template: "dashboard/metrics" }
27
- format.json { render json: @metrics }
43
+ format.json { render json: payload }
44
+ format.any { render json: payload }
28
45
  end
29
46
  end
30
47
 
@@ -52,6 +69,25 @@ module CodeHealer
52
69
  render json: { error: 'Healing not found' }, status: :not_found
53
70
  end
54
71
  end
72
+ format.any do
73
+ if @healing
74
+ render json: {
75
+ healing: @healing,
76
+ timing: {
77
+ total_duration: @healing.duration_seconds,
78
+ ai_processing: @healing.ai_processing_seconds,
79
+ git_operations: @healing.git_operations_seconds
80
+ },
81
+ status: {
82
+ success: @healing.success_status,
83
+ evolution_method: @healing.evolution_method_display,
84
+ ai_provider: @healing.ai_provider_display
85
+ }
86
+ }
87
+ else
88
+ render json: { error: 'Healing not found' }, status: :not_found
89
+ end
90
+ end
55
91
  end
56
92
  end
57
93
 
@@ -15,42 +15,106 @@ module CodeHealer
15
15
  puts "🚀 [HEALING_JOB] Parsed args - Error: #{error.class}, Class: #{class_name}, Method: #{method_name}, Evolution: #{evolution_method}"
16
16
  puts "🚀 [HEALING_JOB] Backtrace length: #{backtrace&.length || 0}"
17
17
 
18
+ # Track start metric
19
+ healing_id = MetricsCollector.generate_healing_id
20
+ MetricsCollector.track_healing_start(
21
+ healing_id,
22
+ class_name.to_s,
23
+ method_name.to_s,
24
+ error.class.name,
25
+ error.message,
26
+ nil # file_path not available in this flow
27
+ )
28
+ MetricsCollector.track_error_occurrence(healing_id, Time.current)
29
+
18
30
  puts "🚀 Evolution Job Started: #{class_name}##{method_name}"
19
31
 
20
- puts "🏥 [HEALING_JOB] About to create isolated healing workspace..."
32
+ puts "🏥 [HEALING_JOB] About to create isolated healing workspace..."
21
33
  # Create isolated healing workspace
22
34
  workspace_path = create_healing_workspace(class_name, method_name)
35
+ MetricsCollector.track_workspace_creation(healing_id, workspace_path)
23
36
  puts "🏥 [HEALING_JOB] Workspace created: #{workspace_path}"
24
37
 
38
+ ai_time_ms = nil
39
+ git_time_ms = nil
40
+ test_success = false
41
+ overall_success = false
42
+ syntax_valid = false
43
+ failure_reason = nil
44
+
25
45
  begin
26
46
  puts "🔧 [HEALING_JOB] About to apply fixes in isolated environment..."
27
47
  # Apply fixes in isolated environment
48
+ ai_started_at = Process.clock_gettime(Process::CLOCK_MONOTONIC)
28
49
  success = apply_fixes_in_workspace(workspace_path, error, class_name, method_name, evolution_method)
50
+ ai_time_ms = ((Process.clock_gettime(Process::CLOCK_MONOTONIC) - ai_started_at) * 1000).round
29
51
 
30
52
  if success
53
+ # Record AI processing success
54
+ MetricsCollector.track_ai_processing(
55
+ healing_id,
56
+ evolution_method,
57
+ ai_provider_for(evolution_method),
58
+ 'success'
59
+ )
60
+
31
61
  # Test fixes in isolated environment
32
62
  test_success = CodeHealer::HealingWorkspaceManager.test_fixes_in_workspace(workspace_path)
33
63
 
34
64
  if test_success
35
- # Merge back to main repo
65
+ syntax_valid = true
66
+ # Create healing branch from workspace
67
+ git_started_at = Process.clock_gettime(Process::CLOCK_MONOTONIC)
36
68
  healing_branch = CodeHealer::HealingWorkspaceManager.create_healing_branch(
37
69
  Rails.root.to_s,
38
70
  workspace_path,
39
71
  CodeHealer::ConfigManager.git_settings['pr_target_branch'] || 'main'
40
72
  )
73
+ git_time_ms = ((Process.clock_gettime(Process::CLOCK_MONOTONIC) - git_started_at) * 1000).round
41
74
 
42
75
  if healing_branch
76
+ MetricsCollector.track_git_operations(
77
+ healing_id,
78
+ healing_branch,
79
+ nil, # PR URL (skipped in workspace flow)
80
+ false # pr_created
81
+ )
82
+ overall_success = true
43
83
  puts "✅ Fixes applied, tested, and merged successfully! Branch: #{healing_branch}"
44
84
  else
85
+ overall_success = false
86
+ failure_reason ||= 'healing_branch_creation_failed'
45
87
  puts "⚠️ Fixes applied and tested, but merge failed"
46
88
  end
47
89
  else
90
+ overall_success = false
91
+ syntax_valid = false
92
+ failure_reason ||= 'workspace_tests_failed_or_syntax_error'
48
93
  puts "⚠️ Fixes applied but failed tests, not merging back"
49
94
  end
50
95
  else
96
+ overall_success = false
97
+ failure_reason ||= 'ai_evolution_failed'
98
+ # Record AI processing failure
99
+ MetricsCollector.track_ai_failure(
100
+ healing_id,
101
+ evolution_method,
102
+ ai_provider_for(evolution_method),
103
+ failure_reason
104
+ )
51
105
  puts "❌ Failed to apply fixes in workspace"
52
106
  end
53
107
  ensure
108
+ # Persist timing metrics if captured
109
+ MetricsCollector.track_timing(healing_id, ai_time_ms, git_time_ms) if ai_time_ms || git_time_ms
110
+ # Mark completion
111
+ MetricsCollector.track_healing_completion(
112
+ healing_id,
113
+ overall_success,
114
+ test_success,
115
+ syntax_valid,
116
+ failure_reason
117
+ )
54
118
  # Clean up workspace
55
119
  cleanup_workspace(workspace_path)
56
120
  end
@@ -82,6 +146,19 @@ module CodeHealer
82
146
  end
83
147
  end
84
148
 
149
+ def ai_provider_for(evolution_method)
150
+ case evolution_method
151
+ when 'claude_code_terminal'
152
+ 'claude'
153
+ when 'api'
154
+ 'openai'
155
+ when 'hybrid'
156
+ 'hybrid'
157
+ else
158
+ 'unknown'
159
+ end
160
+ end
161
+
85
162
  def create_healing_workspace(class_name, method_name)
86
163
  puts "🏥 Creating isolated healing workspace for #{class_name}##{method_name}"
87
164
 
@@ -144,6 +221,9 @@ module CodeHealer
144
221
  error, class_name, method_name
145
222
  )
146
223
 
224
+ # Optionally record business context used
225
+ # MetricsCollector.track_business_context(healing_id, business_context) # healing_id not accessible here
226
+
147
227
  puts "📋 Business context loaded for API evolution"
148
228
 
149
229
  # Change to workspace directory for API operations
@@ -106,16 +106,19 @@ module CodeHealer
106
106
  syntax_check = system("ruby -c #{find_ruby_files.join(' ')} 2>/dev/null")
107
107
  return false unless syntax_check
108
108
 
109
- # Run tests if available
110
- if File.exist?('Gemfile')
111
- bundle_check = system("bundle check >/dev/null 2>&1")
112
- return false unless bundle_check
113
-
114
- # Run tests if RSpec is available
115
- if File.exist?('spec') || File.exist?('test')
116
- test_result = system("bundle exec rspec --dry-run >/dev/null 2>&1") ||
117
- system("bundle exec rake test:prepare >/dev/null 2>&1")
118
- puts "🧪 Test preparation: #{test_result ? '✅' : '⚠️'}"
109
+ # Optionally skip heavy tests in demo mode
110
+ unless CodeHealer::ConfigManager.demo_skip_tests?
111
+ # Run tests if available
112
+ if File.exist?('Gemfile')
113
+ bundle_check = system("bundle check >/dev/null 2>&1")
114
+ return false unless bundle_check
115
+
116
+ # Run tests if RSpec is available
117
+ if File.exist?('spec') || File.exist?('test')
118
+ test_result = system("bundle exec rspec --dry-run >/dev/null 2>&1") ||
119
+ system("bundle exec rake test:prepare >/dev/null 2>&1")
120
+ puts "🧪 Test preparation: #{test_result ? '✅' : '⚠️'}"
121
+ end
119
122
  end
120
123
  end
121
124
 
@@ -170,7 +173,7 @@ module CodeHealer
170
173
  puts "📝 All changes committed in isolated workspace"
171
174
 
172
175
  # Create pull request if auto-create is enabled and no PR was already created
173
- if should_create_pull_request?
176
+ if should_create_pull_request? && !CodeHealer::ConfigManager.demo_skip_pr?
174
177
  puts "🔍 [WORKSPACE] Checking if PR was already created by evolution handler..."
175
178
  # Skip PR creation if we're in a healing workflow (PR likely already created)
176
179
  puts "🔍 [WORKSPACE] PR creation skipped - likely already created by evolution handler"
@@ -60,13 +60,15 @@ module CodeHealer
60
60
  end
61
61
 
62
62
  def daily_healing_trend(days = 30)
63
- # Use Rails date methods instead of raw SQL
63
+ # Timezone-aware daily buckets using application time zone
64
64
  start_date = days.days.ago.to_date
65
- end_date = Date.current
66
-
65
+ end_date = Time.zone.today
66
+
67
67
  trend_data = {}
68
68
  (start_date..end_date).each do |date|
69
- count = where('DATE(created_at) = ?', date).count
69
+ day_start = Time.zone.parse(date.to_s).beginning_of_day
70
+ day_end = day_start.end_of_day
71
+ count = where(created_at: day_start..day_end).count
70
72
  trend_data[date.strftime('%Y-%m-%d')] = count
71
73
  end
72
74
  trend_data
@@ -86,6 +88,14 @@ module CodeHealer
86
88
  end
87
89
 
88
90
  # Instance methods
91
+ def processing?
92
+ healing_completed_at.nil?
93
+ end
94
+
95
+ def display_status
96
+ return 'processing' if processing?
97
+ healing_successful ? 'success' : 'failed'
98
+ end
89
99
  def duration_seconds
90
100
  return nil unless total_duration_ms
91
101
  (total_duration_ms / 1000.0).round(2)
@@ -102,6 +112,7 @@ module CodeHealer
102
112
  end
103
113
 
104
114
  def success_status
115
+ return '⏳ Processing' if processing?
105
116
  healing_successful ? '✅ Success' : '❌ Failed'
106
117
  end
107
118
 
@@ -9,7 +9,7 @@ module CodeHealer
9
9
  error_class: error_class,
10
10
  error_message: error_message,
11
11
  file_path: file_path,
12
- healing_started_at: Time.current
12
+ healing_started_at: Time.zone.now
13
13
  )
14
14
 
15
15
  metric.save!
@@ -66,13 +66,13 @@ module CodeHealer
66
66
 
67
67
  # Calculate timing
68
68
  total_duration = if metric.healing_started_at
69
- ((Time.current - metric.healing_started_at) * 1000).round
69
+ ((Time.zone.now - metric.healing_started_at) * 1000).round
70
70
  else
71
71
  nil
72
72
  end
73
73
 
74
74
  metric.update!(
75
- healing_completed_at: Time.current,
75
+ healing_completed_at: Time.zone.now,
76
76
  total_duration_ms: total_duration,
77
77
  healing_successful: success,
78
78
  tests_passed: tests_passed,
@@ -106,7 +106,7 @@ module CodeHealer
106
106
  metric = HealingMetric.find_by(healing_id: healing_id)
107
107
  return unless metric
108
108
 
109
- metric.update!(error_occurred_at: error_occurred_at)
109
+ metric.update!(error_occurred_at: error_occurred_at.in_time_zone(Time.zone))
110
110
  end
111
111
 
112
112
  # Generate unique healing ID
@@ -320,6 +320,35 @@ evolution_method = case evolution_method.downcase
320
320
 
321
321
  fallback_to_api = ask_for_yes_no("Fallback to API if Claude Code fails?", default: true)
322
322
 
323
+ # Demo Mode Configuration
324
+ puts
325
+ puts "🎭 Demo Mode Configuration:"
326
+ puts "Demo mode optimizes CodeHealer for fast demonstrations and presentations:"
327
+ puts "- Skips test generation for faster response times"
328
+ puts "- Skips pull request creation for immediate results"
329
+ puts "- Uses optimized Claude prompts for quick fixes"
330
+ puts
331
+
332
+ enable_demo_mode = ask_for_yes_no("Enable demo mode for fast demonstrations?", default: false)
333
+
334
+ demo_config = {}
335
+ if enable_demo_mode
336
+ demo_config[:skip_tests] = ask_for_yes_no("Skip test generation in demo mode?", default: true)
337
+ demo_config[:skip_pr] = ask_for_yes_no("Skip pull request creation in demo mode?", default: true)
338
+
339
+ puts
340
+ puts "🚀 Demo mode will significantly speed up healing operations!"
341
+ puts " Perfect for conference talks and live demonstrations."
342
+
343
+ # Add demo-specific instructions
344
+ puts
345
+ puts "📋 Demo Mode Features:"
346
+ puts " - Timeout reduced to 60 seconds for quick responses"
347
+ puts " - Sticky workspace enabled for faster context loading"
348
+ puts " - Claude session persistence for better performance"
349
+ puts " - Tests and PRs skipped for immediate results"
350
+ end
351
+
323
352
  # Create configuration files
324
353
  puts
325
354
  puts "📝 Step 3: Creating Configuration Files"
@@ -377,11 +406,18 @@ create_file_with_content('.env', env_content, dry_run: options[:dry_run])
377
406
 
378
407
  # Claude Code Terminal Configuration
379
408
  claude_code:
380
- enabled: #{evolution_method == 'claude_code_terminal' || evolution_method == 'hybrid'}
381
- timeout: 300 # Timeout in seconds
409
+ enabled: #{evolution_method == 'claude_code_terminal' || evolution_method == 'hybrid'}
410
+ timeout: #{enable_demo_mode ? 60 : 300} # Shorter timeout for demo mode
382
411
  max_file_changes: 10
383
- include_tests: true
384
- command_template: "claude --print '{prompt}' --output-format text --permission-mode acceptEdits --allowedTools Edit"
412
+ include_tests: #{!enable_demo_mode || !demo_config[:skip_tests]}
413
+ persist_session: true # Keep Claude session alive for faster responses
414
+ ignore:
415
+ - "tmp/"
416
+ - "log/"
417
+ - ".git/"
418
+ - "node_modules/"
419
+ - "vendor/"
420
+ command_template: "claude --print '{prompt}' --output-format text --permission-mode acceptEdits --allowedTools Edit"
385
421
  business_context_sources:
386
422
  - "config/business_rules.yml"
387
423
  - "docs/business_logic.md"
@@ -431,6 +467,12 @@ create_file_with_content('.env', env_content, dry_run: options[:dry_run])
431
467
  slack_webhook: ""
432
468
  email_notifications: false
433
469
 
470
+ # Demo Mode Configuration
471
+ demo:
472
+ enabled: #{enable_demo_mode}
473
+ skip_tests: #{demo_config[:skip_tests] || false}
474
+ skip_pr: #{demo_config[:skip_pr] || false}
475
+
434
476
  # Performance Configuration
435
477
  performance:
436
478
  max_concurrent_healing: 3
@@ -444,6 +486,7 @@ create_file_with_content('.env', env_content, dry_run: options[:dry_run])
444
486
  cleanup_after_hours: #{cleanup_after_hours}
445
487
  max_workspaces: 10
446
488
  clone_strategy: "branch" # Options: branch, full_repo
489
+ sticky_workspace: #{enable_demo_mode} # Reuse workspace for faster demo responses
447
490
  YAML
448
491
 
449
492
  create_file_with_content('config/code_healer.yml', config_content, dry_run: options[:dry_run])
@@ -519,10 +562,13 @@ puts " - .env file contains your actual API keys and is ignored by git"
519
562
  puts " - .env.example is safe to commit and shows the required format"
520
563
  puts " - Never commit .env files with real secrets to version control"
521
564
  puts
522
- puts "🏥 Code Heal Directory:"
523
- puts " - Your code will be cloned to: #{code_heal_directory}"
524
- puts " - This ensures safe, isolated healing without affecting your running server"
525
- puts " - Workspaces are automatically cleaned up after #{cleanup_after_hours} hours"
565
+ puts "🏥 Code Heal Directory:"
566
+ puts " - Your code will be cloned to: #{code_heal_directory}"
567
+ puts " - This ensures safe, isolated healing without affecting your running server"
568
+ puts " - Workspaces are automatically cleaned up after #{cleanup_after_hours} hours"
569
+ if enable_demo_mode
570
+ puts " - Demo mode: Sticky workspace enabled for faster context loading"
571
+ end
526
572
  puts
527
573
  puts "⚙️ Configuration:"
528
574
  puts " - code_healer.yml contains comprehensive settings with sensible defaults"
@@ -535,6 +581,10 @@ puts " - All features are pre-configured and ready to use"
535
581
  puts " - Or load .env file in your application.rb: load '.env' if File.exist?('.env')"
536
582
  puts
537
583
  puts "CodeHealer will now automatically detect and heal errors in your application!"
584
+ puts
585
+ puts "📊 Dashboard:"
586
+ puts " - Access your healing metrics at: /code_healer/dashboard"
587
+ puts " - API endpoints available at: /code_healer/api/dashboard/*"
538
588
  end
539
589
 
540
590
  puts
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CodeHealer
4
- VERSION = "0.1.15"
4
+ VERSION = "0.1.17"
5
5
  end
data/lib/code_healer.rb CHANGED
@@ -33,6 +33,7 @@ autoload :MCP, "code_healer/mcp"
33
33
  require_relative "code_healer/models/healing_metric"
34
34
  require_relative "code_healer/services/metrics_collector"
35
35
  require_relative "code_healer/controllers/dashboard_controller"
36
+ require_relative "code_healer/claude_session"
36
37
  autoload :Installer, "code_healer/installer"
37
38
 
38
39
  # Rails integration
@@ -78,5 +79,14 @@ if defined?(Rails)
78
79
  mount CodeHealer::Engine => "/code_healer"
79
80
  end
80
81
  end
82
+
83
+ # Preload Claude session and repository context once per boot
84
+ config.after_initialize do
85
+ begin
86
+ CodeHealer::ClaudeSession.start!
87
+ rescue => e
88
+ puts "⚠️ Claude preload failed: #{e.message}"
89
+ end
90
+ end
81
91
  end
82
92
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: code_healer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.15
4
+ version: 0.1.17
5
5
  platform: ruby
6
6
  authors:
7
7
  - Deepan Kumar
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-08-20 00:00:00.000000000 Z
11
+ date: 2025-08-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -363,6 +363,7 @@ files:
363
363
  - lib/code_healer/business_rule_applier.rb
364
364
  - lib/code_healer/claude_code_evolution_handler.rb
365
365
  - lib/code_healer/claude_error_monitor.rb
366
+ - lib/code_healer/claude_session.rb
366
367
  - lib/code_healer/config_manager.rb
367
368
  - lib/code_healer/context_aware_prompt_builder.rb
368
369
  - lib/code_healer/controllers/dashboard_controller.rb