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
@@ -30,19 +30,33 @@ class CodeViewer {
30
30
  * Initialize the code viewer
31
31
  */
32
32
  initialize() {
33
+ console.log('[CodeViewer] initialize() called');
33
34
  if (this.initialized) {
34
35
  console.log('[CodeViewer] Already initialized, skipping');
35
36
  return;
36
37
  }
37
38
 
38
- console.log('[CodeViewer] Initializing...');
39
- this.setupContainer();
40
- this.setupEventHandlers();
41
- this.subscribeToEvents();
42
- this.processExistingEvents();
43
-
44
- this.initialized = true;
45
- console.log('[CodeViewer] Code Viewer (File Activity Tree) initialized successfully');
39
+ console.log('[CodeViewer] Starting initialization...');
40
+ try {
41
+ // Initialize components
42
+ this.setupContainer();
43
+ console.log('[CodeViewer] Container setup complete');
44
+
45
+ this.setupEventHandlers();
46
+ console.log('[CodeViewer] Event handlers setup complete');
47
+
48
+ this.subscribeToEvents();
49
+ console.log('[CodeViewer] Event subscription complete');
50
+
51
+ this.processExistingEvents();
52
+ console.log('[CodeViewer] Existing events processed');
53
+
54
+ this.initialized = true;
55
+ console.log('[CodeViewer] Initialization complete!');
56
+ } catch (error) {
57
+ console.error('[CodeViewer] Error during initialization:', error);
58
+ throw error;
59
+ }
46
60
  }
47
61
 
48
62
  /**
@@ -74,20 +88,96 @@ class CodeViewer {
74
88
 
75
89
  // Prevent concurrent renders
76
90
  if (this.renderInProgress) {
77
- console.log('[CodeViewer] Render already in progress, skipping');
78
91
  return;
79
92
  }
80
93
 
81
94
  // Check if interface already exists and is intact
82
95
  const existingWrapper = this.container.querySelector('.activity-tree-wrapper');
96
+ const existingEmptyState = this.container.querySelector('.file-tree-empty-state');
83
97
  const existingSvg = this.container.querySelector('#claude-activity-tree-svg');
98
+
99
+ // Always show the tree interface, even if empty
100
+ // We'll show at least a session root node
101
+ // Remove the empty state check - we always want the tree
102
+ if (false) { // Disabled empty state - always show tree
103
+ // Only render empty state if it doesn't exist
104
+ if (!existingEmptyState) {
105
+ this.renderInProgress = true;
106
+
107
+ // Temporarily disconnect observer to prevent loops
108
+ if (this.containerObserver) {
109
+ this.containerObserver.disconnect();
110
+ }
111
+
112
+ // Clear any existing content completely
113
+ this.container.innerHTML = '';
114
+
115
+ // Show empty state
116
+ this.container.innerHTML = `
117
+ <div class="file-tree-empty-state" style="
118
+ text-align: center;
119
+ padding: 50px 20px;
120
+ color: #666;
121
+ font-family: monospace;
122
+ height: 100%;
123
+ display: flex;
124
+ flex-direction: column;
125
+ justify-content: center;
126
+ align-items: center;
127
+ background: #fafafa;
128
+ ">
129
+ <h2 style="color: #333; margin-bottom: 20px; font-size: 24px;">
130
+ 📁 File Activity Tree
131
+ </h2>
132
+ <p style="margin-bottom: 15px; font-size: 16px;">
133
+ No file operations recorded yet.
134
+ </p>
135
+ <p style="font-size: 14px; color: #888;">
136
+ The tree will appear here when files are:
137
+ </p>
138
+ <ul style="
139
+ list-style: none;
140
+ padding: 20px 30px;
141
+ text-align: left;
142
+ display: inline-block;
143
+ background: white;
144
+ border: 1px solid #e0e0e0;
145
+ border-radius: 5px;
146
+ margin-top: 10px;
147
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
148
+ ">
149
+ <li style="margin: 8px 0;">📖 Read (using Read tool)</li>
150
+ <li style="margin: 8px 0;">✏️ Edited (using Edit tool)</li>
151
+ <li style="margin: 8px 0;">💾 Written (using Write tool)</li>
152
+ <li style="margin: 8px 0;">📝 Multi-edited (using MultiEdit tool)</li>
153
+ <li style="margin: 8px 0;">📓 Notebook edited (using NotebookEdit tool)</li>
154
+ </ul>
155
+ <p style="margin-top: 20px; font-size: 12px; color: #999;">
156
+ D3.js tree visualization will render automatically when file operations occur
157
+ </p>
158
+ </div>
159
+ `;
160
+
161
+ // Mark render as complete and re-enable observer if needed
162
+ this.renderInProgress = false;
163
+
164
+ // Re-enable container protection after render
165
+ if (this.containerObserver && this.container) {
166
+ this.containerObserver.observe(this.container, {
167
+ childList: true,
168
+ subtree: false // Only watch direct children, not subtree
169
+ });
170
+ }
171
+ }
172
+ return;
173
+ }
174
+
175
+ // If we have file activity and the interface already exists, skip
84
176
  if (existingWrapper && existingSvg) {
85
- console.log('[CodeViewer] Interface already exists and is intact, skipping render');
86
177
  return;
87
178
  }
88
179
 
89
180
  this.renderInProgress = true;
90
- console.log('[CodeViewer] Rendering interface in container:', this.container.id);
91
181
 
92
182
  // Temporarily disconnect observer to prevent loops
93
183
  if (this.containerObserver) {
@@ -145,7 +235,6 @@ class CodeViewer {
145
235
  * This is called by UIStateManager when the tab is already active
146
236
  */
147
237
  renderContent() {
148
- console.log('[CodeViewer] renderContent() called');
149
238
  this._showInternal();
150
239
  }
151
240
 
@@ -154,7 +243,6 @@ class CodeViewer {
154
243
  * Note: Tab switching is now handled by UIStateManager
155
244
  */
156
245
  show() {
157
- console.log('[CodeViewer] show() called');
158
246
  this._showInternal();
159
247
  }
160
248
 
@@ -162,6 +250,7 @@ class CodeViewer {
162
250
  * Internal show implementation (without tab switching)
163
251
  */
164
252
  _showInternal() {
253
+ console.log('[CodeViewer] _showInternal() called');
165
254
 
166
255
  // Get the file tree container
167
256
  const claudeTreeContainer = document.getElementById('claude-tree-container');
@@ -170,6 +259,37 @@ class CodeViewer {
170
259
  return;
171
260
  }
172
261
 
262
+ console.log('[CodeViewer] Found container, current HTML length:', claudeTreeContainer.innerHTML.length);
263
+ console.log('[CodeViewer] Container children:', claudeTreeContainer.children.length);
264
+
265
+ // Refresh from FileToolTracker to get latest data
266
+ this.refreshFromFileToolTracker();
267
+
268
+ // CRITICAL: Clear any foreign content first - more aggressive cleanup
269
+ const foreignSelectors = [
270
+ '#events-list',
271
+ '.events-list',
272
+ '.event-item',
273
+ '.no-events',
274
+ '[id*="event"]',
275
+ '[class*="event"]'
276
+ ];
277
+
278
+ let foundForeign = false;
279
+ foreignSelectors.forEach(selector => {
280
+ const elements = claudeTreeContainer.querySelectorAll(selector);
281
+ if (elements.length > 0) {
282
+ console.warn(`[CodeViewer] Found ${elements.length} foreign elements matching '${selector}', removing...`);
283
+ elements.forEach(el => el.remove());
284
+ foundForeign = true;
285
+ }
286
+ });
287
+
288
+ if (foundForeign) {
289
+ console.warn('[CodeViewer] Foreign content removed, clearing container completely for fresh start');
290
+ claudeTreeContainer.innerHTML = '';
291
+ }
292
+
173
293
  // CRITICAL: Prevent other components from writing to this container
174
294
  // Add multiple attributes to mark ownership strongly
175
295
  claudeTreeContainer.setAttribute('data-owner', 'code-viewer');
@@ -185,10 +305,10 @@ class CodeViewer {
185
305
  if (!this.initialized) {
186
306
  this.initialize();
187
307
  } else {
188
- // Only render interface if it doesn't exist
308
+ // Always render interface - it will handle empty state or tree as needed
189
309
  const existingWrapper = this.container.querySelector('.activity-tree-wrapper');
190
- if (!existingWrapper) {
191
- console.log('[CodeViewer] Interface missing, rendering...');
310
+ const existingEmptyState = this.container.querySelector('.file-tree-empty-state');
311
+ if (!existingWrapper && !existingEmptyState) {
192
312
  this.renderInterface();
193
313
  }
194
314
  }
@@ -198,7 +318,8 @@ class CodeViewer {
198
318
  this.protectContainer();
199
319
  }
200
320
 
201
- // Setup event handlers for the new controls
321
+ // Always setup event handlers and render tree
322
+ // Even with no file activity, we show a session root
202
323
  this.setupControlHandlers();
203
324
 
204
325
  // Get current session from main selector
@@ -207,14 +328,12 @@ class CodeViewer {
207
328
  this.currentSession = mainSessionSelect.value || null;
208
329
  }
209
330
 
210
- // Build and render tree
331
+ // Build and render tree (will create minimal session root if no data)
211
332
  this.buildTreeData();
212
333
  this.renderTree();
213
334
 
214
335
  // Update stats
215
336
  this.updateStats();
216
-
217
- console.log('[CodeViewer] show() completed, container should now have tree interface');
218
337
  }
219
338
 
220
339
  /**
@@ -240,33 +359,39 @@ class CodeViewer {
240
359
  if (node.nodeType === Node.ELEMENT_NODE) {
241
360
  const element = node;
242
361
 
243
- // AGGRESSIVE filtering: Block ANY content that's not our tree interface
362
+ // AGGRESSIVE filtering: Block ANY content that's not our tree interface or empty state
244
363
  const isUnwantedContent = (
245
364
  element.classList?.contains('event-item') ||
246
365
  element.classList?.contains('events-list') ||
247
366
  element.classList?.contains('no-events') ||
248
367
  element.id === 'events-list' ||
368
+ element.id === 'agents-list' ||
369
+ element.id === 'tools-list' ||
370
+ element.id === 'files-list' ||
249
371
  (element.textContent && (
250
372
  element.textContent.includes('[hook]') ||
251
373
  element.textContent.includes('hook.user_prompt') ||
252
374
  element.textContent.includes('hook.pre_tool') ||
253
375
  element.textContent.includes('hook.post_tool') ||
254
376
  element.textContent.includes('Connect to Socket.IO') ||
255
- element.textContent.includes('No events')
377
+ element.textContent.includes('No events') ||
378
+ element.textContent.includes('No agent events') ||
379
+ element.textContent.includes('No tool events') ||
380
+ element.textContent.includes('No file operations')
256
381
  )) ||
257
382
  // Block any div without our expected classes
258
383
  (element.tagName === 'DIV' &&
259
384
  !element.classList?.contains('activity-tree-wrapper') &&
385
+ !element.classList?.contains('file-tree-empty-state') &&
260
386
  !element.classList?.contains('activity-controls') &&
261
387
  !element.classList?.contains('tree-container') &&
262
388
  !element.classList?.contains('legend') &&
389
+ !element.classList?.contains('stats') &&
263
390
  !element.id?.startsWith('claude-'))
264
391
  );
265
392
 
266
393
  if (isUnwantedContent) {
267
- console.warn('[CodeViewer] BLOCKED unwanted content in File Tree container:', element);
268
- console.warn('[CodeViewer] Element classes:', element.classList?.toString());
269
- console.warn('[CodeViewer] Element text preview:', element.textContent?.substring(0, 100));
394
+ // Block unwanted content silently
270
395
 
271
396
  // Remove the unwanted content immediately
272
397
  try {
@@ -280,9 +405,11 @@ class CodeViewer {
280
405
  reRenderScheduled = true;
281
406
  setTimeout(() => {
282
407
  reRenderScheduled = false;
283
- if (!container.querySelector('.activity-tree-wrapper')) {
284
- console.log('[CodeViewer] Re-rendering interface after blocking unwanted content');
408
+ if (!container.querySelector('.activity-tree-wrapper') &&
409
+ !container.querySelector('.file-tree-empty-state')) {
285
410
  this.renderInterface();
411
+
412
+ // Always setup controls and tree (even if no file activity)
286
413
  this.setupControlHandlers();
287
414
  this.buildTreeData();
288
415
  this.renderTree();
@@ -298,13 +425,15 @@ class CodeViewer {
298
425
  for (const node of mutation.removedNodes) {
299
426
  if (node.nodeType === Node.ELEMENT_NODE) {
300
427
  const element = node;
301
- if (element.classList?.contains('activity-tree-wrapper')) {
302
- console.warn('[CodeViewer] Our tree interface was removed! Re-rendering...');
428
+ if (element.classList?.contains('activity-tree-wrapper') ||
429
+ element.classList?.contains('file-tree-empty-state')) {
303
430
  if (!reRenderScheduled && !this.renderInProgress) {
304
431
  reRenderScheduled = true;
305
432
  setTimeout(() => {
306
433
  reRenderScheduled = false;
307
434
  this.renderInterface();
435
+
436
+ // Always setup controls and tree (even if no file activity)
308
437
  this.setupControlHandlers();
309
438
  this.buildTreeData();
310
439
  this.renderTree();
@@ -322,8 +451,6 @@ class CodeViewer {
322
451
  childList: true,
323
452
  subtree: false // Only watch direct children, not entire subtree
324
453
  });
325
-
326
- console.log('[CodeViewer] Container protection enabled with aggressive filtering');
327
454
  }
328
455
 
329
456
  /**
@@ -336,7 +463,6 @@ class CodeViewer {
336
463
  mainSessionSelect.setAttribute('data-tree-listener', 'true');
337
464
  mainSessionSelect.addEventListener('change', (e) => {
338
465
  this.currentSession = e.target.value || null;
339
- console.log('[CodeViewer] Session changed to:', this.currentSession);
340
466
  if (this.isTabActive()) {
341
467
  this.buildTreeData();
342
468
  this.renderTree();
@@ -387,33 +513,32 @@ class CodeViewer {
387
513
  // Listen for claude events from socket
388
514
  if (window.socket) {
389
515
  window.socket.on('claude_event', (event) => {
390
- console.log('[CodeViewer] Received claude_event:', event);
391
-
392
- // Process both hook events and direct file operation events
516
+
517
+ // When we get file operation events, refresh from FileToolTracker
393
518
  if (this.isFileOperationEvent(event) || this.isDirectFileEvent(event)) {
394
- this.processClaudeEvent(event);
395
- // Only update if the File Tree tab is active
396
- if (this.isTabActive()) {
397
- this.buildTreeData();
398
- this.renderTree();
399
- this.updateStats();
400
- }
519
+ // Let FileToolTracker process the event first, then refresh our view
520
+ setTimeout(() => {
521
+ this.refreshFromFileToolTracker();
522
+ // Only update if the File Tree tab is active
523
+ if (this.isTabActive()) {
524
+ this.buildTreeData();
525
+ this.renderTree();
526
+ this.updateStats();
527
+ }
528
+ }, 100);
401
529
  }
402
530
  });
403
531
 
404
532
  // Also listen for specific file events
405
533
  window.socket.on('file:read', (data) => {
406
- console.log('[CodeViewer] Received file:read event:', data);
407
534
  this.handleDirectFileEvent('Read', data);
408
535
  });
409
536
 
410
537
  window.socket.on('file:write', (data) => {
411
- console.log('[CodeViewer] Received file:write event:', data);
412
538
  this.handleDirectFileEvent('Write', data);
413
539
  });
414
540
 
415
541
  window.socket.on('file:edit', (data) => {
416
- console.log('[CodeViewer] Received file:edit event:', data);
417
542
  this.handleDirectFileEvent('Edit', data);
418
543
  });
419
544
  }
@@ -421,7 +546,6 @@ class CodeViewer {
421
546
  // Listen for events from event bus
422
547
  if (window.eventBus) {
423
548
  window.eventBus.on('claude_event', (event) => {
424
- console.log('[CodeViewer] Received claude_event from eventBus:', event);
425
549
 
426
550
  // Process both hook events and direct file operation events
427
551
  if (this.isFileOperationEvent(event) || this.isDirectFileEvent(event)) {
@@ -449,13 +573,48 @@ class CodeViewer {
449
573
  * Process existing events from dashboard
450
574
  */
451
575
  processExistingEvents() {
576
+ console.log('[CodeViewer] processExistingEvents called');
577
+
578
+ // First try to use FileToolTracker data if available
579
+ if (window.dashboard && window.dashboard.fileToolTracker) {
580
+ this.refreshFromFileToolTracker();
581
+ return;
582
+ }
583
+
584
+ // Fallback to event store if FileToolTracker not available
452
585
  if (window.dashboard && window.dashboard.eventStore) {
453
586
  const events = window.dashboard.eventStore.getAllEvents();
587
+ console.log('[CodeViewer] Fallback to eventStore, total events:', events.length);
588
+
589
+ let fileOpCount = 0;
590
+ let processedCount = 0;
591
+
454
592
  events.forEach(event => {
593
+ // Log detailed info about each event for debugging
594
+ if (event.type === 'hook') {
595
+ console.log('[CodeViewer] Hook event:', {
596
+ subtype: event.subtype,
597
+ tool_name: event.data?.tool_name,
598
+ timestamp: event.timestamp
599
+ });
600
+ }
601
+
455
602
  if (this.isFileOperationEvent(event)) {
603
+ fileOpCount++;
604
+ console.log('[CodeViewer] Found file operation event:', event);
456
605
  this.processClaudeEvent(event);
606
+ processedCount++;
457
607
  }
458
608
  });
609
+
610
+ console.log('[CodeViewer] processExistingEvents summary:', {
611
+ totalEvents: events.length,
612
+ fileOperations: fileOpCount,
613
+ processed: processedCount,
614
+ currentFileActivitySize: this.fileActivity.size
615
+ });
616
+ } else {
617
+ console.log('[CodeViewer] No dashboard or eventStore available');
459
618
  }
460
619
  }
461
620
 
@@ -502,7 +661,6 @@ class CodeViewer {
502
661
  timestamp: data.timestamp || new Date().toISOString()
503
662
  };
504
663
 
505
- console.log('[CodeViewer] Processing direct file event:', event);
506
664
  this.processClaudeEvent(event);
507
665
 
508
666
  // Only update if the File Tree tab is active
@@ -553,8 +711,6 @@ class CodeViewer {
553
711
 
554
712
  filePath = tool_parameters.file_path || tool_parameters.notebook_path;
555
713
 
556
- console.log('[CodeViewer] Processing file operation:', tool_name, filePath);
557
-
558
714
  this.processFileOperation({
559
715
  tool_name,
560
716
  tool_parameters,
@@ -654,8 +810,6 @@ class CodeViewer {
654
810
  activity.astPaths = this.extractASTPaths(activity.lastContent, filePath);
655
811
  }
656
812
  }
657
-
658
- console.log('[CodeViewer] File activity updated:', filePath, 'Total files:', this.fileActivity.size)
659
813
  }
660
814
 
661
815
  /**
@@ -711,12 +865,30 @@ class CodeViewer {
711
865
  * Build tree data from file activity
712
866
  */
713
867
  buildTreeData() {
868
+ // Get current session info
869
+ const sessionId = this.currentSession || 'current-session';
870
+ const sessionName = sessionId.substring(0, 8) + '...';
871
+
872
+ // Always create a root with at least the session node
714
873
  const root = {
715
- name: 'File Activity',
874
+ name: `Session: ${sessionName}`,
716
875
  type: 'root',
717
876
  children: []
718
877
  };
719
878
 
879
+ // If no file activity, still show the session root
880
+ if (!this.fileActivity || this.fileActivity.size === 0) {
881
+ // Add a placeholder node to indicate no files yet
882
+ root.children.push({
883
+ name: '(No file operations yet)',
884
+ type: 'placeholder',
885
+ children: []
886
+ });
887
+ this.treeData = root;
888
+ console.log('[CodeViewer] Built minimal tree with session root');
889
+ return;
890
+ }
891
+
720
892
  // Group by working directory
721
893
  const dirMap = new Map();
722
894
 
@@ -1094,38 +1266,105 @@ class CodeViewer {
1094
1266
 
1095
1267
  stats.textContent = `Files: ${totalFiles} | Operations: ${totalOps} | Sessions: ${this.sessions.size}`;
1096
1268
  }
1269
+
1270
+ /**
1271
+ * Refresh file activity from FileToolTracker
1272
+ */
1273
+ refreshFromFileToolTracker() {
1274
+ if (!window.dashboard || !window.dashboard.fileToolTracker) {
1275
+ console.log('[CodeViewer] FileToolTracker not available');
1276
+ return;
1277
+ }
1278
+
1279
+ const fileOperations = window.dashboard.fileToolTracker.getFileOperations();
1280
+ console.log('[CodeViewer] Refreshing from FileToolTracker:', fileOperations.size, 'files');
1281
+
1282
+ // Clear existing file activity
1283
+ this.fileActivity.clear();
1284
+ this.sessions.clear();
1285
+
1286
+ // Create a default session if needed
1287
+ const defaultSessionId = 'current-session';
1288
+ this.sessions.set(defaultSessionId, {
1289
+ id: defaultSessionId,
1290
+ startTime: new Date().toISOString(),
1291
+ files: new Set()
1292
+ });
1293
+ this.currentSession = defaultSessionId;
1294
+
1295
+ // Convert fileOperations Map to file activity for tree visualization
1296
+ fileOperations.forEach((fileData, filePath) => {
1297
+ // Add file to session
1298
+ const session = this.sessions.get(defaultSessionId);
1299
+ session.files.add(filePath);
1300
+
1301
+ // Create file activity entry
1302
+ const firstOp = fileData.operations[0];
1303
+ const lastOp = fileData.operations[fileData.operations.length - 1];
1304
+
1305
+ this.fileActivity.set(filePath, {
1306
+ path: filePath,
1307
+ firstAccess: firstOp ? firstOp.timestamp : fileData.lastOperation,
1308
+ lastAccess: fileData.lastOperation,
1309
+ accessCount: fileData.operations.length,
1310
+ operations: fileData.operations.map(op => ({
1311
+ type: op.operation,
1312
+ timestamp: op.timestamp,
1313
+ agent: op.agent
1314
+ })),
1315
+ workingDirectory: firstOp ? firstOp.workingDirectory : null,
1316
+ astNodes: [],
1317
+ content: null
1318
+ });
1319
+ });
1320
+
1321
+ console.log('[CodeViewer] File activity refreshed:', this.fileActivity.size, 'files');
1322
+ }
1097
1323
  }
1098
1324
 
1099
1325
  // Create and export singleton instance
1100
- window.CodeViewer = new CodeViewer();
1326
+ try {
1327
+ window.CodeViewer = new CodeViewer();
1328
+ console.log('[CodeViewer] Instance created successfully');
1329
+ } catch (error) {
1330
+ console.error('[CodeViewer] FAILED TO CREATE INSTANCE:', error);
1331
+ }
1101
1332
 
1102
1333
  // Auto-initialize when DOM is ready
1103
1334
  if (document.readyState === 'loading') {
1104
1335
  document.addEventListener('DOMContentLoaded', () => {
1336
+ console.log('[CodeViewer] DOMContentLoaded - attempting initialization');
1337
+ try {
1338
+ window.CodeViewer.initialize();
1339
+
1340
+ // If File Tree tab is already active, show it
1341
+ const claudeTreeTab = document.getElementById('claude-tree-tab');
1342
+ if (claudeTreeTab && claudeTreeTab.classList.contains('active')) {
1343
+ setTimeout(() => window.CodeViewer.show(), 100);
1344
+ }
1345
+ } catch (error) {
1346
+ console.error('[CodeViewer] FAILED TO INITIALIZE:', error);
1347
+ }
1348
+ });
1349
+ } else {
1350
+ console.log('[CodeViewer] DOM already loaded - initializing immediately');
1351
+ try {
1105
1352
  window.CodeViewer.initialize();
1106
1353
 
1107
1354
  // If File Tree tab is already active, show it
1108
1355
  const claudeTreeTab = document.getElementById('claude-tree-tab');
1109
1356
  if (claudeTreeTab && claudeTreeTab.classList.contains('active')) {
1110
- console.log('[CodeViewer] File Tree tab is active on load, showing tree...');
1357
+ console.log('[CodeViewer] File Tree tab is active, showing in 100ms');
1111
1358
  setTimeout(() => window.CodeViewer.show(), 100);
1112
1359
  }
1113
- });
1114
- } else {
1115
- window.CodeViewer.initialize();
1116
-
1117
- // If File Tree tab is already active, show it
1118
- const claudeTreeTab = document.getElementById('claude-tree-tab');
1119
- if (claudeTreeTab && claudeTreeTab.classList.contains('active')) {
1120
- console.log('[CodeViewer] File Tree tab is active, showing tree...');
1121
- setTimeout(() => window.CodeViewer.show(), 100);
1360
+ } catch (error) {
1361
+ console.error('[CodeViewer] FAILED TO INITIALIZE:', error);
1122
1362
  }
1123
1363
  }
1124
1364
 
1125
1365
  // Also listen for tab changes to ensure we render when needed
1126
1366
  document.addEventListener('tabChanged', (event) => {
1127
1367
  if (event.detail && event.detail.newTab === 'claude-tree') {
1128
- console.log('[CodeViewer] Tab changed to File Tree, forcing show...');
1129
1368
  setTimeout(() => window.CodeViewer.show(), 50);
1130
1369
  }
1131
1370
  });
@@ -1139,8 +1378,9 @@ setInterval(() => {
1139
1378
  const claudeTreeContainer = document.getElementById('claude-tree-container');
1140
1379
 
1141
1380
  if (claudeTreeTab && claudeTreeTab.classList.contains('active') &&
1142
- claudeTreeContainer && !claudeTreeContainer.querySelector('.activity-tree-wrapper')) {
1143
- console.log('[CodeViewer] Periodic check: File Tree tab is active but not properly rendered, fixing...');
1381
+ claudeTreeContainer &&
1382
+ !claudeTreeContainer.querySelector('.activity-tree-wrapper') &&
1383
+ !claudeTreeContainer.querySelector('.file-tree-empty-state')) {
1144
1384
  window.CodeViewer.show();
1145
1385
  }
1146
1386
  }, 5000);
@@ -537,3 +537,6 @@ class EventProcessor {
537
537
  // ES6 Module export
538
538
  export { EventProcessor };
539
539
  export default EventProcessor;
540
+
541
+ // Make EventProcessor globally available for dist/dashboard.js
542
+ window.EventProcessor = EventProcessor;