claude-mpm 4.1.4__py3-none-any.whl → 4.1.6__py3-none-any.whl
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.
- claude_mpm/VERSION +1 -1
- claude_mpm/agents/templates/research.json +39 -13
- claude_mpm/cli/__init__.py +2 -0
- claude_mpm/cli/commands/__init__.py +2 -0
- claude_mpm/cli/commands/configure.py +1221 -0
- claude_mpm/cli/commands/configure_tui.py +1921 -0
- claude_mpm/cli/commands/tickets.py +365 -784
- claude_mpm/cli/parsers/base_parser.py +7 -0
- claude_mpm/cli/parsers/configure_parser.py +119 -0
- claude_mpm/cli/startup_logging.py +39 -12
- claude_mpm/constants.py +1 -0
- claude_mpm/core/output_style_manager.py +24 -0
- claude_mpm/core/socketio_pool.py +35 -3
- claude_mpm/core/unified_agent_registry.py +46 -15
- claude_mpm/dashboard/static/css/connection-status.css +370 -0
- claude_mpm/dashboard/static/js/components/connection-debug.js +654 -0
- claude_mpm/dashboard/static/js/connection-manager.js +536 -0
- claude_mpm/dashboard/templates/index.html +11 -0
- claude_mpm/hooks/claude_hooks/services/__init__.py +3 -1
- claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +190 -0
- claude_mpm/services/agents/deployment/agent_discovery_service.py +12 -3
- claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +172 -233
- claude_mpm/services/agents/deployment/agent_lifecycle_manager_refactored.py +575 -0
- claude_mpm/services/agents/deployment/agent_operation_service.py +573 -0
- claude_mpm/services/agents/deployment/agent_record_service.py +419 -0
- claude_mpm/services/agents/deployment/agent_state_service.py +381 -0
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +4 -2
- claude_mpm/services/diagnostics/checks/__init__.py +2 -0
- claude_mpm/services/diagnostics/checks/instructions_check.py +418 -0
- claude_mpm/services/diagnostics/diagnostic_runner.py +15 -2
- claude_mpm/services/event_bus/direct_relay.py +173 -0
- claude_mpm/services/infrastructure/__init__.py +31 -5
- claude_mpm/services/infrastructure/monitoring/__init__.py +43 -0
- claude_mpm/services/infrastructure/monitoring/aggregator.py +437 -0
- claude_mpm/services/infrastructure/monitoring/base.py +130 -0
- claude_mpm/services/infrastructure/monitoring/legacy.py +203 -0
- claude_mpm/services/infrastructure/monitoring/network.py +218 -0
- claude_mpm/services/infrastructure/monitoring/process.py +342 -0
- claude_mpm/services/infrastructure/monitoring/resources.py +243 -0
- claude_mpm/services/infrastructure/monitoring/service.py +367 -0
- claude_mpm/services/infrastructure/monitoring.py +67 -1030
- claude_mpm/services/project/analyzer.py +13 -4
- claude_mpm/services/project/analyzer_refactored.py +450 -0
- claude_mpm/services/project/analyzer_v2.py +566 -0
- claude_mpm/services/project/architecture_analyzer.py +461 -0
- claude_mpm/services/project/dependency_analyzer.py +462 -0
- claude_mpm/services/project/language_analyzer.py +265 -0
- claude_mpm/services/project/metrics_collector.py +410 -0
- claude_mpm/services/socketio/handlers/connection_handler.py +345 -0
- claude_mpm/services/socketio/server/broadcaster.py +32 -1
- claude_mpm/services/socketio/server/connection_manager.py +516 -0
- claude_mpm/services/socketio/server/core.py +63 -0
- claude_mpm/services/socketio/server/eventbus_integration.py +20 -9
- claude_mpm/services/socketio/server/main.py +27 -1
- claude_mpm/services/ticket_manager.py +5 -1
- claude_mpm/services/ticket_services/__init__.py +26 -0
- claude_mpm/services/ticket_services/crud_service.py +328 -0
- claude_mpm/services/ticket_services/formatter_service.py +290 -0
- claude_mpm/services/ticket_services/search_service.py +324 -0
- claude_mpm/services/ticket_services/validation_service.py +303 -0
- claude_mpm/services/ticket_services/workflow_service.py +244 -0
- {claude_mpm-4.1.4.dist-info → claude_mpm-4.1.6.dist-info}/METADATA +3 -1
- {claude_mpm-4.1.4.dist-info → claude_mpm-4.1.6.dist-info}/RECORD +67 -46
- claude_mpm/agents/OUTPUT_STYLE.md +0 -73
- claude_mpm/agents/backups/INSTRUCTIONS.md +0 -352
- claude_mpm/agents/templates/OPTIMIZATION_REPORT.md +0 -156
- claude_mpm/agents/templates/backup/data_engineer_agent_20250726_234551.json +0 -79
- claude_mpm/agents/templates/backup/documentation_agent_20250726_234551.json +0 -68
- claude_mpm/agents/templates/backup/engineer_agent_20250726_234551.json +0 -77
- claude_mpm/agents/templates/backup/ops_agent_20250726_234551.json +0 -78
- claude_mpm/agents/templates/backup/qa_agent_20250726_234551.json +0 -67
- claude_mpm/agents/templates/backup/research_agent_2025011_234551.json +0 -88
- claude_mpm/agents/templates/backup/research_agent_20250726_234551.json +0 -72
- claude_mpm/agents/templates/backup/research_memory_efficient.json +0 -88
- claude_mpm/agents/templates/backup/security_agent_20250726_234551.json +0 -78
- claude_mpm/agents/templates/backup/version_control_agent_20250726_234551.json +0 -62
- claude_mpm/agents/templates/vercel_ops_instructions.md +0 -582
- {claude_mpm-4.1.4.dist-info → claude_mpm-4.1.6.dist-info}/WHEEL +0 -0
- {claude_mpm-4.1.4.dist-info → claude_mpm-4.1.6.dist-info}/entry_points.txt +0 -0
- {claude_mpm-4.1.4.dist-info → claude_mpm-4.1.6.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-4.1.4.dist-info → claude_mpm-4.1.6.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,654 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Connection Debug Panel
|
|
3
|
+
*
|
|
4
|
+
* Provides detailed connection metrics and debugging tools
|
|
5
|
+
* for troubleshooting connection issues.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
class ConnectionDebugPanel {
|
|
9
|
+
constructor(connectionManager) {
|
|
10
|
+
this.connectionManager = connectionManager;
|
|
11
|
+
this.isVisible = false;
|
|
12
|
+
this.updateInterval = null;
|
|
13
|
+
|
|
14
|
+
this.init();
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
init() {
|
|
18
|
+
// Create debug panel HTML
|
|
19
|
+
this.createPanel();
|
|
20
|
+
|
|
21
|
+
// Setup event listeners
|
|
22
|
+
this.setupEventListeners();
|
|
23
|
+
|
|
24
|
+
// Start metric updates when visible
|
|
25
|
+
this.connectionManager.onStatusChange(() => {
|
|
26
|
+
if (this.isVisible) {
|
|
27
|
+
this.updateMetrics();
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
createPanel() {
|
|
33
|
+
const panel = document.createElement('div');
|
|
34
|
+
panel.id = 'connection-debug-panel';
|
|
35
|
+
panel.className = 'connection-debug-panel';
|
|
36
|
+
panel.style.display = 'none';
|
|
37
|
+
|
|
38
|
+
panel.innerHTML = `
|
|
39
|
+
<div class="debug-panel-header">
|
|
40
|
+
<h3>🔧 Connection Debug</h3>
|
|
41
|
+
<button id="close-debug-panel" class="btn-close">✕</button>
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
<div class="debug-panel-content">
|
|
45
|
+
<!-- Connection Info -->
|
|
46
|
+
<div class="debug-section">
|
|
47
|
+
<h4>Connection Info</h4>
|
|
48
|
+
<div class="debug-info">
|
|
49
|
+
<div class="info-row">
|
|
50
|
+
<span class="info-label">Client ID:</span>
|
|
51
|
+
<span id="debug-client-id" class="info-value">--</span>
|
|
52
|
+
</div>
|
|
53
|
+
<div class="info-row">
|
|
54
|
+
<span class="info-label">Socket ID:</span>
|
|
55
|
+
<span id="debug-socket-id" class="info-value">--</span>
|
|
56
|
+
</div>
|
|
57
|
+
<div class="info-row">
|
|
58
|
+
<span class="info-label">State:</span>
|
|
59
|
+
<span id="debug-state" class="info-value">--</span>
|
|
60
|
+
</div>
|
|
61
|
+
<div class="info-row">
|
|
62
|
+
<span class="info-label">Quality:</span>
|
|
63
|
+
<span id="debug-quality" class="info-value">--</span>
|
|
64
|
+
</div>
|
|
65
|
+
<div class="info-row">
|
|
66
|
+
<span class="info-label">Last Sequence:</span>
|
|
67
|
+
<span id="debug-sequence" class="info-value">--</span>
|
|
68
|
+
</div>
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
|
|
72
|
+
<!-- Connection Metrics -->
|
|
73
|
+
<div class="debug-section">
|
|
74
|
+
<h4>Metrics</h4>
|
|
75
|
+
<div class="metrics-grid">
|
|
76
|
+
<div class="metric-item">
|
|
77
|
+
<span class="metric-value" id="debug-total-events">0</span>
|
|
78
|
+
<span class="metric-label">Total Events</span>
|
|
79
|
+
</div>
|
|
80
|
+
<div class="metric-item">
|
|
81
|
+
<span class="metric-value" id="debug-events-acked">0</span>
|
|
82
|
+
<span class="metric-label">Acknowledged</span>
|
|
83
|
+
</div>
|
|
84
|
+
<div class="metric-item">
|
|
85
|
+
<span class="metric-value" id="debug-buffered">0</span>
|
|
86
|
+
<span class="metric-label">Buffered</span>
|
|
87
|
+
</div>
|
|
88
|
+
<div class="metric-item">
|
|
89
|
+
<span class="metric-value" id="debug-reconnects">0</span>
|
|
90
|
+
<span class="metric-label">Reconnects</span>
|
|
91
|
+
</div>
|
|
92
|
+
</div>
|
|
93
|
+
</div>
|
|
94
|
+
|
|
95
|
+
<!-- Connection Timeline -->
|
|
96
|
+
<div class="debug-section">
|
|
97
|
+
<h4>Connection Timeline</h4>
|
|
98
|
+
<div id="debug-timeline" class="debug-timeline">
|
|
99
|
+
<!-- Timeline events will be added here -->
|
|
100
|
+
</div>
|
|
101
|
+
</div>
|
|
102
|
+
|
|
103
|
+
<!-- Debug Actions -->
|
|
104
|
+
<div class="debug-section">
|
|
105
|
+
<h4>Debug Actions</h4>
|
|
106
|
+
<div class="debug-actions">
|
|
107
|
+
<button id="debug-force-reconnect" class="btn-action">Force Reconnect</button>
|
|
108
|
+
<button id="debug-request-stats" class="btn-action">Request Stats</button>
|
|
109
|
+
<button id="debug-clear-buffer" class="btn-action">Clear Buffer</button>
|
|
110
|
+
<button id="debug-simulate-disconnect" class="btn-action">Simulate Disconnect</button>
|
|
111
|
+
<button id="debug-export-logs" class="btn-action">Export Logs</button>
|
|
112
|
+
</div>
|
|
113
|
+
</div>
|
|
114
|
+
|
|
115
|
+
<!-- Network Tests -->
|
|
116
|
+
<div class="debug-section">
|
|
117
|
+
<h4>Network Tests</h4>
|
|
118
|
+
<div class="network-tests">
|
|
119
|
+
<div class="test-row">
|
|
120
|
+
<button id="test-latency" class="btn-test">Test Latency</button>
|
|
121
|
+
<span id="latency-result" class="test-result">--</span>
|
|
122
|
+
</div>
|
|
123
|
+
<div class="test-row">
|
|
124
|
+
<button id="test-throughput" class="btn-test">Test Throughput</button>
|
|
125
|
+
<span id="throughput-result" class="test-result">--</span>
|
|
126
|
+
</div>
|
|
127
|
+
<div class="test-row">
|
|
128
|
+
<button id="test-stability" class="btn-test">Test Stability</button>
|
|
129
|
+
<span id="stability-result" class="test-result">--</span>
|
|
130
|
+
</div>
|
|
131
|
+
</div>
|
|
132
|
+
</div>
|
|
133
|
+
|
|
134
|
+
<!-- Event Log -->
|
|
135
|
+
<div class="debug-section">
|
|
136
|
+
<h4>Recent Events</h4>
|
|
137
|
+
<div id="debug-event-log" class="event-log">
|
|
138
|
+
<!-- Recent events will be shown here -->
|
|
139
|
+
</div>
|
|
140
|
+
</div>
|
|
141
|
+
</div>
|
|
142
|
+
`;
|
|
143
|
+
|
|
144
|
+
document.body.appendChild(panel);
|
|
145
|
+
|
|
146
|
+
// Add styles
|
|
147
|
+
this.addStyles();
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
addStyles() {
|
|
151
|
+
const style = document.createElement('style');
|
|
152
|
+
style.textContent = `
|
|
153
|
+
.connection-debug-panel {
|
|
154
|
+
position: fixed;
|
|
155
|
+
right: 20px;
|
|
156
|
+
top: 80px;
|
|
157
|
+
width: 400px;
|
|
158
|
+
max-height: 80vh;
|
|
159
|
+
background: white;
|
|
160
|
+
border-radius: 12px;
|
|
161
|
+
box-shadow: 0 8px 32px rgba(0,0,0,0.15);
|
|
162
|
+
z-index: 1001;
|
|
163
|
+
overflow: hidden;
|
|
164
|
+
display: flex;
|
|
165
|
+
flex-direction: column;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
.debug-panel-header {
|
|
169
|
+
display: flex;
|
|
170
|
+
justify-content: space-between;
|
|
171
|
+
align-items: center;
|
|
172
|
+
padding: 16px;
|
|
173
|
+
background: linear-gradient(135deg, #667eea 0%, #4299e1 100%);
|
|
174
|
+
color: white;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
.debug-panel-header h3 {
|
|
178
|
+
margin: 0;
|
|
179
|
+
font-size: 16px;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.btn-close {
|
|
183
|
+
background: rgba(255,255,255,0.2);
|
|
184
|
+
border: none;
|
|
185
|
+
color: white;
|
|
186
|
+
width: 28px;
|
|
187
|
+
height: 28px;
|
|
188
|
+
border-radius: 50%;
|
|
189
|
+
cursor: pointer;
|
|
190
|
+
font-size: 16px;
|
|
191
|
+
transition: background 0.2s;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
.btn-close:hover {
|
|
195
|
+
background: rgba(255,255,255,0.3);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
.debug-panel-content {
|
|
199
|
+
overflow-y: auto;
|
|
200
|
+
padding: 16px;
|
|
201
|
+
max-height: calc(80vh - 60px);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
.debug-section {
|
|
205
|
+
margin-bottom: 20px;
|
|
206
|
+
padding-bottom: 16px;
|
|
207
|
+
border-bottom: 1px solid #e2e8f0;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
.debug-section:last-child {
|
|
211
|
+
border-bottom: none;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
.debug-section h4 {
|
|
215
|
+
margin: 0 0 12px 0;
|
|
216
|
+
font-size: 14px;
|
|
217
|
+
color: #2d3748;
|
|
218
|
+
font-weight: 600;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
.debug-info {
|
|
222
|
+
background: #f7fafc;
|
|
223
|
+
padding: 12px;
|
|
224
|
+
border-radius: 8px;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
.info-row {
|
|
228
|
+
display: flex;
|
|
229
|
+
justify-content: space-between;
|
|
230
|
+
padding: 4px 0;
|
|
231
|
+
font-size: 13px;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
.info-label {
|
|
235
|
+
color: #718096;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
.info-value {
|
|
239
|
+
font-family: 'SF Mono', Monaco, monospace;
|
|
240
|
+
color: #2d3748;
|
|
241
|
+
font-weight: 500;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
.debug-actions {
|
|
245
|
+
display: grid;
|
|
246
|
+
grid-template-columns: repeat(2, 1fr);
|
|
247
|
+
gap: 8px;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
.btn-action {
|
|
251
|
+
padding: 8px 12px;
|
|
252
|
+
background: #4299e1;
|
|
253
|
+
color: white;
|
|
254
|
+
border: none;
|
|
255
|
+
border-radius: 6px;
|
|
256
|
+
font-size: 12px;
|
|
257
|
+
cursor: pointer;
|
|
258
|
+
transition: background 0.2s;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
.btn-action:hover {
|
|
262
|
+
background: #3182ce;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
.network-tests {
|
|
266
|
+
display: flex;
|
|
267
|
+
flex-direction: column;
|
|
268
|
+
gap: 8px;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
.test-row {
|
|
272
|
+
display: flex;
|
|
273
|
+
align-items: center;
|
|
274
|
+
gap: 12px;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
.btn-test {
|
|
278
|
+
flex: 0 0 120px;
|
|
279
|
+
padding: 6px 12px;
|
|
280
|
+
background: #805ad5;
|
|
281
|
+
color: white;
|
|
282
|
+
border: none;
|
|
283
|
+
border-radius: 6px;
|
|
284
|
+
font-size: 12px;
|
|
285
|
+
cursor: pointer;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
.test-result {
|
|
289
|
+
flex: 1;
|
|
290
|
+
padding: 6px 12px;
|
|
291
|
+
background: #f7fafc;
|
|
292
|
+
border-radius: 6px;
|
|
293
|
+
font-size: 12px;
|
|
294
|
+
font-family: 'SF Mono', Monaco, monospace;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
.debug-timeline {
|
|
298
|
+
max-height: 150px;
|
|
299
|
+
overflow-y: auto;
|
|
300
|
+
background: #f7fafc;
|
|
301
|
+
padding: 8px;
|
|
302
|
+
border-radius: 8px;
|
|
303
|
+
font-size: 12px;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
.timeline-event {
|
|
307
|
+
padding: 4px 0;
|
|
308
|
+
border-bottom: 1px solid #e2e8f0;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
.timeline-event:last-child {
|
|
312
|
+
border-bottom: none;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
.timeline-time {
|
|
316
|
+
color: #718096;
|
|
317
|
+
font-size: 11px;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
.timeline-desc {
|
|
321
|
+
color: #2d3748;
|
|
322
|
+
margin-top: 2px;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
.event-log {
|
|
326
|
+
max-height: 200px;
|
|
327
|
+
overflow-y: auto;
|
|
328
|
+
background: #1a202c;
|
|
329
|
+
color: #e2e8f0;
|
|
330
|
+
padding: 12px;
|
|
331
|
+
border-radius: 8px;
|
|
332
|
+
font-family: 'SF Mono', Monaco, monospace;
|
|
333
|
+
font-size: 11px;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
.log-entry {
|
|
337
|
+
padding: 2px 0;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
.log-time {
|
|
341
|
+
color: #718096;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
.log-type {
|
|
345
|
+
color: #4299e1;
|
|
346
|
+
font-weight: 600;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
.log-data {
|
|
350
|
+
color: #cbd5e0;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
@media (max-width: 768px) {
|
|
354
|
+
.connection-debug-panel {
|
|
355
|
+
right: 10px;
|
|
356
|
+
left: 10px;
|
|
357
|
+
width: auto;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
`;
|
|
361
|
+
|
|
362
|
+
document.head.appendChild(style);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
setupEventListeners() {
|
|
366
|
+
// Close button
|
|
367
|
+
document.getElementById('close-debug-panel').addEventListener('click', () => {
|
|
368
|
+
this.hide();
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
// Debug actions
|
|
372
|
+
document.getElementById('debug-force-reconnect').addEventListener('click', () => {
|
|
373
|
+
this.forceReconnect();
|
|
374
|
+
});
|
|
375
|
+
|
|
376
|
+
document.getElementById('debug-request-stats').addEventListener('click', () => {
|
|
377
|
+
this.requestStats();
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
document.getElementById('debug-clear-buffer').addEventListener('click', () => {
|
|
381
|
+
this.clearBuffer();
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
document.getElementById('debug-simulate-disconnect').addEventListener('click', () => {
|
|
385
|
+
this.simulateDisconnect();
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
document.getElementById('debug-export-logs').addEventListener('click', () => {
|
|
389
|
+
this.exportLogs();
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
// Network tests
|
|
393
|
+
document.getElementById('test-latency').addEventListener('click', () => {
|
|
394
|
+
this.testLatency();
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
document.getElementById('test-throughput').addEventListener('click', () => {
|
|
398
|
+
this.testThroughput();
|
|
399
|
+
});
|
|
400
|
+
|
|
401
|
+
document.getElementById('test-stability').addEventListener('click', () => {
|
|
402
|
+
this.testStability();
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
show() {
|
|
407
|
+
const panel = document.getElementById('connection-debug-panel');
|
|
408
|
+
panel.style.display = 'flex';
|
|
409
|
+
this.isVisible = true;
|
|
410
|
+
|
|
411
|
+
// Start metric updates
|
|
412
|
+
this.startMetricUpdates();
|
|
413
|
+
|
|
414
|
+
// Initial update
|
|
415
|
+
this.updateMetrics();
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
hide() {
|
|
419
|
+
const panel = document.getElementById('connection-debug-panel');
|
|
420
|
+
panel.style.display = 'none';
|
|
421
|
+
this.isVisible = false;
|
|
422
|
+
|
|
423
|
+
// Stop metric updates
|
|
424
|
+
this.stopMetricUpdates();
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
toggle() {
|
|
428
|
+
if (this.isVisible) {
|
|
429
|
+
this.hide();
|
|
430
|
+
} else {
|
|
431
|
+
this.show();
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
startMetricUpdates() {
|
|
436
|
+
this.updateInterval = setInterval(() => {
|
|
437
|
+
this.updateMetrics();
|
|
438
|
+
}, 1000);
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
stopMetricUpdates() {
|
|
442
|
+
if (this.updateInterval) {
|
|
443
|
+
clearInterval(this.updateInterval);
|
|
444
|
+
this.updateInterval = null;
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
updateMetrics() {
|
|
449
|
+
const metrics = this.connectionManager.getMetrics();
|
|
450
|
+
const socket = this.connectionManager.socket;
|
|
451
|
+
|
|
452
|
+
// Update connection info
|
|
453
|
+
document.getElementById('debug-client-id').textContent = metrics.clientId || '--';
|
|
454
|
+
document.getElementById('debug-socket-id').textContent = socket?.id || '--';
|
|
455
|
+
document.getElementById('debug-state').textContent = metrics.connectionState || '--';
|
|
456
|
+
document.getElementById('debug-quality').textContent =
|
|
457
|
+
`${Math.round(metrics.connectionQuality * 100)}%`;
|
|
458
|
+
document.getElementById('debug-sequence').textContent = metrics.lastSequence || '0';
|
|
459
|
+
|
|
460
|
+
// Update metrics
|
|
461
|
+
document.getElementById('debug-total-events').textContent = metrics.totalEvents || '0';
|
|
462
|
+
document.getElementById('debug-events-acked').textContent = metrics.eventsAcked || '0';
|
|
463
|
+
document.getElementById('debug-buffered').textContent = metrics.bufferedEvents || '0';
|
|
464
|
+
document.getElementById('debug-reconnects').textContent = metrics.totalReconnections || '0';
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
addTimelineEvent(description) {
|
|
468
|
+
const timeline = document.getElementById('debug-timeline');
|
|
469
|
+
const event = document.createElement('div');
|
|
470
|
+
event.className = 'timeline-event';
|
|
471
|
+
|
|
472
|
+
const now = new Date();
|
|
473
|
+
event.innerHTML = `
|
|
474
|
+
<div class="timeline-time">${now.toLocaleTimeString()}</div>
|
|
475
|
+
<div class="timeline-desc">${description}</div>
|
|
476
|
+
`;
|
|
477
|
+
|
|
478
|
+
timeline.insertBefore(event, timeline.firstChild);
|
|
479
|
+
|
|
480
|
+
// Keep only last 20 events
|
|
481
|
+
while (timeline.children.length > 20) {
|
|
482
|
+
timeline.removeChild(timeline.lastChild);
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
addLogEntry(type, data) {
|
|
487
|
+
const log = document.getElementById('debug-event-log');
|
|
488
|
+
const entry = document.createElement('div');
|
|
489
|
+
entry.className = 'log-entry';
|
|
490
|
+
|
|
491
|
+
const now = new Date();
|
|
492
|
+
entry.innerHTML = `
|
|
493
|
+
<span class="log-time">${now.toLocaleTimeString()}</span>
|
|
494
|
+
<span class="log-type">${type}</span>
|
|
495
|
+
<span class="log-data">${JSON.stringify(data)}</span>
|
|
496
|
+
`;
|
|
497
|
+
|
|
498
|
+
log.insertBefore(entry, log.firstChild);
|
|
499
|
+
|
|
500
|
+
// Keep only last 50 entries
|
|
501
|
+
while (log.children.length > 50) {
|
|
502
|
+
log.removeChild(log.lastChild);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
// Debug actions
|
|
507
|
+
forceReconnect() {
|
|
508
|
+
this.addTimelineEvent('Force reconnect initiated');
|
|
509
|
+
if (this.connectionManager.socket) {
|
|
510
|
+
this.connectionManager.socket.disconnect();
|
|
511
|
+
setTimeout(() => {
|
|
512
|
+
this.connectionManager.socket.connect();
|
|
513
|
+
}, 100);
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
requestStats() {
|
|
518
|
+
this.addTimelineEvent('Requesting connection stats');
|
|
519
|
+
if (this.connectionManager.socket) {
|
|
520
|
+
this.connectionManager.socket.emit('get_connection_stats');
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
clearBuffer() {
|
|
525
|
+
this.addTimelineEvent('Clearing event buffer');
|
|
526
|
+
this.connectionManager.eventBuffer = [];
|
|
527
|
+
localStorage.removeItem('claude_mpm_event_buffer');
|
|
528
|
+
this.updateMetrics();
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
simulateDisconnect() {
|
|
532
|
+
this.addTimelineEvent('Simulating disconnect');
|
|
533
|
+
if (this.connectionManager.socket) {
|
|
534
|
+
this.connectionManager.socket.disconnect();
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
exportLogs() {
|
|
539
|
+
const logs = {
|
|
540
|
+
metrics: this.connectionManager.getMetrics(),
|
|
541
|
+
timeline: [],
|
|
542
|
+
events: []
|
|
543
|
+
};
|
|
544
|
+
|
|
545
|
+
// Collect timeline events
|
|
546
|
+
const timeline = document.getElementById('debug-timeline');
|
|
547
|
+
Array.from(timeline.children).forEach(child => {
|
|
548
|
+
logs.timeline.push(child.textContent.trim());
|
|
549
|
+
});
|
|
550
|
+
|
|
551
|
+
// Collect event log
|
|
552
|
+
const eventLog = document.getElementById('debug-event-log');
|
|
553
|
+
Array.from(eventLog.children).forEach(child => {
|
|
554
|
+
logs.events.push(child.textContent.trim());
|
|
555
|
+
});
|
|
556
|
+
|
|
557
|
+
// Download as JSON
|
|
558
|
+
const blob = new Blob([JSON.stringify(logs, null, 2)], { type: 'application/json' });
|
|
559
|
+
const url = URL.createObjectURL(blob);
|
|
560
|
+
const a = document.createElement('a');
|
|
561
|
+
a.href = url;
|
|
562
|
+
a.download = `connection-debug-${Date.now()}.json`;
|
|
563
|
+
a.click();
|
|
564
|
+
URL.revokeObjectURL(url);
|
|
565
|
+
|
|
566
|
+
this.addTimelineEvent('Logs exported');
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
// Network tests
|
|
570
|
+
async testLatency() {
|
|
571
|
+
const resultEl = document.getElementById('latency-result');
|
|
572
|
+
resultEl.textContent = 'Testing...';
|
|
573
|
+
|
|
574
|
+
const start = Date.now();
|
|
575
|
+
this.connectionManager.socket.emit('ping');
|
|
576
|
+
|
|
577
|
+
// Wait for pong
|
|
578
|
+
const pongHandler = () => {
|
|
579
|
+
const latency = Date.now() - start;
|
|
580
|
+
resultEl.textContent = `${latency}ms`;
|
|
581
|
+
this.connectionManager.socket.off('pong', pongHandler);
|
|
582
|
+
this.addTimelineEvent(`Latency test: ${latency}ms`);
|
|
583
|
+
};
|
|
584
|
+
|
|
585
|
+
this.connectionManager.socket.on('pong', pongHandler);
|
|
586
|
+
|
|
587
|
+
// Timeout after 5 seconds
|
|
588
|
+
setTimeout(() => {
|
|
589
|
+
this.connectionManager.socket.off('pong', pongHandler);
|
|
590
|
+
if (resultEl.textContent === 'Testing...') {
|
|
591
|
+
resultEl.textContent = 'Timeout';
|
|
592
|
+
}
|
|
593
|
+
}, 5000);
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
async testThroughput() {
|
|
597
|
+
const resultEl = document.getElementById('throughput-result');
|
|
598
|
+
resultEl.textContent = 'Testing...';
|
|
599
|
+
|
|
600
|
+
// Send 100 events rapidly
|
|
601
|
+
const start = Date.now();
|
|
602
|
+
let received = 0;
|
|
603
|
+
|
|
604
|
+
const handler = () => {
|
|
605
|
+
received++;
|
|
606
|
+
if (received === 100) {
|
|
607
|
+
const duration = (Date.now() - start) / 1000;
|
|
608
|
+
const throughput = Math.round(100 / duration);
|
|
609
|
+
resultEl.textContent = `${throughput} evt/s`;
|
|
610
|
+
this.addTimelineEvent(`Throughput test: ${throughput} events/sec`);
|
|
611
|
+
}
|
|
612
|
+
};
|
|
613
|
+
|
|
614
|
+
this.connectionManager.socket.on('test_response', handler);
|
|
615
|
+
|
|
616
|
+
for (let i = 0; i < 100; i++) {
|
|
617
|
+
this.connectionManager.socket.emit('test_event', { index: i });
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
// Cleanup after 10 seconds
|
|
621
|
+
setTimeout(() => {
|
|
622
|
+
this.connectionManager.socket.off('test_response', handler);
|
|
623
|
+
if (received < 100) {
|
|
624
|
+
resultEl.textContent = `${received}/100 received`;
|
|
625
|
+
}
|
|
626
|
+
}, 10000);
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
async testStability() {
|
|
630
|
+
const resultEl = document.getElementById('stability-result');
|
|
631
|
+
resultEl.textContent = 'Testing (30s)...';
|
|
632
|
+
|
|
633
|
+
let disconnects = 0;
|
|
634
|
+
let reconnects = 0;
|
|
635
|
+
const startMetrics = { ...this.connectionManager.metrics };
|
|
636
|
+
|
|
637
|
+
// Monitor for 30 seconds
|
|
638
|
+
setTimeout(() => {
|
|
639
|
+
const endMetrics = this.connectionManager.metrics;
|
|
640
|
+
disconnects = endMetrics.totalConnections - startMetrics.totalConnections;
|
|
641
|
+
|
|
642
|
+
if (disconnects === 0) {
|
|
643
|
+
resultEl.textContent = 'Stable ✓';
|
|
644
|
+
} else {
|
|
645
|
+
resultEl.textContent = `${disconnects} drops`;
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
this.addTimelineEvent(`Stability test: ${disconnects} disconnections`);
|
|
649
|
+
}, 30000);
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
// Export for use
|
|
654
|
+
export { ConnectionDebugPanel };
|