claude-mpm 4.2.44__py3-none-any.whl → 4.2.51__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.
Files changed (148) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/BASE_PM.md +43 -1
  3. claude_mpm/agents/INSTRUCTIONS.md +75 -1
  4. claude_mpm/agents/WORKFLOW.md +46 -1
  5. claude_mpm/agents/frontmatter_validator.py +20 -12
  6. claude_mpm/agents/templates/nextjs_engineer.json +277 -0
  7. claude_mpm/agents/templates/python_engineer.json +289 -0
  8. claude_mpm/agents/templates/react_engineer.json +11 -3
  9. claude_mpm/agents/templates/security.json +50 -9
  10. claude_mpm/cli/commands/agents.py +2 -2
  11. claude_mpm/cli/commands/uninstall.py +1 -2
  12. claude_mpm/cli/interactive/agent_wizard.py +3 -3
  13. claude_mpm/cli/parsers/agent_manager_parser.py +3 -3
  14. claude_mpm/cli/parsers/agents_parser.py +1 -1
  15. claude_mpm/constants.py +1 -1
  16. claude_mpm/core/error_handler.py +2 -4
  17. claude_mpm/core/file_utils.py +4 -12
  18. claude_mpm/core/log_manager.py +8 -5
  19. claude_mpm/core/logger.py +1 -1
  20. claude_mpm/core/logging_utils.py +6 -6
  21. claude_mpm/core/unified_agent_registry.py +18 -4
  22. claude_mpm/dashboard/react/components/DataInspector/DataInspector.module.css +188 -0
  23. claude_mpm/dashboard/react/components/EventViewer/EventViewer.module.css +156 -0
  24. claude_mpm/dashboard/react/components/shared/ConnectionStatus.module.css +38 -0
  25. claude_mpm/dashboard/react/components/shared/FilterBar.module.css +92 -0
  26. claude_mpm/dashboard/static/archive/activity_dashboard_fixed.html +248 -0
  27. claude_mpm/dashboard/static/archive/activity_dashboard_test.html +61 -0
  28. claude_mpm/dashboard/static/archive/test_activity_connection.html +179 -0
  29. claude_mpm/dashboard/static/archive/test_claude_tree_tab.html +68 -0
  30. claude_mpm/dashboard/static/archive/test_dashboard.html +409 -0
  31. claude_mpm/dashboard/static/archive/test_dashboard_fixed.html +519 -0
  32. claude_mpm/dashboard/static/archive/test_dashboard_verification.html +181 -0
  33. claude_mpm/dashboard/static/archive/test_file_data.html +315 -0
  34. claude_mpm/dashboard/static/archive/test_file_tree_empty_state.html +243 -0
  35. claude_mpm/dashboard/static/archive/test_file_tree_fix.html +234 -0
  36. claude_mpm/dashboard/static/archive/test_file_tree_rename.html +117 -0
  37. claude_mpm/dashboard/static/archive/test_file_tree_tab.html +115 -0
  38. claude_mpm/dashboard/static/archive/test_file_viewer.html +224 -0
  39. claude_mpm/dashboard/static/archive/test_final_activity.html +220 -0
  40. claude_mpm/dashboard/static/archive/test_tab_fix.html +139 -0
  41. claude_mpm/dashboard/static/built/assets/events.DjpNxWNo.css +1 -0
  42. claude_mpm/dashboard/static/built/components/activity-tree.js +1 -1
  43. claude_mpm/dashboard/static/built/components/agent-hierarchy.js +777 -0
  44. claude_mpm/dashboard/static/built/components/agent-inference.js +1 -1
  45. claude_mpm/dashboard/static/built/components/build-tracker.js +333 -0
  46. claude_mpm/dashboard/static/built/components/code-simple.js +857 -0
  47. claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +353 -0
  48. claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +235 -0
  49. claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +409 -0
  50. claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +435 -0
  51. claude_mpm/dashboard/static/built/components/code-viewer.js +2 -1076
  52. claude_mpm/dashboard/static/built/components/connection-debug.js +654 -0
  53. claude_mpm/dashboard/static/built/components/diff-viewer.js +891 -0
  54. claude_mpm/dashboard/static/built/components/event-processor.js +1 -1
  55. claude_mpm/dashboard/static/built/components/event-viewer.js +1 -1
  56. claude_mpm/dashboard/static/built/components/export-manager.js +1 -1
  57. claude_mpm/dashboard/static/built/components/file-change-tracker.js +443 -0
  58. claude_mpm/dashboard/static/built/components/file-change-viewer.js +690 -0
  59. claude_mpm/dashboard/static/built/components/file-tool-tracker.js +1 -1
  60. claude_mpm/dashboard/static/built/components/module-viewer.js +1 -1
  61. claude_mpm/dashboard/static/built/components/nav-bar.js +145 -0
  62. claude_mpm/dashboard/static/built/components/page-structure.js +429 -0
  63. claude_mpm/dashboard/static/built/components/session-manager.js +1 -1
  64. claude_mpm/dashboard/static/built/components/ui-state-manager.js +2 -465
  65. claude_mpm/dashboard/static/built/components/working-directory.js +1 -1
  66. claude_mpm/dashboard/static/built/connection-manager.js +536 -0
  67. claude_mpm/dashboard/static/built/dashboard.js +1 -1
  68. claude_mpm/dashboard/static/built/extension-error-handler.js +164 -0
  69. claude_mpm/dashboard/static/built/react/events.js +30 -0
  70. claude_mpm/dashboard/static/built/shared/dom-helpers.js +396 -0
  71. claude_mpm/dashboard/static/built/shared/event-bus.js +330 -0
  72. claude_mpm/dashboard/static/built/shared/event-filter-service.js +540 -0
  73. claude_mpm/dashboard/static/built/shared/logger.js +385 -0
  74. claude_mpm/dashboard/static/built/shared/page-structure.js +251 -0
  75. claude_mpm/dashboard/static/built/shared/tooltip-service.js +253 -0
  76. claude_mpm/dashboard/static/built/socket-client.js +1 -1
  77. claude_mpm/dashboard/static/built/tab-isolation-fix.js +185 -0
  78. claude_mpm/dashboard/static/css/dashboard.css +28 -5
  79. claude_mpm/dashboard/static/dist/assets/events.DjpNxWNo.css +1 -0
  80. claude_mpm/dashboard/static/dist/components/activity-tree.js +1 -1
  81. claude_mpm/dashboard/static/dist/components/agent-inference.js +1 -1
  82. claude_mpm/dashboard/static/dist/components/code-viewer.js +2 -0
  83. claude_mpm/dashboard/static/dist/components/event-processor.js +1 -1
  84. claude_mpm/dashboard/static/dist/components/event-viewer.js +1 -1
  85. claude_mpm/dashboard/static/dist/components/export-manager.js +1 -1
  86. claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +1 -1
  87. claude_mpm/dashboard/static/dist/components/module-viewer.js +1 -1
  88. claude_mpm/dashboard/static/dist/components/session-manager.js +1 -1
  89. claude_mpm/dashboard/static/dist/components/working-directory.js +1 -1
  90. claude_mpm/dashboard/static/dist/dashboard.js +1 -1
  91. claude_mpm/dashboard/static/dist/react/events.js +30 -0
  92. claude_mpm/dashboard/static/dist/socket-client.js +1 -1
  93. claude_mpm/dashboard/static/events.html +607 -0
  94. claude_mpm/dashboard/static/index.html +713 -0
  95. claude_mpm/dashboard/static/js/components/activity-tree.js +3 -17
  96. claude_mpm/dashboard/static/js/components/agent-hierarchy.js +4 -1
  97. claude_mpm/dashboard/static/js/components/agent-inference.js +3 -0
  98. claude_mpm/dashboard/static/js/components/build-tracker.js +8 -0
  99. claude_mpm/dashboard/static/js/components/code-viewer.js +306 -66
  100. claude_mpm/dashboard/static/js/components/event-processor.js +3 -0
  101. claude_mpm/dashboard/static/js/components/event-viewer.js +39 -2
  102. claude_mpm/dashboard/static/js/components/export-manager.js +3 -0
  103. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +30 -10
  104. claude_mpm/dashboard/static/js/components/socket-manager.js +4 -0
  105. claude_mpm/dashboard/static/js/components/ui-state-manager.js +285 -85
  106. claude_mpm/dashboard/static/js/components/working-directory.js +3 -0
  107. claude_mpm/dashboard/static/js/dashboard.js +61 -33
  108. claude_mpm/dashboard/static/js/socket-client.js +12 -8
  109. claude_mpm/dashboard/static/js/stores/dashboard-store.js +562 -0
  110. claude_mpm/dashboard/static/js/tab-isolation-fix.js +185 -0
  111. claude_mpm/dashboard/static/legacy/activity.html +736 -0
  112. claude_mpm/dashboard/static/legacy/agents.html +786 -0
  113. claude_mpm/dashboard/static/legacy/files.html +747 -0
  114. claude_mpm/dashboard/static/legacy/tools.html +831 -0
  115. claude_mpm/dashboard/static/monitors-index.html +218 -0
  116. claude_mpm/dashboard/static/monitors.html +431 -0
  117. claude_mpm/dashboard/static/production/events.html +659 -0
  118. claude_mpm/dashboard/static/production/main.html +715 -0
  119. claude_mpm/dashboard/static/production/monitors.html +483 -0
  120. claude_mpm/dashboard/static/socket.io.min.js +7 -0
  121. claude_mpm/dashboard/static/socket.io.v4.8.1.backup.js +7 -0
  122. claude_mpm/dashboard/static/test-archive/dashboard.html +635 -0
  123. claude_mpm/dashboard/static/test-archive/debug-events.html +147 -0
  124. claude_mpm/dashboard/static/test-archive/test-navigation.html +256 -0
  125. claude_mpm/dashboard/static/test-archive/test-react-exports.html +180 -0
  126. claude_mpm/dashboard/templates/index.html +79 -9
  127. claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +1 -1
  128. claude_mpm/services/agents/deployment/agent_discovery_service.py +3 -0
  129. claude_mpm/services/agents/deployment/agent_template_builder.py +25 -8
  130. claude_mpm/services/agents/deployment/agent_validator.py +3 -0
  131. claude_mpm/services/agents/deployment/validation/template_validator.py +13 -4
  132. claude_mpm/services/agents/local_template_manager.py +2 -6
  133. claude_mpm/services/monitor/daemon.py +1 -2
  134. claude_mpm/services/monitor/daemon_manager.py +2 -5
  135. claude_mpm/services/monitor/event_emitter.py +2 -2
  136. claude_mpm/services/monitor/handlers/code_analysis.py +4 -6
  137. claude_mpm/services/monitor/handlers/hooks.py +2 -4
  138. claude_mpm/services/monitor/server.py +27 -4
  139. claude_mpm/tools/code_tree_analyzer.py +2 -2
  140. {claude_mpm-4.2.44.dist-info → claude_mpm-4.2.51.dist-info}/METADATA +1 -1
  141. {claude_mpm-4.2.44.dist-info → claude_mpm-4.2.51.dist-info}/RECORD +146 -81
  142. claude_mpm/dashboard/static/test-browser-monitor.html +0 -470
  143. claude_mpm/dashboard/static/test-simple.html +0 -97
  144. /claude_mpm/dashboard/static/{test_debug.html → test-archive/test_debug.html} +0 -0
  145. {claude_mpm-4.2.44.dist-info → claude_mpm-4.2.51.dist-info}/WHEEL +0 -0
  146. {claude_mpm-4.2.44.dist-info → claude_mpm-4.2.51.dist-info}/entry_points.txt +0 -0
  147. {claude_mpm-4.2.44.dist-info → claude_mpm-4.2.51.dist-info}/licenses/LICENSE +0 -0
  148. {claude_mpm-4.2.44.dist-info → claude_mpm-4.2.51.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,607 @@
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>Claude MPM - Events Dashboard</title>
7
+
8
+ <!-- Load Socket.IO -->
9
+ <script src="/static/socket.io.min.js"></script>
10
+
11
+ <!-- Verify Socket.IO is loaded - strict mode with error throwing -->
12
+ <script>
13
+ // Check if Socket.IO is loaded and available - no fallback
14
+ if (typeof io === 'undefined') {
15
+ const error = new Error('Required dependency missing: Socket.IO not loaded from /static/socket.io.min.js');
16
+ console.error(error.message);
17
+ // Display error to user
18
+ document.addEventListener('DOMContentLoaded', function() {
19
+ document.body.innerHTML = `
20
+ <div style="padding: 20px; background: rgba(248, 113, 113, 0.1); border: 1px solid #f87171; border-radius: 8px; color: #f87171; font-family: monospace; margin: 20px;">
21
+ <h2>Dependency Error</h2>
22
+ <p><strong>Error:</strong> ${error.message}</p>
23
+ <p>The dashboard requires Socket.IO to function. Please ensure the Socket.IO library is properly loaded.</p>
24
+ </div>
25
+ `;
26
+ });
27
+ throw error;
28
+ } else {
29
+ console.log('Socket.IO loaded successfully, version:', io.version || 'unknown');
30
+ }
31
+ </script>
32
+
33
+ <style>
34
+ * {
35
+ margin: 0;
36
+ padding: 0;
37
+ box-sizing: border-box;
38
+ }
39
+
40
+ body {
41
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
42
+ background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%);
43
+ color: #e0e0e0;
44
+ width: 100vw;
45
+ height: 100vh;
46
+ overflow: hidden;
47
+ display: flex;
48
+ flex-direction: column;
49
+ }
50
+
51
+ .container {
52
+ width: 100%;
53
+ height: 100%;
54
+ padding: 20px;
55
+ overflow-y: auto;
56
+ display: flex;
57
+ flex-direction: column;
58
+ }
59
+
60
+ .header {
61
+ background: rgba(255, 255, 255, 0.05);
62
+ backdrop-filter: blur(10px);
63
+ border-radius: 12px;
64
+ padding: 20px;
65
+ margin-bottom: 20px;
66
+ border: 1px solid rgba(255, 255, 255, 0.1);
67
+ }
68
+
69
+ .header h1 {
70
+ font-size: 24px;
71
+ margin-bottom: 10px;
72
+ background: linear-gradient(135deg, #10b981 0%, #06b6d4 100%);
73
+ -webkit-background-clip: text;
74
+ -webkit-text-fill-color: transparent;
75
+ }
76
+
77
+ .status-bar {
78
+ display: flex;
79
+ gap: 20px;
80
+ align-items: center;
81
+ flex-wrap: wrap;
82
+ }
83
+
84
+ .status-indicator {
85
+ display: flex;
86
+ align-items: center;
87
+ gap: 8px;
88
+ padding: 8px 16px;
89
+ background: rgba(255, 255, 255, 0.05);
90
+ border-radius: 20px;
91
+ font-size: 14px;
92
+ }
93
+
94
+ .status-dot {
95
+ width: 10px;
96
+ height: 10px;
97
+ border-radius: 50%;
98
+ animation: pulse 2s infinite;
99
+ }
100
+
101
+ .status-dot.connected {
102
+ background: #4ade80;
103
+ box-shadow: 0 0 10px #4ade80;
104
+ }
105
+
106
+ .status-dot.disconnected {
107
+ background: #f87171;
108
+ box-shadow: 0 0 10px #f87171;
109
+ }
110
+
111
+ @keyframes pulse {
112
+ 0%, 100% { opacity: 1; }
113
+ 50% { opacity: 0.5; }
114
+ }
115
+
116
+ .controls-panel {
117
+ background: rgba(255, 255, 255, 0.05);
118
+ backdrop-filter: blur(10px);
119
+ border: 1px solid rgba(255, 255, 255, 0.1);
120
+ border-radius: 10px;
121
+ padding: 15px;
122
+ margin-bottom: 20px;
123
+ display: flex;
124
+ gap: 15px;
125
+ align-items: center;
126
+ flex-wrap: wrap;
127
+ }
128
+
129
+ .control-group {
130
+ display: flex;
131
+ align-items: center;
132
+ gap: 10px;
133
+ }
134
+
135
+ .control-label {
136
+ font-size: 14px;
137
+ color: #94a3b8;
138
+ }
139
+
140
+ .btn {
141
+ padding: 10px 20px;
142
+ background: linear-gradient(135deg, #10b981 0%, #06b6d4 100%);
143
+ border: none;
144
+ border-radius: 8px;
145
+ color: white;
146
+ cursor: pointer;
147
+ font-size: 14px;
148
+ transition: transform 0.2s, box-shadow 0.2s;
149
+ }
150
+
151
+ .btn:hover {
152
+ transform: translateY(-2px);
153
+ box-shadow: 0 5px 15px rgba(16, 185, 129, 0.4);
154
+ }
155
+
156
+ .btn.secondary {
157
+ background: rgba(255, 255, 255, 0.1);
158
+ }
159
+
160
+ .btn.danger {
161
+ background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
162
+ }
163
+
164
+ .search-box {
165
+ flex: 1;
166
+ min-width: 200px;
167
+ padding: 10px 15px;
168
+ background: rgba(255, 255, 255, 0.05);
169
+ border: 1px solid rgba(255, 255, 255, 0.1);
170
+ border-radius: 8px;
171
+ color: white;
172
+ font-size: 14px;
173
+ }
174
+
175
+ .filter-select {
176
+ padding: 10px 15px;
177
+ background: rgba(255, 255, 255, 0.05);
178
+ border: 1px solid rgba(255, 255, 255, 0.1);
179
+ border-radius: 8px;
180
+ color: white;
181
+ font-size: 14px;
182
+ cursor: pointer;
183
+ }
184
+
185
+ .filter-select option {
186
+ background: #0f172a;
187
+ }
188
+
189
+ .checkbox-label {
190
+ display: flex;
191
+ align-items: center;
192
+ gap: 8px;
193
+ padding: 10px 15px;
194
+ background: rgba(255, 255, 255, 0.05);
195
+ border: 1px solid rgba(255, 255, 255, 0.1);
196
+ border-radius: 8px;
197
+ cursor: pointer;
198
+ font-size: 14px;
199
+ }
200
+
201
+ .checkbox-label input {
202
+ cursor: pointer;
203
+ }
204
+
205
+ .events-container {
206
+ background: rgba(255, 255, 255, 0.05);
207
+ backdrop-filter: blur(10px);
208
+ border-radius: 12px;
209
+ border: 1px solid rgba(255, 255, 255, 0.1);
210
+ overflow: hidden;
211
+ flex: 1;
212
+ display: flex;
213
+ flex-direction: column;
214
+ min-height: 0;
215
+ }
216
+
217
+ .events-header {
218
+ padding: 15px 20px;
219
+ background: rgba(255, 255, 255, 0.05);
220
+ border-bottom: 1px solid rgba(255, 255, 255, 0.1);
221
+ display: flex;
222
+ justify-content: space-between;
223
+ align-items: center;
224
+ }
225
+
226
+ .events-title {
227
+ font-weight: 600;
228
+ }
229
+
230
+ .events-info {
231
+ font-size: 12px;
232
+ color: rgba(255, 255, 255, 0.6);
233
+ }
234
+
235
+ .events-list {
236
+ flex: 1;
237
+ overflow-y: auto;
238
+ position: relative;
239
+ min-height: 300px;
240
+ }
241
+
242
+ .event-item {
243
+ padding: 12px 20px;
244
+ border-bottom: 1px solid rgba(255, 255, 255, 0.05);
245
+ transition: background 0.2s;
246
+ cursor: pointer;
247
+ font-family: 'Courier New', monospace;
248
+ font-size: 13px;
249
+ position: relative;
250
+ animation: slideIn 0.3s ease;
251
+ }
252
+
253
+ @keyframes slideIn {
254
+ from {
255
+ opacity: 0;
256
+ transform: translateX(-20px);
257
+ }
258
+ to {
259
+ opacity: 1;
260
+ transform: translateX(0);
261
+ }
262
+ }
263
+
264
+ .event-item:hover {
265
+ background: rgba(255, 255, 255, 0.05);
266
+ }
267
+
268
+ .event-item.expanded {
269
+ background: rgba(255, 255, 255, 0.08);
270
+ }
271
+
272
+ .event-header-row {
273
+ display: flex;
274
+ gap: 10px;
275
+ align-items: center;
276
+ margin-bottom: 5px;
277
+ }
278
+
279
+ .event-type {
280
+ padding: 3px 8px;
281
+ border-radius: 10px;
282
+ font-size: 11px;
283
+ font-weight: 600;
284
+ text-transform: uppercase;
285
+ }
286
+
287
+ .event-type.agent {
288
+ background: rgba(167, 139, 250, 0.2);
289
+ color: #a78bfa;
290
+ }
291
+
292
+ .event-type.tool {
293
+ background: rgba(96, 165, 250, 0.2);
294
+ color: #60a5fa;
295
+ }
296
+
297
+ .event-type.file {
298
+ background: rgba(251, 191, 36, 0.2);
299
+ color: #fbbf24;
300
+ }
301
+
302
+ .event-type.session {
303
+ background: rgba(74, 222, 128, 0.2);
304
+ color: #4ade80;
305
+ }
306
+
307
+ .event-type.error {
308
+ background: rgba(248, 113, 113, 0.2);
309
+ color: #f87171;
310
+ }
311
+
312
+ .event-type.info {
313
+ background: rgba(134, 239, 172, 0.2);
314
+ color: #86efac;
315
+ }
316
+
317
+ .event-time {
318
+ font-size: 11px;
319
+ color: rgba(255, 255, 255, 0.5);
320
+ }
321
+
322
+ .event-preview {
323
+ color: rgba(255, 255, 255, 0.7);
324
+ white-space: nowrap;
325
+ overflow: hidden;
326
+ text-overflow: ellipsis;
327
+ }
328
+
329
+ .event-details {
330
+ margin-top: 10px;
331
+ padding: 10px;
332
+ background: rgba(0, 0, 0, 0.3);
333
+ border-radius: 6px;
334
+ white-space: pre-wrap;
335
+ word-break: break-all;
336
+ max-height: 300px;
337
+ overflow-y: auto;
338
+ display: none;
339
+ }
340
+
341
+ .event-item.expanded .event-details {
342
+ display: block;
343
+ }
344
+
345
+ .json-key {
346
+ color: #60a5fa;
347
+ }
348
+
349
+ .json-string {
350
+ color: #86efac;
351
+ }
352
+
353
+ .json-number {
354
+ color: #fbbf24;
355
+ }
356
+
357
+ .json-boolean {
358
+ color: #a78bfa;
359
+ }
360
+
361
+ .json-null {
362
+ color: #f87171;
363
+ }
364
+
365
+ .stats-panel {
366
+ display: grid;
367
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
368
+ gap: 15px;
369
+ margin-bottom: 20px;
370
+ }
371
+
372
+ .stat-card {
373
+ background: rgba(255, 255, 255, 0.05);
374
+ backdrop-filter: blur(10px);
375
+ border: 1px solid rgba(255, 255, 255, 0.1);
376
+ border-radius: 10px;
377
+ padding: 15px;
378
+ display: flex;
379
+ align-items: center;
380
+ gap: 15px;
381
+ }
382
+
383
+ .stat-icon {
384
+ font-size: 24px;
385
+ background: linear-gradient(135deg, #10b981 0%, #06b6d4 100%);
386
+ -webkit-background-clip: text;
387
+ -webkit-text-fill-color: transparent;
388
+ }
389
+
390
+ .stat-info {
391
+ flex: 1;
392
+ }
393
+
394
+ .stat-label {
395
+ font-size: 12px;
396
+ color: #94a3b8;
397
+ text-transform: uppercase;
398
+ letter-spacing: 0.5px;
399
+ }
400
+
401
+ .stat-value {
402
+ font-size: 24px;
403
+ font-weight: 600;
404
+ color: #e0e0e0;
405
+ }
406
+
407
+ .event-rate {
408
+ display: inline-block;
409
+ margin-left: 10px;
410
+ padding: 2px 6px;
411
+ background: rgba(16, 185, 129, 0.2);
412
+ border-radius: 10px;
413
+ font-size: 11px;
414
+ color: #10b981;
415
+ }
416
+
417
+ .no-events {
418
+ text-align: center;
419
+ padding: 60px 20px;
420
+ color: rgba(255, 255, 255, 0.5);
421
+ }
422
+
423
+ /* Scrollbar styling */
424
+ ::-webkit-scrollbar {
425
+ width: 8px;
426
+ height: 8px;
427
+ }
428
+
429
+ ::-webkit-scrollbar-track {
430
+ background: rgba(255, 255, 255, 0.05);
431
+ border-radius: 4px;
432
+ }
433
+
434
+ ::-webkit-scrollbar-thumb {
435
+ background: rgba(255, 255, 255, 0.2);
436
+ border-radius: 4px;
437
+ }
438
+
439
+ ::-webkit-scrollbar-thumb:hover {
440
+ background: rgba(255, 255, 255, 0.3);
441
+ }
442
+
443
+ /* Navigation styles will be injected by nav-bar.js */
444
+
445
+ /* React component integration styles */
446
+ .react-events-container {
447
+ flex: 1;
448
+ display: flex;
449
+ flex-direction: column;
450
+ gap: 20px;
451
+ }
452
+
453
+ .fallback-container {
454
+ flex: 1;
455
+ display: flex;
456
+ flex-direction: column;
457
+ gap: 20px;
458
+ }
459
+
460
+ /* Ensure React components inherit the dashboard styling */
461
+ #react-events-root .stats-panel {
462
+ display: grid;
463
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
464
+ gap: 15px;
465
+ margin-bottom: 20px;
466
+ }
467
+
468
+ #react-events-root .stat-card {
469
+ background: rgba(255, 255, 255, 0.05);
470
+ backdrop-filter: blur(10px);
471
+ border: 1px solid rgba(255, 255, 255, 0.1);
472
+ border-radius: 10px;
473
+ padding: 15px;
474
+ display: flex;
475
+ align-items: center;
476
+ gap: 15px;
477
+ }
478
+
479
+ #react-events-root .stat-icon {
480
+ font-size: 24px;
481
+ background: linear-gradient(135deg, #10b981 0%, #06b6d4 100%);
482
+ -webkit-background-clip: text;
483
+ -webkit-text-fill-color: transparent;
484
+ }
485
+
486
+ #react-events-root .stat-info {
487
+ flex: 1;
488
+ }
489
+
490
+ #react-events-root .stat-label {
491
+ font-size: 12px;
492
+ color: #94a3b8;
493
+ text-transform: uppercase;
494
+ letter-spacing: 0.5px;
495
+ }
496
+
497
+ #react-events-root .stat-value {
498
+ font-size: 24px;
499
+ font-weight: 600;
500
+ color: #e0e0e0;
501
+ }
502
+ </style>
503
+ </head>
504
+ <body>
505
+ <div class="container">
506
+ <!-- Header with standardized structure -->
507
+ <div class="header">
508
+ <h1>📊 Events Dashboard</h1>
509
+ <div class="status-bar">
510
+ <div class="status-indicator">
511
+ <span class="status-dot disconnected" id="connection-status"></span>
512
+ <span id="connection-text">Disconnected</span>
513
+ </div>
514
+ <div class="status-indicator">
515
+ <span>📊</span>
516
+ <span id="event-count">0 events</span>
517
+ </div>
518
+ <div class="status-indicator">
519
+ <span>⚡</span>
520
+ <span id="event-rate">0/s</span>
521
+ </div>
522
+ <div class="status-indicator">
523
+ <span>🔌</span>
524
+ <span id="active-connections">0 active</span>
525
+ </div>
526
+ </div>
527
+ </div>
528
+
529
+ <!-- Navigation Bar -->
530
+ <div id="navigation-container"></div>
531
+
532
+ <!-- React Events Container (will be populated by React or show error) -->
533
+ <div id="react-events-root" style="flex: 1; display: flex; flex-direction: column;">
534
+ <!-- Loading placeholder - removed fallback functionality -->
535
+ <div id="loading-placeholder" style="text-align: center; padding: 60px 20px; color: rgba(255, 255, 255, 0.5);">
536
+ <h3>Loading React Dashboard...</h3>
537
+ <p>Please wait while the React components initialize...</p>
538
+ </div>
539
+ </div>
540
+ </div>
541
+
542
+ <script type="module">
543
+ // Import navigation component
544
+ import { NavBar } from '/static/built/components/nav-bar.js';
545
+
546
+ // Initialize navigation
547
+ const navBar = new NavBar();
548
+ navBar.initialize('navigation-container');
549
+
550
+ // Try to load React Events component - strict mode with error throwing
551
+ async function loadReactEvents() {
552
+ console.log('Loading React Events component (strict mode)...');
553
+
554
+ try {
555
+ const { initializeReactEvents } = await import('/static/dist/react/events.js');
556
+
557
+ // Hide loading placeholder when React loads
558
+ const loadingElement = document.getElementById('loading-placeholder');
559
+ if (loadingElement) {
560
+ loadingElement.style.display = 'none';
561
+ }
562
+
563
+ // Initialize React component
564
+ initializeReactEvents();
565
+ console.log('React Events component loaded successfully');
566
+
567
+ } catch (error) {
568
+ const loadError = new Error(`Failed to load React components: ${error instanceof Error ? error.message : String(error)}`);
569
+ console.error(loadError.message);
570
+
571
+ // Display error to user instead of fallback
572
+ const container = document.getElementById('react-events-root');
573
+ if (container) {
574
+ container.innerHTML = `
575
+ <div style="padding: 20px; background: rgba(248, 113, 113, 0.1); border: 1px solid #f87171; border-radius: 8px; color: #f87171; font-family: monospace;">
576
+ <h2>React Component Loading Error</h2>
577
+ <p><strong>Error:</strong> ${loadError.message}</p>
578
+ <p>The React-based dashboard failed to load. This may be due to:</p>
579
+ <ul style="margin: 10px 0; padding-left: 20px;">
580
+ <li>Missing React build files at /static/dist/react/events.js</li>
581
+ <li>Network connectivity issues</li>
582
+ <li>Build process errors</li>
583
+ </ul>
584
+ <p>Check the console for detailed error information.</p>
585
+ </div>
586
+ `;
587
+ }
588
+
589
+ throw loadError;
590
+ }
591
+ }
592
+
593
+ // Load React component when DOM is ready
594
+ if (document.readyState === 'loading') {
595
+ document.addEventListener('DOMContentLoaded', loadReactEvents);
596
+ } else {
597
+ loadReactEvents();
598
+ }
599
+ </script>
600
+
601
+ <!-- Removed vanilla JS fallback implementation -->
602
+ <!-- Dashboard now uses React-only mode with error throwing -->
603
+ <script>
604
+ console.log('Events dashboard now running in React-only mode (no vanilla JS fallback)');
605
+ </script>
606
+ </body>
607
+ </html>