code_healer 0.1.12 → 0.1.15

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.
@@ -0,0 +1,408 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>CodeHealer Dashboard</title>
7
+ <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
8
+ <style>
9
+ * {
10
+ margin: 0;
11
+ padding: 0;
12
+ box-sizing: border-box;
13
+ }
14
+
15
+ body {
16
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
17
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
18
+ min-height: 100vh;
19
+ color: #333;
20
+ }
21
+
22
+ .dashboard-container {
23
+ max-width: 1400px;
24
+ margin: 0 auto;
25
+ padding: 20px;
26
+ }
27
+
28
+ .dashboard-header {
29
+ text-align: center;
30
+ margin-bottom: 40px;
31
+ color: white;
32
+ }
33
+
34
+ .dashboard-header h1 {
35
+ font-size: 3rem;
36
+ font-weight: 700;
37
+ margin-bottom: 10px;
38
+ text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
39
+ }
40
+
41
+ .dashboard-header p {
42
+ font-size: 1.2rem;
43
+ opacity: 0.9;
44
+ }
45
+
46
+ .metrics-grid {
47
+ display: grid;
48
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
49
+ gap: 20px;
50
+ margin-bottom: 40px;
51
+ }
52
+
53
+ .metric-card {
54
+ background: white;
55
+ border-radius: 16px;
56
+ padding: 24px;
57
+ box-shadow: 0 10px 30px rgba(0,0,0,0.1);
58
+ transition: transform 0.3s ease, box-shadow 0.3s ease;
59
+ border: 1px solid rgba(255,255,255,0.2);
60
+ }
61
+
62
+ .metric-card:hover {
63
+ transform: translateY(-5px);
64
+ box-shadow: 0 20px 40px rgba(0,0,0,0.15);
65
+ }
66
+
67
+ .metric-value {
68
+ font-size: 2.5rem;
69
+ font-weight: 700;
70
+ color: #667eea;
71
+ margin-bottom: 8px;
72
+ }
73
+
74
+ .metric-label {
75
+ font-size: 0.9rem;
76
+ color: #666;
77
+ text-transform: uppercase;
78
+ letter-spacing: 0.5px;
79
+ font-weight: 500;
80
+ }
81
+
82
+ .metric-trend {
83
+ font-size: 0.8rem;
84
+ color: #28a745;
85
+ margin-top: 8px;
86
+ }
87
+
88
+ .charts-section {
89
+ display: grid;
90
+ grid-template-columns: 1fr 1fr;
91
+ gap: 30px;
92
+ margin-bottom: 40px;
93
+ }
94
+
95
+ .chart-container {
96
+ background: white;
97
+ border-radius: 16px;
98
+ padding: 24px;
99
+ box-shadow: 0 10px 30px rgba(0,0,0,0.1);
100
+ }
101
+
102
+ .chart-title {
103
+ font-size: 1.2rem;
104
+ font-weight: 600;
105
+ margin-bottom: 20px;
106
+ color: #333;
107
+ text-align: center;
108
+ }
109
+
110
+ .recent-healings {
111
+ background: white;
112
+ border-radius: 16px;
113
+ padding: 24px;
114
+ box-shadow: 0 10px 30px rgba(0,0,0,0.1);
115
+ }
116
+
117
+ .section-title {
118
+ font-size: 1.5rem;
119
+ font-weight: 600;
120
+ margin-bottom: 20px;
121
+ color: #333;
122
+ text-align: center;
123
+ }
124
+
125
+ .healing-item {
126
+ display: flex;
127
+ justify-content: space-between;
128
+ align-items: center;
129
+ padding: 16px;
130
+ border-bottom: 1px solid #eee;
131
+ transition: background-color 0.2s ease;
132
+ }
133
+
134
+ .healing-item:hover {
135
+ background-color: #f8f9fa;
136
+ }
137
+
138
+ .healing-item:last-child {
139
+ border-bottom: none;
140
+ }
141
+
142
+ .healing-info h4 {
143
+ font-size: 1rem;
144
+ font-weight: 600;
145
+ color: #333;
146
+ margin-bottom: 4px;
147
+ }
148
+
149
+ .healing-info p {
150
+ font-size: 0.9rem;
151
+ color: #666;
152
+ margin: 0;
153
+ }
154
+
155
+ .healing-status {
156
+ padding: 6px 12px;
157
+ border-radius: 20px;
158
+ font-size: 0.8rem;
159
+ font-weight: 500;
160
+ text-transform: uppercase;
161
+ }
162
+
163
+ .status-success {
164
+ background-color: #d4edda;
165
+ color: #155724;
166
+ }
167
+
168
+ .status-failed {
169
+ background-color: #f8d7da;
170
+ color: #721c24;
171
+ }
172
+
173
+ .status-pending {
174
+ background-color: #fff3cd;
175
+ color: #856404;
176
+ }
177
+
178
+ .view-details-btn {
179
+ background: #667eea;
180
+ color: white;
181
+ padding: 8px 16px;
182
+ border-radius: 20px;
183
+ text-decoration: none;
184
+ font-size: 0.8rem;
185
+ font-weight: 500;
186
+ transition: background-color 0.2s ease;
187
+ }
188
+
189
+ .view-details-btn:hover {
190
+ background: #5a6fd8;
191
+ }
192
+
193
+ @media (max-width: 768px) {
194
+ .charts-section {
195
+ grid-template-columns: 1fr;
196
+ }
197
+
198
+ .dashboard-header h1 {
199
+ font-size: 2rem;
200
+ }
201
+
202
+ .metric-value {
203
+ font-size: 2rem;
204
+ }
205
+ }
206
+
207
+ .loading {
208
+ text-align: center;
209
+ padding: 40px;
210
+ color: #666;
211
+ }
212
+
213
+ .error {
214
+ background: #f8d7da;
215
+ color: #721c24;
216
+ padding: 16px;
217
+ border-radius: 8px;
218
+ margin: 20px 0;
219
+ text-align: center;
220
+ }
221
+ </style>
222
+ </head>
223
+ <body>
224
+ <div class="dashboard-container">
225
+ <div class="dashboard-header">
226
+ <h1>🏥 CodeHealer Dashboard</h1>
227
+ <p>AI-Powered Code Healing & Self-Repair Analytics</p>
228
+ </div>
229
+
230
+ <div class="metrics-grid">
231
+ <div class="metric-card">
232
+ <div class="metric-value" id="total-healings">-</div>
233
+ <div class="metric-label">Total Healings</div>
234
+ <div class="metric-trend">📈 All time</div>
235
+ </div>
236
+
237
+ <div class="metric-card">
238
+ <div class="metric-value" id="success-rate">-</div>
239
+ <div class="metric-label">Success Rate</div>
240
+ <div class="metric-trend">🎯 Performance</div>
241
+ </div>
242
+
243
+ <div class="metric-card">
244
+ <div class="metric-value" id="healings-today">-</div>
245
+ <div class="metric-label">Healings Today</div>
246
+ <div class="metric-trend">📅 Daily</div>
247
+ </div>
248
+
249
+ <div class="metric-card">
250
+ <div class="metric-value" id="avg-resolution">-</div>
251
+ <div class="metric-label">Avg Resolution Time</div>
252
+ <div class="metric-trend">⚡ Speed</div>
253
+ </div>
254
+ </div>
255
+
256
+ <div class="charts-section">
257
+ <div class="chart-container">
258
+ <div class="chart-title">Daily Healing Trend (Last 7 Days)</div>
259
+ <canvas id="dailyTrendChart" width="400" height="200"></canvas>
260
+ </div>
261
+
262
+ <div class="chart-container">
263
+ <div class="chart-title">Evolution Methods Distribution</div>
264
+ <canvas id="evolutionMethodsChart" width="400" height="200"></canvas>
265
+ </div>
266
+ </div>
267
+
268
+ <div class="recent-healings">
269
+ <div class="section-title">Recent Healing Operations</div>
270
+ <div id="recent-healings-list">
271
+ <div class="loading">Loading recent healings...</div>
272
+ </div>
273
+ </div>
274
+ </div>
275
+
276
+ <script>
277
+ // Dashboard data loading
278
+ async function loadDashboardData() {
279
+ try {
280
+ const response = await fetch('/code_healer/api/dashboard/summary');
281
+ const data = await response.json();
282
+
283
+ if (response.ok) {
284
+ updateMetrics(data);
285
+ updateCharts(data);
286
+ loadRecentHealings();
287
+ } else {
288
+ throw new Error('Failed to load dashboard data');
289
+ }
290
+ } catch (error) {
291
+ console.error('Error loading dashboard data:', error);
292
+ document.querySelector('.metrics-grid').innerHTML =
293
+ '<div class="error">Failed to load dashboard data. Please try again later.</div>';
294
+ }
295
+ }
296
+
297
+ function updateMetrics(data) {
298
+ document.getElementById('total-healings').textContent = data.total_healings || 0;
299
+ document.getElementById('success-rate').textContent = `${data.success_rate || 0}%`;
300
+ document.getElementById('healings-today').textContent = data.healings_today || 0;
301
+ document.getElementById('avg-resolution').textContent = `${data.average_resolution_time || 0}ms`;
302
+ }
303
+
304
+ function updateCharts(data) {
305
+ // Daily Trend Chart
306
+ const dailyCtx = document.getElementById('dailyTrendChart').getContext('2d');
307
+ new Chart(dailyCtx, {
308
+ type: 'line',
309
+ data: {
310
+ labels: Object.keys(data.daily_trend || {}),
311
+ datasets: [{
312
+ label: 'Healings',
313
+ data: Object.values(data.daily_trend || {}),
314
+ borderColor: '#667eea',
315
+ backgroundColor: 'rgba(102, 126, 234, 0.1)',
316
+ tension: 0.4,
317
+ fill: true
318
+ }]
319
+ },
320
+ options: {
321
+ responsive: true,
322
+ plugins: {
323
+ legend: {
324
+ display: false
325
+ }
326
+ },
327
+ scales: {
328
+ y: {
329
+ beginAtZero: true,
330
+ ticks: {
331
+ stepSize: 1
332
+ }
333
+ }
334
+ }
335
+ }
336
+ });
337
+
338
+ // Evolution Methods Chart
339
+ const evolutionCtx = document.getElementById('evolutionMethodsChart').getContext('2d');
340
+ new Chart(evolutionCtx, {
341
+ type: 'doughnut',
342
+ data: {
343
+ labels: Object.keys(data.evolution_methods || {}),
344
+ datasets: [{
345
+ data: Object.values(data.evolution_methods || {}),
346
+ backgroundColor: [
347
+ '#667eea',
348
+ '#764ba2',
349
+ '#f093fb',
350
+ '#f5576c',
351
+ '#4facfe',
352
+ '#00f2fe'
353
+ ]
354
+ }]
355
+ },
356
+ options: {
357
+ responsive: true,
358
+ plugins: {
359
+ legend: {
360
+ position: 'bottom'
361
+ }
362
+ }
363
+ }
364
+ });
365
+ }
366
+
367
+ async function loadRecentHealings() {
368
+ try {
369
+ const response = await fetch('/code_healer/api/dashboard/metrics?limit=5');
370
+ const healings = await response.json();
371
+
372
+ const container = document.getElementById('recent-healings-list');
373
+ if (healings && healings.length > 0) {
374
+ container.innerHTML = healings.map(healing => `
375
+ <div class="healing-item">
376
+ <div class="healing-info">
377
+ <h4>${healing.class_name}#${healing.method_name}</h4>
378
+ <p>${healing.error_class}: ${healing.error_message}</p>
379
+ <small>${new Date(healing.created_at).toLocaleString()}</small>
380
+ </div>
381
+ <div style="display: flex; align-items: center; gap: 12px;">
382
+ <div class="healing-status status-${healing.healing_successful ? 'success' : 'failed'}">
383
+ ${healing.healing_successful ? '✅ Success' : '❌ Failed'}
384
+ </div>
385
+ <a href="/code_healer/dashboard/healing/${healing.healing_id}" class="view-details-btn">
386
+ View Details
387
+ </a>
388
+ </div>
389
+ </div>
390
+ `).join('');
391
+ } else {
392
+ container.innerHTML = '<div class="loading">No healing operations found yet.</div>';
393
+ }
394
+ } catch (error) {
395
+ console.error('Error loading recent healings:', error);
396
+ document.getElementById('recent-healings-list').innerHTML =
397
+ '<div class="error">Failed to load recent healings.</div>';
398
+ }
399
+ }
400
+
401
+ // Initialize dashboard
402
+ document.addEventListener('DOMContentLoaded', loadDashboardData);
403
+
404
+ // Auto-refresh every 30 seconds
405
+ setInterval(loadDashboardData, 30000);
406
+ </script>
407
+ </body>
408
+ </html>
data/lib/code_healer.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "code_healer/version"
4
+ require_relative "code_healer/engine"
4
5
 
5
6
  # Require external gems explicitly
6
7
  require 'openai'
@@ -28,6 +29,12 @@ autoload :McpTools, "code_healer/mcp_tools"
28
29
  autoload :McpPrompts, "code_healer/mcp_prompts"
29
30
  autoload :MCP, "code_healer/mcp"
30
31
 
32
+ # Dashboard components - load them explicitly to avoid autoload issues
33
+ require_relative "code_healer/models/healing_metric"
34
+ require_relative "code_healer/services/metrics_collector"
35
+ require_relative "code_healer/controllers/dashboard_controller"
36
+ autoload :Installer, "code_healer/installer"
37
+
31
38
  # Rails integration
32
39
  if defined?(Rails)
33
40
  require "rails"
@@ -64,5 +71,12 @@ if defined?(Rails)
64
71
  puts " Run 'code_healer-setup' to configure CodeHealer"
65
72
  end
66
73
  end
74
+
75
+ # Mount the engine to provide dashboard routes and views
76
+ initializer "code_healer.mount_engine" do |app|
77
+ app.routes.prepend do
78
+ mount CodeHealer::Engine => "/code_healer"
79
+ end
80
+ end
67
81
  end
68
82
  end
@@ -0,0 +1,48 @@
1
+ module CodeHealer
2
+ module Generators
3
+ class InstallGenerator < Rails::Generators::Base
4
+ source_root File.expand_path('templates', __dir__)
5
+
6
+ desc "Installs CodeHealer dashboard and required components"
7
+
8
+ def install_dashboard
9
+ # Generate migration
10
+ generate_migration
11
+
12
+ # Add routes
13
+ inject_routes
14
+
15
+ # Create initializer
16
+ create_initializer
17
+
18
+ # Copy dashboard assets
19
+ copy_dashboard_assets
20
+
21
+ puts "✅ CodeHealer dashboard installed successfully!"
22
+ puts "🚀 Run 'rails db:migrate' to create the database tables"
23
+ puts "🌐 Access your dashboard at: /code_healer/dashboard"
24
+ end
25
+
26
+ private
27
+
28
+ def generate_migration
29
+ migration_template "create_healing_metrics.rb", "db/migrate/create_healing_metrics.rb"
30
+ end
31
+
32
+ def inject_routes
33
+ route "mount CodeHealer::Engine => '/code_healer'"
34
+ end
35
+
36
+ def create_initializer
37
+ copy_file "code_healer.rb", "config/initializers/code_healer.rb"
38
+ end
39
+
40
+ def copy_dashboard_assets
41
+ copy_file "dashboard_controller.rb", "app/controllers/code_healer/dashboard_controller.rb"
42
+ copy_file "healing_metric.rb", "app/models/code_healer/healing_metric.rb"
43
+ copy_file "metrics_collector.rb", "app/services/code_healer/metrics_collector.rb"
44
+ copy_file "dashboard_index.html.erb", "app/views/code_healer/dashboard/index.html.erb"
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,56 @@
1
+ class CreateHealingMetrics < ActiveRecord::Migration[<%= ActiveRecord::Migration.current_version %>]
2
+ def change
3
+ create_table :healing_metrics do |t|
4
+ # Basic healing info
5
+ t.string :healing_id, null: false, index: true
6
+ t.string :class_name, null: false
7
+ t.string :method_name, null: false
8
+ t.string :error_class, null: false
9
+ t.text :error_message
10
+ t.string :file_path
11
+
12
+ # AI and evolution details
13
+ t.string :evolution_method # claude_code_terminal, api, hybrid
14
+ t.string :ai_provider # claude, openai
15
+ t.boolean :ai_success, default: false
16
+ t.text :ai_response
17
+ t.integer :ai_tokens_used
18
+ t.decimal :ai_cost, precision: 10, scale: 4
19
+
20
+ # Workspace and Git details
21
+ t.string :workspace_path
22
+ t.string :healing_branch
23
+ t.string :pull_request_url
24
+ t.boolean :pr_created, default: false
25
+
26
+ # Timing and performance
27
+ t.datetime :error_occurred_at
28
+ t.datetime :healing_started_at
29
+ t.datetime :healing_completed_at
30
+ t.integer :total_duration_ms
31
+ t.integer :ai_processing_time_ms
32
+ t.integer :git_operations_time_ms
33
+
34
+ # Success metrics
35
+ t.boolean :healing_successful, default: false
36
+ t.boolean :tests_passed, default: false
37
+ t.boolean :syntax_valid, default: false
38
+ t.text :failure_reason
39
+
40
+ # Business context
41
+ t.text :business_context_used
42
+ t.string :jira_issue_id
43
+ t.string :confluence_page_id
44
+
45
+ # Metadata
46
+ t.json :additional_metadata
47
+ t.timestamps
48
+ end
49
+
50
+ # Indexes for performance
51
+ add_index :healing_metrics, [:class_name, :method_name]
52
+ add_index :healing_metrics, [:evolution_method, :ai_provider]
53
+ add_index :healing_metrics, [:healing_successful, :created_at]
54
+ add_index :healing_metrics, :created_at
55
+ end
56
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: code_healer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.12
4
+ version: 0.1.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Deepan Kumar
@@ -345,10 +345,12 @@ extensions: []
345
345
  extra_rdoc_files: []
346
346
  files:
347
347
  - CHANGELOG.md
348
+ - DASHBOARD_README.md
348
349
  - GEM_SUMMARY.md
349
350
  - README.md
350
351
  - code_healer.gemspec
351
352
  - config/code_healer.yml.example
353
+ - config/routes.rb
352
354
  - docs/INSTALLATION.md
353
355
  - examples/basic_usage.rb
354
356
  - exe/code_healer-setup
@@ -363,17 +365,23 @@ files:
363
365
  - lib/code_healer/claude_error_monitor.rb
364
366
  - lib/code_healer/config_manager.rb
365
367
  - lib/code_healer/context_aware_prompt_builder.rb
368
+ - lib/code_healer/controllers/dashboard_controller.rb
366
369
  - lib/code_healer/core.rb
370
+ - lib/code_healer/engine.rb
367
371
  - lib/code_healer/error_handler.rb
368
372
  - lib/code_healer/evolution_job.rb
369
373
  - lib/code_healer/global_handler.rb
370
374
  - lib/code_healer/healing_job.rb
371
375
  - lib/code_healer/healing_workspace_manager.rb
376
+ - lib/code_healer/installer.rb
372
377
  - lib/code_healer/mcp.rb
373
378
  - lib/code_healer/mcp_prompts.rb
374
379
  - lib/code_healer/mcp_server.rb
375
380
  - lib/code_healer/mcp_tools.rb
381
+ - lib/code_healer/models/healing_metric.rb
376
382
  - lib/code_healer/pull_request_creator.rb
383
+ - lib/code_healer/routes.rb
384
+ - lib/code_healer/services/metrics_collector.rb
377
385
  - lib/code_healer/setup.rb
378
386
  - lib/code_healer/simple_evolution.rb
379
387
  - lib/code_healer/simple_global_handler.rb
@@ -381,6 +389,10 @@ files:
381
389
  - lib/code_healer/terminal_integration.rb
382
390
  - lib/code_healer/usage_analyzer.rb
383
391
  - lib/code_healer/version.rb
392
+ - lib/code_healer/views/dashboard/healing_details.html.erb
393
+ - lib/code_healer/views/dashboard/index.html.erb
394
+ - lib/generators/code_healer/install_generator.rb
395
+ - lib/generators/code_healer/templates/create_healing_metrics.rb
384
396
  homepage: https://github.com/deepan-g2/code-healer
385
397
  licenses:
386
398
  - MIT