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,429 @@
1
+ /**
2
+ * Page Structure Component
3
+ * Provides standardized page layout for all dashboard views
4
+ * Includes header with title, connection status, and statistics
5
+ */
6
+
7
+ export class PageStructure {
8
+ constructor() {
9
+ this.connectionStatus = false;
10
+ this.startTime = Date.now();
11
+ this.uptimeInterval = null;
12
+ }
13
+
14
+ /**
15
+ * Create the standard page header structure
16
+ * @param {Object} config - Configuration for the page
17
+ * @param {string} config.title - Page title with emoji
18
+ * @param {Array} config.stats - Statistics to display
19
+ * @returns {string} HTML for the header
20
+ */
21
+ createHeader(config) {
22
+ const { title, stats = [] } = config;
23
+
24
+ return `
25
+ <div class="header">
26
+ <h1>${title}</h1>
27
+ <div class="status-bar">
28
+ <div class="status-indicator">
29
+ <span class="status-dot disconnected" id="connection-status"></span>
30
+ <span id="connection-text">Disconnected</span>
31
+ </div>
32
+ ${stats.map(stat => `
33
+ <div class="status-indicator">
34
+ <span>${stat.icon || ''}</span>
35
+ <span id="${stat.id}">${stat.defaultValue || '0'}</span>
36
+ </div>
37
+ `).join('')}
38
+ </div>
39
+ </div>
40
+ `;
41
+ }
42
+
43
+ /**
44
+ * Create the statistics panel
45
+ * @param {Array} cards - Statistics cards configuration
46
+ * @returns {string} HTML for the statistics panel
47
+ */
48
+ createStatsPanel(cards) {
49
+ return `
50
+ <div class="stats-panel">
51
+ ${cards.map(card => `
52
+ <div class="stat-card">
53
+ <div class="stat-icon">${card.icon}</div>
54
+ <div class="stat-info">
55
+ <div class="stat-label">${card.label}</div>
56
+ <div class="stat-value" id="${card.id}">${card.defaultValue || '0'}</div>
57
+ </div>
58
+ </div>
59
+ `).join('')}
60
+ </div>
61
+ `;
62
+ }
63
+
64
+ /**
65
+ * Create the controls panel
66
+ * @param {Array} controls - Control elements configuration
67
+ * @returns {string} HTML for the controls panel
68
+ */
69
+ createControlsPanel(controls = []) {
70
+ if (controls.length === 0) return '';
71
+
72
+ return `
73
+ <div class="controls-panel">
74
+ ${controls.map(control => {
75
+ switch (control.type) {
76
+ case 'select':
77
+ return `
78
+ <div class="control-group">
79
+ <label class="control-label">${control.label}:</label>
80
+ <select id="${control.id}">
81
+ ${control.options.map(opt =>
82
+ `<option value="${opt.value}" ${opt.selected ? 'selected' : ''}>${opt.text}</option>`
83
+ ).join('')}
84
+ </select>
85
+ </div>
86
+ `;
87
+ case 'input':
88
+ return `
89
+ <div class="control-group">
90
+ <input type="text" id="${control.id}" placeholder="${control.placeholder || ''}">
91
+ </div>
92
+ `;
93
+ case 'button':
94
+ return `
95
+ <button class="btn ${control.class || ''}" id="${control.id}">${control.text}</button>
96
+ `;
97
+ default:
98
+ return '';
99
+ }
100
+ }).join('')}
101
+ </div>
102
+ `;
103
+ }
104
+
105
+ /**
106
+ * Apply standard page structure to a container
107
+ * @param {string} containerId - ID of the container element
108
+ * @param {Object} config - Page configuration
109
+ */
110
+ applyStructure(containerId, config) {
111
+ const container = document.getElementById(containerId);
112
+ if (!container) {
113
+ console.error(`Container with ID "${containerId}" not found`);
114
+ return;
115
+ }
116
+
117
+ // Create the complete structure
118
+ const structure = `
119
+ ${this.createHeader(config.header)}
120
+ <div id="navigation-container"></div>
121
+ ${config.statsPanel ? this.createStatsPanel(config.statsPanel) : ''}
122
+ ${config.controls ? this.createControlsPanel(config.controls) : ''}
123
+ <div class="main-panel">
124
+ ${config.mainContent || '<div id="main-content"></div>'}
125
+ </div>
126
+ `;
127
+
128
+ // Insert the structure
129
+ container.innerHTML = structure;
130
+
131
+ // Initialize connection status handlers
132
+ this.initializeConnectionStatus();
133
+
134
+ // Initialize uptime counter if needed
135
+ if (config.header.stats && config.header.stats.some(s => s.id === 'uptime')) {
136
+ this.startUptimeCounter();
137
+ }
138
+ }
139
+
140
+ /**
141
+ * Initialize connection status indicators
142
+ */
143
+ initializeConnectionStatus() {
144
+ // This will be called by the socket manager when connection changes
145
+ window.addEventListener('connection-status-changed', (event) => {
146
+ this.updateConnectionStatus(event.detail.connected);
147
+ });
148
+ }
149
+
150
+ /**
151
+ * Update connection status display
152
+ * @param {boolean} connected - Connection status
153
+ */
154
+ updateConnectionStatus(connected) {
155
+ const statusDot = document.getElementById('connection-status');
156
+ const statusText = document.getElementById('connection-text');
157
+
158
+ if (statusDot && statusText) {
159
+ this.connectionStatus = connected;
160
+ statusDot.className = `status-dot ${connected ? 'connected' : 'disconnected'}`;
161
+ statusText.textContent = connected ? 'Connected' : 'Disconnected';
162
+ }
163
+ }
164
+
165
+ /**
166
+ * Start the uptime counter
167
+ */
168
+ startUptimeCounter() {
169
+ if (this.uptimeInterval) {
170
+ clearInterval(this.uptimeInterval);
171
+ }
172
+
173
+ this.uptimeInterval = setInterval(() => {
174
+ const uptime = Date.now() - this.startTime;
175
+ const hours = Math.floor(uptime / 3600000);
176
+ const minutes = Math.floor((uptime % 3600000) / 60000);
177
+ const seconds = Math.floor((uptime % 60000) / 1000);
178
+
179
+ const uptimeElement = document.getElementById('uptime');
180
+ if (uptimeElement) {
181
+ uptimeElement.textContent =
182
+ `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
183
+ }
184
+ }, 1000);
185
+ }
186
+
187
+ /**
188
+ * Update a statistic value
189
+ * @param {string} statId - ID of the statistic element
190
+ * @param {string|number} value - New value
191
+ */
192
+ updateStat(statId, value) {
193
+ const element = document.getElementById(statId);
194
+ if (element) {
195
+ element.textContent = value;
196
+ }
197
+ }
198
+
199
+ /**
200
+ * Update multiple statistics at once
201
+ * @param {Object} stats - Object with stat IDs as keys and values as values
202
+ */
203
+ updateStats(stats) {
204
+ Object.entries(stats).forEach(([id, value]) => {
205
+ this.updateStat(id, value);
206
+ });
207
+ }
208
+
209
+ /**
210
+ * Clean up resources
211
+ */
212
+ destroy() {
213
+ if (this.uptimeInterval) {
214
+ clearInterval(this.uptimeInterval);
215
+ this.uptimeInterval = null;
216
+ }
217
+ }
218
+ }
219
+
220
+ // Export default styles that should be applied to all pages
221
+ export const pageStyles = `
222
+ * {
223
+ margin: 0;
224
+ padding: 0;
225
+ box-sizing: border-box;
226
+ }
227
+
228
+ body {
229
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
230
+ background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%);
231
+ color: #e0e0e0;
232
+ min-height: 100vh;
233
+ padding: 20px;
234
+ }
235
+
236
+ .container {
237
+ max-width: 1600px;
238
+ margin: 0 auto;
239
+ }
240
+
241
+ .header {
242
+ background: rgba(255, 255, 255, 0.05);
243
+ backdrop-filter: blur(10px);
244
+ border-radius: 12px;
245
+ padding: 20px;
246
+ margin-bottom: 20px;
247
+ border: 1px solid rgba(255, 255, 255, 0.1);
248
+ }
249
+
250
+ .header h1 {
251
+ font-size: 24px;
252
+ margin-bottom: 10px;
253
+ background: linear-gradient(135deg, #10b981 0%, #06b6d4 100%);
254
+ -webkit-background-clip: text;
255
+ -webkit-text-fill-color: transparent;
256
+ }
257
+
258
+ .status-bar {
259
+ display: flex;
260
+ gap: 20px;
261
+ align-items: center;
262
+ flex-wrap: wrap;
263
+ }
264
+
265
+ .status-indicator {
266
+ display: flex;
267
+ align-items: center;
268
+ gap: 8px;
269
+ padding: 8px 16px;
270
+ background: rgba(255, 255, 255, 0.05);
271
+ border-radius: 20px;
272
+ font-size: 14px;
273
+ }
274
+
275
+ .status-dot {
276
+ width: 10px;
277
+ height: 10px;
278
+ border-radius: 50%;
279
+ animation: pulse 2s infinite;
280
+ }
281
+
282
+ .status-dot.connected {
283
+ background: #4ade80;
284
+ box-shadow: 0 0 10px #4ade80;
285
+ }
286
+
287
+ .status-dot.disconnected {
288
+ background: #f87171;
289
+ box-shadow: 0 0 10px #f87171;
290
+ }
291
+
292
+ @keyframes pulse {
293
+ 0%, 100% { opacity: 1; }
294
+ 50% { opacity: 0.5; }
295
+ }
296
+
297
+ .stats-panel {
298
+ display: grid;
299
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
300
+ gap: 15px;
301
+ margin-bottom: 20px;
302
+ }
303
+
304
+ .stat-card {
305
+ background: rgba(255, 255, 255, 0.05);
306
+ backdrop-filter: blur(10px);
307
+ border: 1px solid rgba(255, 255, 255, 0.1);
308
+ border-radius: 10px;
309
+ padding: 15px;
310
+ display: flex;
311
+ align-items: center;
312
+ gap: 15px;
313
+ }
314
+
315
+ .stat-icon {
316
+ font-size: 24px;
317
+ background: linear-gradient(135deg, #10b981 0%, #06b6d4 100%);
318
+ -webkit-background-clip: text;
319
+ -webkit-text-fill-color: transparent;
320
+ }
321
+
322
+ .stat-info {
323
+ flex: 1;
324
+ }
325
+
326
+ .stat-label {
327
+ font-size: 12px;
328
+ color: #94a3b8;
329
+ text-transform: uppercase;
330
+ letter-spacing: 0.5px;
331
+ }
332
+
333
+ .stat-value {
334
+ font-size: 24px;
335
+ font-weight: 600;
336
+ color: #e0e0e0;
337
+ }
338
+
339
+ .controls-panel {
340
+ background: rgba(255, 255, 255, 0.05);
341
+ backdrop-filter: blur(10px);
342
+ border: 1px solid rgba(255, 255, 255, 0.1);
343
+ border-radius: 10px;
344
+ padding: 15px;
345
+ margin-bottom: 20px;
346
+ display: flex;
347
+ gap: 15px;
348
+ align-items: center;
349
+ flex-wrap: wrap;
350
+ }
351
+
352
+ .control-group {
353
+ display: flex;
354
+ align-items: center;
355
+ gap: 10px;
356
+ }
357
+
358
+ .control-label {
359
+ font-size: 14px;
360
+ color: #94a3b8;
361
+ }
362
+
363
+ select, input[type="text"] {
364
+ padding: 8px 12px;
365
+ background: rgba(255, 255, 255, 0.1);
366
+ border: 1px solid rgba(255, 255, 255, 0.2);
367
+ border-radius: 6px;
368
+ color: #e0e0e0;
369
+ font-size: 14px;
370
+ }
371
+
372
+ select option {
373
+ background: #1e293b;
374
+ }
375
+
376
+ .btn {
377
+ padding: 8px 16px;
378
+ background: linear-gradient(135deg, #10b981 0%, #06b6d4 100%);
379
+ border: none;
380
+ border-radius: 6px;
381
+ color: white;
382
+ cursor: pointer;
383
+ font-size: 14px;
384
+ font-weight: 500;
385
+ transition: all 0.3s;
386
+ }
387
+
388
+ .btn:hover {
389
+ transform: translateY(-2px);
390
+ box-shadow: 0 5px 15px rgba(16, 185, 129, 0.3);
391
+ }
392
+
393
+ .btn.btn-secondary {
394
+ background: rgba(255, 255, 255, 0.1);
395
+ }
396
+
397
+ .btn.btn-secondary:hover {
398
+ background: rgba(255, 255, 255, 0.15);
399
+ }
400
+
401
+ .main-panel {
402
+ background: rgba(255, 255, 255, 0.05);
403
+ backdrop-filter: blur(10px);
404
+ border: 1px solid rgba(255, 255, 255, 0.1);
405
+ border-radius: 10px;
406
+ padding: 20px;
407
+ min-height: 500px;
408
+ }
409
+
410
+ /* Scrollbar styling */
411
+ ::-webkit-scrollbar {
412
+ width: 8px;
413
+ height: 8px;
414
+ }
415
+
416
+ ::-webkit-scrollbar-track {
417
+ background: rgba(255, 255, 255, 0.05);
418
+ border-radius: 4px;
419
+ }
420
+
421
+ ::-webkit-scrollbar-thumb {
422
+ background: rgba(255, 255, 255, 0.2);
423
+ border-radius: 4px;
424
+ }
425
+
426
+ ::-webkit-scrollbar-thumb:hover {
427
+ background: rgba(255, 255, 255, 0.3);
428
+ }
429
+ `;
@@ -1,2 +1,2 @@
1
- class e{constructor(e){this.socketClient=e,this.sessions=new Map,this.currentSessionId=null,this.selectedSessionId="",this.init()}init(){this.setupEventHandlers(),this.setupSocketListeners(),this.updateSessionSelect()}setupEventHandlers(){const e=document.getElementById("session-select");e&&e.addEventListener("change",e=>{this.selectedSessionId=e.target.value,this.onSessionFilterChanged(),window.dashboard&&window.dashboard.loadWorkingDirectoryForSession&&window.dashboard.loadWorkingDirectoryForSession(e.target.value)});const s=document.querySelector('button[onclick="refreshSessions()"]');s&&s.addEventListener("click",()=>{this.refreshSessions()})}setupSocketListeners(){this.socketClient.onEventUpdate((e,s)=>{console.log("[SESSION-MANAGER] Received sessions update:",s),this.sessions=s,this.updateSessionSelect(),this.updateFooterInfo()}),document.addEventListener("socketConnectionStatus",e=>{"connected"===e.detail.type&&setTimeout(()=>this.refreshSessions(),1e3)})}updateSessionSelect(){const e=document.getElementById("session-select");if(!e)return;const s=e.value;let t="/";if(window.dashboard&&window.dashboard.workingDirectoryManager)t=window.dashboard.workingDirectoryManager.getDefaultWorkingDir();else{const e=document.getElementById("working-dir-path");if(e?.textContent?.trim()){const s=e.textContent.trim();"Loading..."!==s&&"Unknown"!==s&&(t=s)}}if(console.log("[SESSION-MANAGER] Using default working directory:",t),e.innerHTML=`\n <option value="">${t} | All Sessions</option>\n `,this.sessions&&this.sessions.size>0){Array.from(this.sessions.values()).sort((e,s)=>new Date(s.lastActivity||s.startTime)-new Date(e.lastActivity||e.startTime)).forEach(s=>{const n=document.createElement("option");n.value=s.id,new Date(s.startTime||s.last_activity).toLocaleString(),s.eventCount||s.event_count;const o=s.id===this.currentSessionId;let i=s.working_directory||s.workingDirectory||"";if(console.log(`[SESSION-DROPDOWN] Session ${s.id.substring(0,8)} working_directory:`,i),!i){i=this.extractSessionInfoFromEvents(s.id).workingDir||t,console.log("[SESSION-DROPDOWN] Extracted working directory from events:",i)}const r=s.id.substring(0,8),a=i||t;n.textContent=`${a} | ${r}...${o?" [ACTIVE]":""}`,e.appendChild(n)})}s&&Array.from(e.options).some(e=>e.value===s)?(e.value=s,this.selectedSessionId=s,this.onSessionFilterChanged()):(this.selectedSessionId=e.value,this.selectedSessionId&&this.onSessionFilterChanged())}onSessionFilterChanged(){const e=window.eventViewer;e&&e.setSessionFilter(this.selectedSessionId),this.updateFooterInfo(),document.dispatchEvent(new CustomEvent("sessionFilterChanged",{detail:{sessionId:this.selectedSessionId}})),document.dispatchEvent(new CustomEvent("sessionChanged",{detail:{sessionId:this.selectedSessionId}}))}refreshSessions(){this.socketClient&&this.socketClient.getConnectionState().isConnected?(console.log("Refreshing sessions..."),this.socketClient.requestStatus()):console.warn("Cannot refresh sessions: not connected to server")}updateFooterInfo(){console.log("[SESSION-DEBUG] updateFooterInfo called, selectedSessionId:",this.selectedSessionId);const e=document.getElementById("footer-session"),s=document.getElementById("footer-working-dir"),t=document.getElementById("footer-git-branch");if(!e)return void console.warn("[SESSION-DEBUG] footer-session element not found");let n="All Sessions",o=window.dashboard?.workingDirectoryManager?.getDefaultWorkingDir()||window.dashboardConfig?.workingDirectory||".",i="Unknown";if(console.log("[SESSION-DEBUG] Initial values - sessionInfo:",n,"workingDir:",o,"gitBranch:",i),"current"===this.selectedSessionId){if(n=this.currentSessionId?`Current: ${this.currentSessionId.substring(0,8)}...`:"Current: None",this.currentSessionId){const e=this.extractSessionInfoFromEvents(this.currentSessionId);o=e.workingDir||window.dashboard?.workingDirectoryManager?.getDefaultWorkingDir()||window.dashboardConfig?.workingDirectory||".",i=e.gitBranch||"Unknown"}}else if(this.selectedSessionId){const e=this.sessions.get(this.selectedSessionId);if(e&&(n=`${this.selectedSessionId.substring(0,8)}...`,o=e.working_directory||e.workingDirectory||"",i=e.git_branch||e.gitBranch||"",!o||!i)){const e=this.extractSessionInfoFromEvents(this.selectedSessionId);o=o||e.workingDir||window.dashboardConfig?.workingDirectory||".",i=i||e.gitBranch||""}}console.log("[SESSION-DEBUG] Final values before setting footer - sessionInfo:",n,"workingDir:",o,"gitBranch:",i),e.textContent=n,s?(console.log("[SESSION-DEBUG] Setting footer working dir to:",o),s.textContent=o):console.warn("[SESSION-DEBUG] footer-working-dir element not found"),t?(console.log("[SESSION-DEBUG] Setting footer git branch to:",i),t.textContent=i):console.warn("[SESSION-DEBUG] footer-git-branch element not found")}extractSessionInfoFromEvents(e){let s="",t="";console.log(`[DEBUG] extractSessionInfoFromEvents called for sessionId: ${e}`);const n=this.socketClient;if(n&&n.events){console.log(`[DEBUG] Total events available: ${n.events.length}`);const o=n.events.filter(s=>s.data&&s.data.session_id===e);console.log(`[DEBUG] Events matching sessionId ${e}: ${o.length}`),o.length>0&&(console.log(`[DEBUG] Sample events for session ${e}:`),o.slice(0,3).forEach((e,s)=>{console.log(`[DEBUG] Event ${s+1}:`,{type:e.type,timestamp:e.timestamp,data_keys:e.data?Object.keys(e.data):"no data",full_event:e})}),o.length>3&&(console.log(`[DEBUG] Last 3 events for session ${e}:`),o.slice(-3).forEach((e,s)=>{console.log(`[DEBUG] Last Event ${s+1}:`,{type:e.type,timestamp:e.timestamp,data_keys:e.data?Object.keys(e.data):"no data",full_event:e})})));for(let e=o.length-1;e>=0;e--){const n=o[e];if(n.data){if(console.log(`[DEBUG] Examining event ${e} data:`,n.data),s||(n.data.working_directory?(s=n.data.working_directory,console.log(`[DEBUG] Found working_directory: ${s}`)):n.data.cwd?(s=n.data.cwd,console.log(`[DEBUG] Found cwd: ${s}`)):n.data.instance_info&&n.data.instance_info.working_dir&&(s=n.data.instance_info.working_dir,console.log(`[DEBUG] Found instance_info.working_dir: ${s}`))),!t){const e=["git_branch","gitBranch","branch","git.branch","vcs_branch","current_branch"];for(const s of e)if(n.data[s]){t=n.data[s],console.log(`[DEBUG] Found git branch in field '${s}': ${t}`);break}if(!t){if(n.data.instance_info){console.log("[DEBUG] Checking instance_info for branch:",n.data.instance_info);for(const s of e)if(n.data.instance_info[s]){t=n.data.instance_info[s],console.log(`[DEBUG] Found git branch in instance_info.${s}: ${t}`);break}}!t&&n.data.git&&(console.log("[DEBUG] Checking git object:",n.data.git),n.data.git.branch&&(t=n.data.git.branch,console.log(`[DEBUG] Found git branch in git.branch: ${t}`)))}}if(s&&t){console.log("[DEBUG] Found both workingDir and gitBranch, stopping search");break}}}}else console.log("[DEBUG] No socket client or events available");return console.log(`[DEBUG] Final results - workingDir: '${s}', gitBranch: '${t}'`),{workingDir:s,gitBranch:t}}setCurrentSessionId(e){this.currentSessionId=e,this.updateSessionSelect(),this.updateFooterInfo()}addSession(e){if(!e.id)return;const s=this.sessions.get(e.id);s?Object.assign(s,e):this.sessions.set(e.id,{id:e.id,startTime:e.startTime||e.start_time||(new Date).toISOString(),lastActivity:e.lastActivity||e.last_activity||(new Date).toISOString(),eventCount:e.eventCount||e.event_count||0,working_directory:e.working_directory||e.workingDirectory||"",git_branch:e.git_branch||e.gitBranch||"",agent_type:e.agent_type||e.agentType||"",...e}),this.updateSessionSelect()}removeSession(e){if(this.sessions.has(e)){if(this.sessions.delete(e),this.selectedSessionId===e){this.selectedSessionId="";const e=document.getElementById("session-select");e&&(e.value=""),this.onSessionFilterChanged()}this.updateSessionSelect()}}getCurrentFilter(){return this.selectedSessionId}getSession(e){return this.sessions.get(e)||null}getAllSessions(){return this.sessions}getCurrentSessionId(){return this.currentSessionId}clearSessions(){this.sessions.clear(),this.currentSessionId=null,this.selectedSessionId="",this.updateSessionSelect(),this.updateFooterInfo()}exportSessionData(){return{sessions:Array.from(this.sessions.entries()),currentSessionId:this.currentSessionId,selectedSessionId:this.selectedSessionId}}importSessionData(e){e.sessions&&Array.isArray(e.sessions)&&(this.sessions.clear(),e.sessions.forEach(([e,s])=>{this.sessions.set(e,s)})),e.currentSessionId&&(this.currentSessionId=e.currentSessionId),void 0!==e.selectedSessionId&&(this.selectedSessionId=e.selectedSessionId),this.updateSessionSelect(),this.updateFooterInfo()}getEventsForSession(e){if(!e||!this.socketClient)return[];return(this.socketClient.events||[]).filter(s=>(s.session_id||s.data&&s.data.session_id||null)===e)}}window.refreshSessions=function(){window.sessionManager&&window.sessionManager.refreshSessions()},window.SessionManager=e;export{e as S};
1
+ window.refreshSessions=function(){window.sessionManager&&window.sessionManager.refreshSessions()},window.SessionManager=class{constructor(e){this.socketClient=e,this.sessions=new Map,this.currentSessionId=null,this.selectedSessionId="",this.init()}init(){this.setupEventHandlers(),this.setupSocketListeners(),this.updateSessionSelect()}setupEventHandlers(){const e=document.getElementById("session-select");e&&e.addEventListener("change",e=>{this.selectedSessionId=e.target.value,this.onSessionFilterChanged(),window.dashboard&&window.dashboard.loadWorkingDirectoryForSession&&window.dashboard.loadWorkingDirectoryForSession(e.target.value)});const s=document.querySelector('button[onclick="refreshSessions()"]');s&&s.addEventListener("click",()=>{this.refreshSessions()})}setupSocketListeners(){this.socketClient.onEventUpdate((e,s)=>{console.log("[SESSION-MANAGER] Received sessions update:",s),this.sessions=s,this.updateSessionSelect(),this.updateFooterInfo()}),document.addEventListener("socketConnectionStatus",e=>{"connected"===e.detail.type&&setTimeout(()=>this.refreshSessions(),1e3)})}updateSessionSelect(){const e=document.getElementById("session-select");if(!e)return;const s=e.value;let t="/";if(window.dashboard&&window.dashboard.workingDirectoryManager)t=window.dashboard.workingDirectoryManager.getDefaultWorkingDir();else{const e=document.getElementById("working-dir-path");if(e?.textContent?.trim()){const s=e.textContent.trim();"Loading..."!==s&&"Unknown"!==s&&(t=s)}}if(console.log("[SESSION-MANAGER] Using default working directory:",t),e.innerHTML=`\n <option value="">${t} | All Sessions</option>\n `,this.sessions&&this.sessions.size>0){Array.from(this.sessions.values()).sort((e,s)=>new Date(s.lastActivity||s.startTime)-new Date(e.lastActivity||e.startTime)).forEach(s=>{const n=document.createElement("option");n.value=s.id,new Date(s.startTime||s.last_activity).toLocaleString(),s.eventCount||s.event_count;const o=s.id===this.currentSessionId;let i=s.working_directory||s.workingDirectory||"";if(console.log(`[SESSION-DROPDOWN] Session ${s.id.substring(0,8)} working_directory:`,i),!i){i=this.extractSessionInfoFromEvents(s.id).workingDir||t,console.log("[SESSION-DROPDOWN] Extracted working directory from events:",i)}const r=s.id.substring(0,8),a=i||t;n.textContent=`${a} | ${r}...${o?" [ACTIVE]":""}`,e.appendChild(n)})}s&&Array.from(e.options).some(e=>e.value===s)?(e.value=s,this.selectedSessionId=s,this.onSessionFilterChanged()):(this.selectedSessionId=e.value,this.selectedSessionId&&this.onSessionFilterChanged())}onSessionFilterChanged(){const e=window.eventViewer;e&&e.setSessionFilter(this.selectedSessionId),this.updateFooterInfo(),document.dispatchEvent(new CustomEvent("sessionFilterChanged",{detail:{sessionId:this.selectedSessionId}})),document.dispatchEvent(new CustomEvent("sessionChanged",{detail:{sessionId:this.selectedSessionId}}))}refreshSessions(){this.socketClient&&this.socketClient.getConnectionState().isConnected?(console.log("Refreshing sessions..."),this.socketClient.requestStatus()):console.warn("Cannot refresh sessions: not connected to server")}updateFooterInfo(){console.log("[SESSION-DEBUG] updateFooterInfo called, selectedSessionId:",this.selectedSessionId);const e=document.getElementById("footer-session"),s=document.getElementById("footer-working-dir"),t=document.getElementById("footer-git-branch");if(!e)return void console.warn("[SESSION-DEBUG] footer-session element not found");let n="All Sessions",o=window.dashboard?.workingDirectoryManager?.getDefaultWorkingDir()||window.dashboardConfig?.workingDirectory||".",i="Unknown";if(console.log("[SESSION-DEBUG] Initial values - sessionInfo:",n,"workingDir:",o,"gitBranch:",i),"current"===this.selectedSessionId){if(n=this.currentSessionId?`Current: ${this.currentSessionId.substring(0,8)}...`:"Current: None",this.currentSessionId){const e=this.extractSessionInfoFromEvents(this.currentSessionId);o=e.workingDir||window.dashboard?.workingDirectoryManager?.getDefaultWorkingDir()||window.dashboardConfig?.workingDirectory||".",i=e.gitBranch||"Unknown"}}else if(this.selectedSessionId){const e=this.sessions.get(this.selectedSessionId);if(e&&(n=`${this.selectedSessionId.substring(0,8)}...`,o=e.working_directory||e.workingDirectory||"",i=e.git_branch||e.gitBranch||"",!o||!i)){const e=this.extractSessionInfoFromEvents(this.selectedSessionId);o=o||e.workingDir||window.dashboardConfig?.workingDirectory||".",i=i||e.gitBranch||""}}console.log("[SESSION-DEBUG] Final values before setting footer - sessionInfo:",n,"workingDir:",o,"gitBranch:",i),e.textContent=n,s?(console.log("[SESSION-DEBUG] Setting footer working dir to:",o),s.textContent=o):console.warn("[SESSION-DEBUG] footer-working-dir element not found"),t?(console.log("[SESSION-DEBUG] Setting footer git branch to:",i),t.textContent=i):console.warn("[SESSION-DEBUG] footer-git-branch element not found")}extractSessionInfoFromEvents(e){let s="",t="";console.log(`[DEBUG] extractSessionInfoFromEvents called for sessionId: ${e}`);const n=this.socketClient;if(n&&n.events){console.log(`[DEBUG] Total events available: ${n.events.length}`);const o=n.events.filter(s=>s.data&&s.data.session_id===e);console.log(`[DEBUG] Events matching sessionId ${e}: ${o.length}`),o.length>0&&(console.log(`[DEBUG] Sample events for session ${e}:`),o.slice(0,3).forEach((e,s)=>{console.log(`[DEBUG] Event ${s+1}:`,{type:e.type,timestamp:e.timestamp,data_keys:e.data?Object.keys(e.data):"no data",full_event:e})}),o.length>3&&(console.log(`[DEBUG] Last 3 events for session ${e}:`),o.slice(-3).forEach((e,s)=>{console.log(`[DEBUG] Last Event ${s+1}:`,{type:e.type,timestamp:e.timestamp,data_keys:e.data?Object.keys(e.data):"no data",full_event:e})})));for(let e=o.length-1;e>=0;e--){const n=o[e];if(n.data){if(console.log(`[DEBUG] Examining event ${e} data:`,n.data),s||(n.data.working_directory?(s=n.data.working_directory,console.log(`[DEBUG] Found working_directory: ${s}`)):n.data.cwd?(s=n.data.cwd,console.log(`[DEBUG] Found cwd: ${s}`)):n.data.instance_info&&n.data.instance_info.working_dir&&(s=n.data.instance_info.working_dir,console.log(`[DEBUG] Found instance_info.working_dir: ${s}`))),!t){const e=["git_branch","gitBranch","branch","git.branch","vcs_branch","current_branch"];for(const s of e)if(n.data[s]){t=n.data[s],console.log(`[DEBUG] Found git branch in field '${s}': ${t}`);break}if(!t){if(n.data.instance_info){console.log("[DEBUG] Checking instance_info for branch:",n.data.instance_info);for(const s of e)if(n.data.instance_info[s]){t=n.data.instance_info[s],console.log(`[DEBUG] Found git branch in instance_info.${s}: ${t}`);break}}!t&&n.data.git&&(console.log("[DEBUG] Checking git object:",n.data.git),n.data.git.branch&&(t=n.data.git.branch,console.log(`[DEBUG] Found git branch in git.branch: ${t}`)))}}if(s&&t){console.log("[DEBUG] Found both workingDir and gitBranch, stopping search");break}}}}else console.log("[DEBUG] No socket client or events available");return console.log(`[DEBUG] Final results - workingDir: '${s}', gitBranch: '${t}'`),{workingDir:s,gitBranch:t}}setCurrentSessionId(e){this.currentSessionId=e,this.updateSessionSelect(),this.updateFooterInfo()}addSession(e){if(!e.id)return;const s=this.sessions.get(e.id);s?Object.assign(s,e):this.sessions.set(e.id,{id:e.id,startTime:e.startTime||e.start_time||(new Date).toISOString(),lastActivity:e.lastActivity||e.last_activity||(new Date).toISOString(),eventCount:e.eventCount||e.event_count||0,working_directory:e.working_directory||e.workingDirectory||"",git_branch:e.git_branch||e.gitBranch||"",agent_type:e.agent_type||e.agentType||"",...e}),this.updateSessionSelect()}removeSession(e){if(this.sessions.has(e)){if(this.sessions.delete(e),this.selectedSessionId===e){this.selectedSessionId="";const e=document.getElementById("session-select");e&&(e.value=""),this.onSessionFilterChanged()}this.updateSessionSelect()}}getCurrentFilter(){return this.selectedSessionId}getSession(e){return this.sessions.get(e)||null}getAllSessions(){return this.sessions}getCurrentSessionId(){return this.currentSessionId}clearSessions(){this.sessions.clear(),this.currentSessionId=null,this.selectedSessionId="",this.updateSessionSelect(),this.updateFooterInfo()}exportSessionData(){return{sessions:Array.from(this.sessions.entries()),currentSessionId:this.currentSessionId,selectedSessionId:this.selectedSessionId}}importSessionData(e){e.sessions&&Array.isArray(e.sessions)&&(this.sessions.clear(),e.sessions.forEach(([e,s])=>{this.sessions.set(e,s)})),e.currentSessionId&&(this.currentSessionId=e.currentSessionId),void 0!==e.selectedSessionId&&(this.selectedSessionId=e.selectedSessionId),this.updateSessionSelect(),this.updateFooterInfo()}getEventsForSession(e){if(!e||!this.socketClient)return[];return(this.socketClient.events||[]).filter(s=>(s.session_id||s.data&&s.data.session_id||null)===e)}};
2
2
  //# sourceMappingURL=session-manager.js.map