code_healer 0.1.3 โ†’ 0.1.6

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: fcc597b56e69d320ba09b31cf5841c188a7b9599275c0ab5d7a8f4a352fc4142
4
- data.tar.gz: c20f8a3e50018e4ecc4c5d7b42c77c68522dfaf97435eb7dc99a8e83d7f10b89
3
+ metadata.gz: a1ceaaefb9e7954b186c14720e3a68876975deed3d720e812420933dd6016484
4
+ data.tar.gz: 5299cd3f4a2e394700692d65e74d8132e1bd77b779220cda6b40c0e9db6d2f76
5
5
  SHA512:
6
- metadata.gz: d7c683615b16fabf415d946c5b37b0bbaa13ef491b50d7a803d95688005bc406a07dfa333df4d9808631d68bb4073257577ec5d6f15bcce38379a3b720ef62c5
7
- data.tar.gz: 79f822c7bea5d3b3d59a80201454bd7191b383aa4bb6ae56954cc0e32f42b35f5cbdc4da2ce2f3939ec3a4c00b1c71a4dd23dae654745fe29a6cf2c9a92668ec
6
+ metadata.gz: a84ffb72f678182aceaf0e39e206e55e9684811c1e2edbccf6bc5368a1a6330123f9215bb5fa81dd47b63042b94a01e93accaa700a958058ad155673b518b68e
7
+ data.tar.gz: 1a07538709f991f556c5fe407e8212aeb21f161f107494d4a07323b6db10389b1471ddc9b61834097b8a41161c6e287ec335dd739227562a56842d67b25f7097
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
+ ## [0.1.6] - 2025-01-14
9
+
10
+ ### Added
11
+ - **Code heal directory permission validation** during interactive setup
12
+ - **Repository access testing** to ensure the directory can clone and push to the target repo
13
+ - **Write permission verification** for the code heal directory
14
+ - **Automatic directory creation** if it doesn't exist
15
+ - **Comprehensive error messages** with troubleshooting tips for permission issues
16
+
17
+ ### Fixed
18
+ - **Duplicate HealingJob class definition** that was preventing isolated healing workspace system from working
19
+ - **Class loading conflict** between old and new healing logic
20
+ - **Isolated healing workspace system** now properly activated
21
+
22
+ ## [0.1.4] - 2025-01-14
23
+
24
+ ### Added
25
+ - **Comprehensive logging** for isolated healing workspace system
26
+ - **Detailed workspace creation logs** showing each step of the process
27
+ - **Clone operation logging** with success/failure status
28
+ - **Fix application logging** in isolated environment
29
+ - **Workspace cleanup logging** for debugging
30
+
31
+ ### Fixed
32
+ - **Workspace configuration reading** to handle both string and symbol keys
33
+ - **Branch name sanitization** to prevent invalid Git branch names
34
+
8
35
  ## [0.1.3] - 2025-01-14
9
36
 
10
37
  ### Added
@@ -99,6 +99,27 @@ module CodeHealer
99
99
  def git_settings
100
100
  config['git'] || {}
101
101
  end
102
+
103
+ # Code Heal Directory Configuration
104
+ def code_heal_directory_config
105
+ config['code_heal_directory'] || {}
106
+ end
107
+
108
+ def code_heal_directory_path
109
+ code_heal_directory_config['path'] || '/tmp/code_healer_workspaces'
110
+ end
111
+
112
+ def auto_cleanup_workspaces?
113
+ code_heal_directory_config['auto_cleanup'] != false
114
+ end
115
+
116
+ def workspace_cleanup_after_hours
117
+ code_heal_directory_config['cleanup_after_hours'] || 24
118
+ end
119
+
120
+ def max_workspaces
121
+ code_heal_directory_config['max_workspaces'] || 10
122
+ end
102
123
 
103
124
  def pull_request_settings
104
125
  config['pull_request'] || {}
@@ -267,6 +288,13 @@ module CodeHealer
267
288
  'safety' => {
268
289
  'backup_before_evolution' => true,
269
290
  'rollback_on_syntax_error' => true
291
+ },
292
+ 'code_heal_directory' => {
293
+ 'path' => '/tmp/code_healer_workspaces',
294
+ 'auto_cleanup' => true,
295
+ 'cleanup_after_hours' => 24,
296
+ 'max_workspaces' => 10,
297
+ 'clone_strategy' => 'branch'
270
298
  }
271
299
  }
272
300
  end
@@ -9,18 +9,39 @@ class EvolutionJob
9
9
  # Reconstruct the error object
10
10
  error = reconstruct_error(error_data)
11
11
 
12
- # Determine evolution strategy
13
- evolution_method = CodeHealer::ConfigManager.evolution_method
12
+ # Create isolated healing workspace
13
+ workspace_path = create_healing_workspace(class_name, method_name)
14
14
 
15
- case evolution_method
16
- when 'claude_code_terminal'
17
- handle_claude_code_evolution(error, class_name, method_name, file_path)
18
- when 'api'
19
- handle_api_evolution(error, class_name, method_name, file_path)
20
- when 'hybrid'
21
- handle_hybrid_evolution(error, class_name, method_name, file_path)
22
- else
23
- puts "โŒ Unknown evolution method: #{evolution_method}"
15
+ begin
16
+ # Apply fixes in isolated environment
17
+ success = apply_fixes_in_workspace(workspace_path, error, class_name, method_name)
18
+
19
+ if success
20
+ # Test fixes in isolated environment
21
+ test_success = CodeHealer::HealingWorkspaceManager.test_fixes_in_workspace(workspace_path)
22
+
23
+ if test_success
24
+ # Merge back to main repo
25
+ healing_branch = CodeHealer::HealingWorkspaceManager.merge_fixes_back(
26
+ Rails.root.to_s,
27
+ workspace_path,
28
+ CodeHealer::ConfigManager.git_settings['pr_target_branch'] || 'main'
29
+ )
30
+
31
+ if healing_branch
32
+ puts "โœ… Fixes applied, tested, and merged successfully! Branch: #{healing_branch}"
33
+ else
34
+ puts "โš ๏ธ Fixes applied and tested, but merge failed"
35
+ end
36
+ else
37
+ puts "โš ๏ธ Fixes applied but failed tests, not merging back"
38
+ end
39
+ else
40
+ puts "โŒ Failed to apply fixes in workspace"
41
+ end
42
+ ensure
43
+ # Clean up workspace
44
+ cleanup_workspace(workspace_path)
24
45
  end
25
46
 
26
47
  puts "โœ… Evolution Job Completed: #{class_name}##{method_name}"
@@ -32,35 +53,59 @@ class EvolutionJob
32
53
 
33
54
  private
34
55
 
35
- def reconstruct_error(error_data)
36
- # Reconstruct the error object from serialized data
37
- error_class = Object.const_get(error_data['class'])
38
- error = error_class.new(error_data['message'])
56
+ def create_healing_workspace(class_name, method_name)
57
+ puts "๐Ÿฅ Creating isolated healing workspace for #{class_name}##{method_name}"
39
58
 
40
- # Restore backtrace if available
41
- if error_data['backtrace']
42
- error.set_backtrace(error_data['backtrace'])
43
- end
59
+ # Create unique workspace
60
+ workspace_path = CodeHealer::HealingWorkspaceManager.create_healing_workspace(
61
+ Rails.root.to_s,
62
+ nil # Use current branch
63
+ )
44
64
 
45
- error
65
+ puts "โœ… Healing workspace created: #{workspace_path}"
66
+ workspace_path
46
67
  end
47
-
48
- def handle_claude_code_evolution(error, class_name, method_name, file_path)
49
- puts "๐Ÿค– Using Claude Code Terminal for evolution..."
68
+
69
+ def apply_fixes_in_workspace(workspace_path, error, class_name, method_name)
70
+ puts "๐Ÿ”ง Applying fixes in isolated workspace"
50
71
 
51
- # Use the existing Claude Code evolution handler (it's a class method)
52
- success = CodeHealer::ClaudeCodeEvolutionHandler.handle_error_with_claude_code(error, class_name, method_name, file_path)
72
+ # Determine evolution strategy
73
+ evolution_method = CodeHealer::ConfigManager.evolution_method
53
74
 
54
- if success
55
- puts "โœ… Claude Code evolution completed successfully!"
75
+ case evolution_method
76
+ when 'claude_code_terminal'
77
+ handle_claude_code_evolution_in_workspace(workspace_path, error, class_name, method_name)
78
+ when 'api'
79
+ handle_api_evolution_in_workspace(workspace_path, error, class_name, method_name)
80
+ when 'hybrid'
81
+ handle_hybrid_evolution_in_workspace(workspace_path, error, class_name, method_name)
56
82
  else
57
- puts "โŒ Claude Code evolution failed"
58
- raise "Claude Code evolution failed for #{class_name}##{method_name}"
83
+ puts "โŒ Unknown evolution method: #{evolution_method}"
84
+ false
59
85
  end
60
86
  end
61
-
62
- def handle_api_evolution(error, class_name, method_name, file_path)
63
- puts "๐ŸŒ Using OpenAI API for evolution..."
87
+
88
+ def handle_claude_code_evolution_in_workspace(workspace_path, error, class_name, method_name)
89
+ puts "๐Ÿค– Using Claude Code Terminal for evolution in workspace..."
90
+
91
+ # Change to workspace directory for Claude Code operations
92
+ Dir.chdir(workspace_path) do
93
+ success = CodeHealer::ClaudeCodeEvolutionHandler.handle_error_with_claude_code(
94
+ error, class_name, method_name, nil # file_path not needed in workspace
95
+ )
96
+
97
+ if success
98
+ puts "โœ… Claude Code evolution completed successfully in workspace!"
99
+ true
100
+ else
101
+ puts "โŒ Claude Code evolution failed in workspace"
102
+ false
103
+ end
104
+ end
105
+ end
106
+
107
+ def handle_api_evolution_in_workspace(workspace_path, error, class_name, method_name)
108
+ puts "๐ŸŒ Using OpenAI API for evolution in workspace..."
64
109
 
65
110
  # Load business context for API evolution
66
111
  business_context = CodeHealer::BusinessContextManager.get_context_for_error(
@@ -69,31 +114,56 @@ class EvolutionJob
69
114
 
70
115
  puts "๐Ÿ“‹ Business context loaded for API evolution"
71
116
 
72
- # Use the existing MCP evolution handler with business context
73
- success = CodeHealer::SimpleEvolution.handle_error_with_mcp_intelligence(
74
- error, class_name, method_name, file_path, business_context
75
- )
76
-
77
- if success
78
- puts "โœ… API evolution completed successfully!"
79
- else
80
- puts "โŒ API evolution failed"
81
- raise "API evolution failed for #{class_name}##{method_name}"
117
+ # Change to workspace directory for API operations
118
+ Dir.chdir(workspace_path) do
119
+ success = CodeHealer::SimpleEvolution.handle_error_with_mcp_intelligence(
120
+ error, class_name, method_name, nil, business_context # file_path not needed in workspace
121
+ )
122
+
123
+ if success
124
+ puts "โœ… API evolution completed successfully in workspace!"
125
+ true
126
+ else
127
+ puts "โŒ API evolution failed in workspace"
128
+ false
129
+ end
82
130
  end
83
131
  end
84
-
85
- def handle_hybrid_evolution(error, class_name, method_name, file_path)
86
- puts "๐Ÿ”„ Using Hybrid approach for evolution..."
132
+
133
+ def handle_hybrid_evolution_in_workspace(workspace_path, error, class_name, method_name)
134
+ puts "๐Ÿ”„ Using Hybrid approach for evolution in workspace..."
87
135
 
88
136
  begin
89
137
  # Try Claude Code first
90
- success = handle_claude_code_evolution(error, class_name, method_name, file_path)
91
- return if success
138
+ success = handle_claude_code_evolution_in_workspace(workspace_path, error, class_name, method_name)
139
+ return success if success
92
140
  rescue => e
93
141
  puts "โš ๏ธ Claude Code failed, falling back to API: #{e.message}"
94
142
  end
95
143
 
96
144
  # Fallback to API
97
- handle_api_evolution(error, class_name, method_name, file_path)
145
+ handle_api_evolution_in_workspace(workspace_path, error, class_name, method_name)
146
+ end
147
+
148
+ def cleanup_workspace(workspace_path)
149
+ return unless workspace_path && Dir.exist?(workspace_path)
150
+
151
+ puts "๐Ÿงน Cleaning up healing workspace: #{workspace_path}"
152
+ CodeHealer::HealingWorkspaceManager.cleanup_workspace(workspace_path)
153
+ end
154
+
155
+ def reconstruct_error(error_data)
156
+ # Reconstruct the error object from serialized data
157
+ error_class = Object.const_get(error_data['class'])
158
+ error = error_class.new(error_data['message'])
159
+
160
+ # Restore backtrace if available
161
+ if error_data['backtrace']
162
+ error.set_backtrace(error_data['backtrace'])
163
+ end
164
+
165
+ error
98
166
  end
167
+
168
+
99
169
  end
@@ -1,167 +1,187 @@
1
- # frozen_string_literal: true
1
+ require 'sidekiq'
2
2
 
3
3
  module CodeHealer
4
4
  class HealingJob
5
5
  include Sidekiq::Job
6
-
6
+
7
7
  sidekiq_options retry: 3, backtrace: true, queue: 'evolution'
8
-
9
- def perform(error_type, error_message, class_name, method_name, evolution_method = 'api', backtrace = nil)
10
- puts "๐Ÿš€ Evolution Job Started: #{class_name}##{method_name}"
8
+
9
+ def perform(*args)
10
+ puts "๐Ÿš€ [HEALING_JOB] Starting job with args: #{args.inspect}"
11
11
 
12
- # Reconstruct the error object with backtrace
13
- error = reconstruct_error(error_type, error_message, backtrace)
12
+ # Support both legacy and new invocation styles
13
+ error, class_name, method_name, evolution_method, backtrace = parse_args(args)
14
14
 
15
- # Determine evolution strategy
16
- case evolution_method
17
- when 'claude_code_terminal'
18
- handle_claude_code_evolution(error, class_name, method_name)
19
- when 'api'
20
- handle_api_evolution(error, class_name, method_name)
21
- when 'hybrid'
22
- handle_hybrid_evolution(error, class_name, method_name)
23
- else
24
- puts "โš ๏ธ Unknown evolution method: #{evolution_method}"
15
+ puts "๐Ÿš€ [HEALING_JOB] Parsed args - Error: #{error.class}, Class: #{class_name}, Method: #{method_name}, Evolution: #{evolution_method}"
16
+ puts "๐Ÿš€ [HEALING_JOB] Backtrace length: #{backtrace&.length || 0}"
17
+
18
+ puts "๐Ÿš€ Evolution Job Started: #{class_name}##{method_name}"
19
+
20
+ puts "๐Ÿฅ [HEALING_JOB] About to create isolated healing workspace..."
21
+ # Create isolated healing workspace
22
+ workspace_path = create_healing_workspace(class_name, method_name)
23
+ puts "๐Ÿฅ [HEALING_JOB] Workspace created: #{workspace_path}"
24
+
25
+ begin
26
+ puts "๐Ÿ”ง [HEALING_JOB] About to apply fixes in isolated environment..."
27
+ # Apply fixes in isolated environment
28
+ success = apply_fixes_in_workspace(workspace_path, error, class_name, method_name, evolution_method)
29
+
30
+ if success
31
+ # Test fixes in isolated environment
32
+ test_success = CodeHealer::HealingWorkspaceManager.test_fixes_in_workspace(workspace_path)
33
+
34
+ if test_success
35
+ # Merge back to main repo
36
+ healing_branch = CodeHealer::HealingWorkspaceManager.merge_fixes_back(
37
+ Rails.root.to_s,
38
+ workspace_path,
39
+ CodeHealer::ConfigManager.git_settings['pr_target_branch'] || 'main'
40
+ )
41
+
42
+ if healing_branch
43
+ puts "โœ… Fixes applied, tested, and merged successfully! Branch: #{healing_branch}"
44
+ else
45
+ puts "โš ๏ธ Fixes applied and tested, but merge failed"
46
+ end
47
+ else
48
+ puts "โš ๏ธ Fixes applied but failed tests, not merging back"
49
+ end
50
+ else
51
+ puts "โŒ Failed to apply fixes in workspace"
52
+ end
53
+ ensure
54
+ # Clean up workspace
55
+ cleanup_workspace(workspace_path)
25
56
  end
57
+
58
+ puts "โœ… Evolution Job Completed: #{class_name}##{method_name}"
59
+ rescue => e
60
+ puts "โŒ Evolution Job Failed: #{e.message}"
61
+ puts "๐Ÿ“ Backtrace: #{e.backtrace.first(5)}"
62
+ raise e # Re-raise to trigger Sidekiq retry
26
63
  end
27
-
64
+
28
65
  private
29
-
30
- def handle_claude_code_evolution(error, class_name, method_name)
31
- puts "๐Ÿค– Using Claude Code Terminal for evolution..."
32
-
33
- if defined?(CodeHealer::ClaudeCodeEvolutionHandler)
34
- # For Claude Code: pass the full backtrace instead of file path
35
- # Claude can analyze the backtrace and find files itself
36
- puts "๐Ÿ“‹ Sending full backtrace to Claude Code for intelligent analysis"
37
- puts "๐Ÿ” Backtrace length: #{error.backtrace&.length || 0} lines"
38
-
39
- CodeHealer::ClaudeCodeEvolutionHandler.handle_error_with_claude_code(
40
- error, class_name, method_name, nil
41
- )
66
+
67
+ def parse_args(args)
68
+ # Formats supported:
69
+ # 1) [error_class, error_message, class_name, method_name, evolution_method, backtrace]
70
+ # 2) [error_data_hash, class_name, method_name, file_path]
71
+ if args.length >= 6 && args[0].is_a?(String)
72
+ error_class, error_message, class_name, method_name, evolution_method, backtrace = args
73
+ error = reconstruct_error({ 'class' => error_class, 'message' => error_message, 'backtrace' => backtrace })
74
+ [error, class_name, method_name, evolution_method, backtrace]
75
+ elsif args.length == 4 && args[0].is_a?(Hash)
76
+ error_data, class_name, method_name, _file_path = args
77
+ error = reconstruct_error(error_data)
78
+ evolution_method = CodeHealer::ConfigManager.evolution_method
79
+ [error, class_name, method_name, evolution_method, error.backtrace]
42
80
  else
43
- puts "โš ๏ธ ClaudeCodeEvolutionHandler not available"
81
+ raise ArgumentError, "Unsupported HealingJob arguments: #{args.inspect}"
44
82
  end
45
83
  end
46
-
47
- def handle_api_evolution(error, class_name, method_name)
48
- puts "๐ŸŒ Using OpenAI API for evolution..."
49
-
50
- # For API: extract file path since API doesn't have codebase access
51
- file_path = extract_file_path_from_backtrace(error.backtrace)
52
- puts "๐Ÿ“ File path for API: #{file_path || 'Not found'}"
53
-
54
- # Load business context
55
- if defined?(CodeHealer::BusinessContextManager)
56
- business_context = CodeHealer::BusinessContextManager.get_context_for_error(
57
- error, class_name, method_name
58
- )
59
- puts "๐Ÿ“‹ Business context loaded for API evolution"
60
- else
61
- business_context = {}
62
- puts "โš ๏ธ BusinessContextManager not available"
63
- end
64
-
65
- # Use SimpleHealer for API-based evolution
66
- if defined?(CodeHealer::SimpleHealer)
67
- CodeHealer::SimpleHealer.handle_error_with_mcp_intelligence(
68
- error, class_name, method_name, file_path, business_context
69
- )
84
+
85
+ def create_healing_workspace(class_name, method_name)
86
+ puts "๐Ÿฅ Creating isolated healing workspace for #{class_name}##{method_name}"
87
+
88
+ # Create unique workspace
89
+ workspace_path = CodeHealer::HealingWorkspaceManager.create_healing_workspace(
90
+ Rails.root.to_s,
91
+ nil # Use current branch
92
+ )
93
+
94
+ puts "โœ… Healing workspace created: #{workspace_path}"
95
+ workspace_path
96
+ end
97
+
98
+ def apply_fixes_in_workspace(workspace_path, error, class_name, method_name, evolution_method)
99
+ puts "๐Ÿ”ง Applying fixes in isolated workspace"
100
+
101
+ case evolution_method
102
+ when 'claude_code_terminal'
103
+ handle_claude_code_evolution_in_workspace(workspace_path, error, class_name, method_name)
104
+ when 'api'
105
+ handle_api_evolution_in_workspace(workspace_path, error, class_name, method_name)
106
+ when 'hybrid'
107
+ begin
108
+ success = handle_claude_code_evolution_in_workspace(workspace_path, error, class_name, method_name)
109
+ return true if success
110
+ rescue => e
111
+ puts "โš ๏ธ Claude Code failed, falling back to API: #{e.message}"
112
+ end
113
+ handle_api_evolution_in_workspace(workspace_path, error, class_name, method_name)
70
114
  else
71
- puts "โš ๏ธ SimpleHealer not available"
115
+ puts "โŒ Unknown evolution method: #{evolution_method}"
116
+ false
72
117
  end
73
118
  end
74
-
75
- def handle_hybrid_evolution(error, class_name, method_name)
76
- puts "๐Ÿ”„ Using hybrid evolution strategy..."
77
-
78
- # Try Claude Code first, fallback to API
79
- begin
80
- handle_claude_code_evolution(error, class_name, method_name)
81
- rescue => e
82
- puts "โš ๏ธ Claude Code evolution failed: #{e.message}"
83
- puts "๐Ÿ”„ Falling back to API evolution..."
84
- handle_api_evolution(error, class_name, method_name)
119
+
120
+ def handle_claude_code_evolution_in_workspace(workspace_path, error, class_name, method_name)
121
+ puts "๐Ÿค– Using Claude Code Terminal for evolution in workspace..."
122
+
123
+ # Change to workspace directory for Claude Code operations
124
+ Dir.chdir(workspace_path) do
125
+ success = CodeHealer::ClaudeCodeEvolutionHandler.handle_error_with_claude_code(
126
+ error, class_name, method_name, nil # file_path not needed in workspace
127
+ )
128
+
129
+ if success
130
+ puts "โœ… Claude Code evolution completed successfully in workspace!"
131
+ true
132
+ else
133
+ puts "โŒ Claude Code evolution failed in workspace"
134
+ false
135
+ end
85
136
  end
86
137
  end
87
-
88
- def extract_file_path_from_backtrace(backtrace)
89
- return nil unless backtrace
90
-
91
- core_methods = %w[* + - / % ** == != < > <= >= <=> === =~ !~ & | ^ ~ << >> [] []= `]
92
- app_file_line = backtrace.find { |line| line.include?('/app/') }
93
-
94
- return nil unless app_file_line
95
-
96
- if app_file_line =~ /(.+):(\d+):in `(.+)'/
97
- file_path = $1
98
- method_name = $3
99
-
100
- # Handle Ruby operators by looking deeper in the stack
101
- if core_methods.include?(method_name)
102
- deeper_app_line = backtrace.find do |line|
103
- line.include?('/app/') &&
104
- line =~ /in `(.+)'/ &&
105
- !core_methods.include?($1) &&
106
- !$1.include?('block in') &&
107
- !$1.include?('each') &&
108
- !$1.include?('map') &&
109
- !$1.include?('reduce')
110
- end
111
-
112
- if deeper_app_line && deeper_app_line =~ /(.+):(\d+):in `(.+)'/
113
- file_path = $1
114
- method_name = $3
115
- end
116
- end
117
-
118
- # Handle iterator methods and blocks
119
- if method_name && (
120
- method_name.include?('block in') ||
121
- method_name.include?('each') ||
122
- method_name.include?('map') ||
123
- method_name.include?('reduce') ||
124
- method_name.include?('sum')
138
+
139
+ def handle_api_evolution_in_workspace(workspace_path, error, class_name, method_name)
140
+ puts "๐ŸŒ Using OpenAI API for evolution in workspace..."
141
+
142
+ # Load business context for API evolution
143
+ business_context = CodeHealer::BusinessContextManager.get_context_for_error(
144
+ error, class_name, method_name
145
+ )
146
+
147
+ puts "๐Ÿ“‹ Business context loaded for API evolution"
148
+
149
+ # Change to workspace directory for API operations
150
+ Dir.chdir(workspace_path) do
151
+ success = CodeHealer::SimpleEvolution.handle_error_with_mcp_intelligence(
152
+ error, class_name, method_name, nil, business_context # file_path not needed in workspace
125
153
  )
126
- containing_line = backtrace.find do |line|
127
- line.include?('/app/') &&
128
- line =~ /in `(.+)'/ &&
129
- !$1.include?('block in') &&
130
- !$1.include?('each') &&
131
- !$1.include?('map') &&
132
- !$1.include?('reduce') &&
133
- !$1.include?('sum')
134
- end
135
-
136
- if containing_line && containing_line =~ /(.+):(\d+):in `(.+)'/
137
- file_path = $1
138
- method_name = $3
139
- end
154
+
155
+ if success
156
+ puts "โœ… API evolution completed successfully in workspace!"
157
+ true
158
+ else
159
+ puts "โŒ API evolution failed in workspace"
160
+ false
140
161
  end
141
-
142
- return file_path if file_path
143
162
  end
144
-
145
- nil
146
163
  end
147
-
148
- def reconstruct_error(error_type, error_message, backtrace = nil)
149
- # Create a simple error object with the type and message
150
- error_class = error_type.constantize rescue StandardError
151
- error = error_class.new(error_message)
152
-
153
- # Set the backtrace if provided
154
- if backtrace
155
- error.set_backtrace(backtrace)
156
- puts "๐Ÿ“‹ Backtrace restored: #{backtrace.length} lines"
157
- else
158
- puts "โš ๏ธ No backtrace provided"
164
+
165
+ def cleanup_workspace(workspace_path)
166
+ return unless workspace_path && Dir.exist?(workspace_path)
167
+
168
+ puts "๐Ÿงน Cleaning up healing workspace: #{workspace_path}"
169
+ CodeHealer::HealingWorkspaceManager.cleanup_workspace(workspace_path)
170
+ end
171
+
172
+ def reconstruct_error(error_data)
173
+ # Reconstruct the error object from serialized data
174
+ error_class = Object.const_get(error_data['class'])
175
+ error = error_class.new(error_data['message'])
176
+
177
+ # Restore backtrace if available
178
+ if error_data['backtrace']
179
+ error.set_backtrace(error_data['backtrace'])
159
180
  end
160
-
181
+
161
182
  error
162
- rescue
163
- # Fallback to generic error
164
- StandardError.new(error_message)
165
183
  end
166
184
  end
167
185
  end
186
+
187
+ # This duplicate class has been removed to fix the isolated healing workspace system