code_healer 0.1.14 → 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.
@@ -1,161 +1,408 @@
1
1
  <!DOCTYPE html>
2
- <html>
2
+ <html lang="en">
3
3
  <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
4
6
  <title>CodeHealer Dashboard</title>
5
7
  <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
6
8
  <style>
7
- body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; margin: 0; padding: 20px; background: #f5f5f5; }
8
- .container { max-width: 1200px; margin: 0 auto; }
9
- .header { background: white; padding: 20px; border-radius: 8px; margin-bottom: 20px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
10
- .header h1 { margin: 0; color: #2c3e50; }
11
- .header p { margin: 10px 0 0 0; color: #7f8c8d; }
12
-
13
- .metrics-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 20px; margin-bottom: 20px; }
14
- .metric-card { background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
15
- .metric-card h3 { margin: 0 0 10px 0; color: #2c3e50; font-size: 14px; text-transform: uppercase; letter-spacing: 0.5px; }
16
- .metric-card .value { font-size: 32px; font-weight: bold; color: #3498db; margin: 0; }
17
- .metric-card .label { color: #7f8c8d; font-size: 12px; margin: 5px 0 0 0; }
18
-
19
- .charts-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-bottom: 20px; }
20
- .chart-card { background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
21
- .chart-card h3 { margin: 0 0 20px 0; color: #2c3e50; }
22
-
23
- .recent-healings { background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
24
- .recent-healings h3 { margin: 0 0 20px 0; color: #2c3e50; }
25
- .healing-item { padding: 15px; border-bottom: 1px solid #ecf0f1; }
26
- .healing-item:last-child { border-bottom: none; }
27
- .healing-item .class-method { font-weight: bold; color: #2c3e50; }
28
- .healing-item .error { color: #e74c3c; font-size: 14px; }
29
- .healing-item .status { color: #27ae60; font-size: 12px; }
30
- .healing-item .time { color: #7f8c8d; font-size: 12px; }
31
-
32
- .success { color: #27ae60; }
33
- .warning { color: #f39c12; }
34
- .danger { color: #e74c3c; }
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
+ }
35
221
  </style>
36
222
  </head>
37
223
  <body>
38
- <div class="container">
39
- <div class="header">
224
+ <div class="dashboard-container">
225
+ <div class="dashboard-header">
40
226
  <h1>🏥 CodeHealer Dashboard</h1>
41
- <p>Intelligent Code Healing Analytics & Insights</p>
227
+ <p>AI-Powered Code Healing & Self-Repair Analytics</p>
42
228
  </div>
43
-
229
+
44
230
  <div class="metrics-grid">
45
231
  <div class="metric-card">
46
- <h3>Total Healings</h3>
47
- <div class="value"><%= @summary[:total_healings] %></div>
48
- <div class="label">All time</div>
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>
49
235
  </div>
50
236
 
51
237
  <div class="metric-card">
52
- <h3>Success Rate</h3>
53
- <div class="value <%= @summary[:success_rate] >= 80 ? 'success' : (@summary[:success_rate] >= 60 ? 'warning' : 'danger') %>">
54
- <%= @summary[:success_rate] %>%
55
- </div>
56
- <div class="label">Healing success</div>
238
+ <div class="metric-value" id="success-rate">-</div>
239
+ <div class="metric-label">Success Rate</div>
240
+ <div class="metric-trend">🎯 Performance</div>
57
241
  </div>
58
242
 
59
243
  <div class="metric-card">
60
- <h3>Today</h3>
61
- <div class="value"><%= @summary[:healings_today] %></div>
62
- <div class="label">Healings today</div>
244
+ <div class="metric-value" id="healings-today">-</div>
245
+ <div class="metric-label">Healings Today</div>
246
+ <div class="metric-trend">📅 Daily</div>
63
247
  </div>
64
248
 
65
249
  <div class="metric-card">
66
- <h3>This Week</h3>
67
- <div class="value"><%= @summary[:healings_this_week] %></div>
68
- <div class="label">Healings this week</div>
69
- </div>
70
-
71
- <div class="metric-card">
72
- <h3>This Month</h3>
73
- <div class="value"><%= @summary[:healings_this_month] %></div>
74
- <div class="label">Healings this month</div>
75
- </div>
76
-
77
- <div class="metric-card">
78
- <h3>Avg Resolution</h3>
79
- <div class="value">
80
- <%= @summary[:average_resolution_time] ? "#{(@summary[:average_resolution_time] / 1000.0).round(2)}s" : "N/A" %>
81
- </div>
82
- <div class="label">Average time to fix</div>
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>
83
253
  </div>
84
254
  </div>
85
-
86
- <div class="charts-grid">
87
- <div class="chart-card">
88
- <h3>Daily Healing Trend (Last 7 Days)</h3>
89
- <canvas id="dailyTrendChart"></canvas>
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>
90
260
  </div>
91
261
 
92
- <div class="chart-card">
93
- <h3>Evolution Method Distribution</h3>
94
- <canvas id="evolutionMethodsChart"></canvas>
262
+ <div class="chart-container">
263
+ <div class="chart-title">Evolution Methods Distribution</div>
264
+ <canvas id="evolutionMethodsChart" width="400" height="200"></canvas>
95
265
  </div>
96
266
  </div>
97
-
267
+
98
268
  <div class="recent-healings">
99
- <h3>Recent Healings</h3>
100
- <% @recent_healings.each do |healing| %>
101
- <div class="healing-item">
102
- <div class="class-method"><%= healing.class_name %>#<%= healing.method_name %></div>
103
- <div class="error"><%= healing.error_class %>: <%= healing.error_message&.truncate(100) %></div>
104
- <div class="status">
105
- <%= healing.success_status %> |
106
- <%= healing.evolution_method_display %> |
107
- <%= healing.ai_provider_display %>
108
- </div>
109
- <div class="time"><%= healing.created_at.strftime("%Y-%m-%d %H:%M:%S") %></div>
110
- </div>
111
- <% end %>
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>
112
273
  </div>
113
274
  </div>
114
-
275
+
115
276
  <script>
116
- // Daily Trend Chart
117
- const dailyTrendCtx = document.getElementById('dailyTrendChart').getContext('2d');
118
- new Chart(dailyTrendCtx, {
119
- type: 'line',
120
- data: {
121
- labels: <%= raw @summary[:daily_trend].keys.map { |date| Date.parse(date).strftime("%m/%d") }.to_json %>,
122
- datasets: [{
123
- label: 'Healings',
124
- data: <%= raw @summary[:daily_trend].values.to_json %>,
125
- borderColor: '#3498db',
126
- backgroundColor: 'rgba(52, 152, 219, 0.1)',
127
- tension: 0.4
128
- }]
129
- },
130
- options: {
131
- responsive: true,
132
- plugins: {
133
- legend: { display: false }
134
- },
135
- scales: {
136
- y: { beginAtZero: true, ticks: { stepSize: 1 } }
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');
137
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>';
138
294
  }
139
- });
140
-
141
- // Evolution Methods Chart
142
- const evolutionMethodsCtx = document.getElementById('evolutionMethodsChart').getContext('2d');
143
- new Chart(evolutionMethodsCtx, {
144
- type: 'doughnut',
145
- data: {
146
- labels: <%= raw @summary[:evolution_methods].keys.map(&:titleize).to_json %>,
147
- datasets: [{
148
- data: <%= raw @summary[:evolution_methods].values.to_json %>,
149
- backgroundColor: ['#3498db', '#e74c3c', '#2ecc71', '#f39c12', '#9b59b6']
150
- }]
151
- },
152
- options: {
153
- responsive: true,
154
- plugins: {
155
- legend: { position: 'bottom' }
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>';
156
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>';
157
398
  }
158
- });
399
+ }
400
+
401
+ // Initialize dashboard
402
+ document.addEventListener('DOMContentLoaded', loadDashboardData);
403
+
404
+ // Auto-refresh every 30 seconds
405
+ setInterval(loadDashboardData, 30000);
159
406
  </script>
160
407
  </body>
161
408
  </html>
data/lib/code_healer.rb CHANGED
@@ -72,33 +72,11 @@ if defined?(Rails)
72
72
  end
73
73
  end
74
74
 
75
- # Mount the engine to provide dashboard routes
75
+ # Mount the engine to provide dashboard routes and views
76
76
  initializer "code_healer.mount_engine" do |app|
77
77
  app.routes.prepend do
78
78
  mount CodeHealer::Engine => "/code_healer"
79
79
  end
80
80
  end
81
-
82
- # Add dashboard routes directly to the host app
83
- initializer "code_healer.add_dashboard_routes" do |app|
84
- app.routes.prepend do
85
- namespace :code_healer do
86
- get '/dashboard', to: 'dashboard#index'
87
- get '/dashboard/metrics', to: 'dashboard#metrics'
88
- get '/dashboard/trends', to: 'dashboard#trends'
89
- get '/dashboard/performance', to: 'dashboard#performance'
90
- get '/dashboard/healing/:healing_id', to: 'dashboard#healing_details'
91
-
92
- # API endpoints (JSON only)
93
- namespace :api do
94
- get '/dashboard/summary', to: 'dashboard#summary'
95
- get '/dashboard/metrics', to: 'dashboard#metrics'
96
- get '/dashboard/trends', to: 'dashboard#trends'
97
- get '/dashboard/performance', to: 'dashboard#performance'
98
- get '/dashboard/healing/:healing_id', to: 'dashboard#healing_details'
99
- end
100
- end
101
- end
102
- end
103
81
  end
104
82
  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.14
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
@@ -350,6 +350,7 @@ files:
350
350
  - README.md
351
351
  - code_healer.gemspec
352
352
  - config/code_healer.yml.example
353
+ - config/routes.rb
353
354
  - docs/INSTALLATION.md
354
355
  - examples/basic_usage.rb
355
356
  - exe/code_healer-setup
@@ -388,6 +389,7 @@ files:
388
389
  - lib/code_healer/terminal_integration.rb
389
390
  - lib/code_healer/usage_analyzer.rb
390
391
  - lib/code_healer/version.rb
392
+ - lib/code_healer/views/dashboard/healing_details.html.erb
391
393
  - lib/code_healer/views/dashboard/index.html.erb
392
394
  - lib/generators/code_healer/install_generator.rb
393
395
  - lib/generators/code_healer/templates/create_healing_metrics.rb