code_healer 0.1.15 → 0.1.16

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: bc8423f76ddef06527d9b8e70a219d0e958ee89e3f352d6bd816697d7d7bb49d
4
+ data.tar.gz: c37a4b4101bcda99e166364629d6075c64244f4ef9d04e12b22dccbc5a176f61
5
5
  SHA512:
6
- metadata.gz: 98e5125e4f561073f31a8f263b5aba7b4ec62dba1d7a9c6b3dca818aa412c5f4578a55ff28dc95dd27768aa86dc61353050c43960ed29d8cc2499790bccef987
7
- data.tar.gz: 52611005c0b0e47e16e86fb6f0d62ff0aea6a338e42de0b725e5de7a1d77713f3e89494db821d5f06c350283bf6027d629c859a3515e8dcb7cdb0cda113823f7
6
+ metadata.gz: bea3163ae16b27e735c3aa21c89f2c7a4ffcaf7245c4eca00c39ea17896370ac5870116fa7d6f0499f8aa72fe3bf837d9d3164e4e27f175522dfc9998bc568ff
7
+ data.tar.gz: ecf0d683184721228fb6dc3e9d444bac88b2bc5aceb2488890af4356700b5442baf79f058eaee4169e103574eed690b905bc49e8acea4d6c1ea4be6cfc9d2268
data/CHANGELOG.md CHANGED
@@ -5,6 +5,20 @@ 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.16] - 2025-08-21
9
+
10
+ ### Added
11
+ - Processing state: dashboard shows in-flight healings as "processing" (no longer treated as failed)
12
+ - API metrics payload now includes `status` and timezone-aware `created_at`
13
+
14
+ ### Changed
15
+ - API endpoints default to JSON (`/code_healer/api/...`) to avoid template lookup
16
+ - Compact metrics JSON for dashboard list rendering
17
+
18
+ ### Fixed
19
+ - Timezone correctness: all metrics timestamps use `Time.zone`
20
+ - Daily trend counts computed with timezone-aware day buckets
21
+
8
22
  ## [0.1.15] - 2025-08-21
9
23
 
10
24
  ### 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'
@@ -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
@@ -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
@@ -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.16"
5
5
  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.16
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