claude-mpm 4.1.10__py3-none-any.whl → 4.1.11__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 (48) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/cli/__init__.py +11 -0
  3. claude_mpm/cli/commands/analyze.py +2 -1
  4. claude_mpm/cli/commands/configure.py +9 -8
  5. claude_mpm/cli/commands/configure_tui.py +3 -1
  6. claude_mpm/cli/commands/dashboard.py +288 -0
  7. claude_mpm/cli/commands/debug.py +0 -1
  8. claude_mpm/cli/commands/mpm_init.py +427 -0
  9. claude_mpm/cli/commands/mpm_init_handler.py +83 -0
  10. claude_mpm/cli/parsers/base_parser.py +15 -0
  11. claude_mpm/cli/parsers/dashboard_parser.py +113 -0
  12. claude_mpm/cli/parsers/mpm_init_parser.py +122 -0
  13. claude_mpm/constants.py +10 -0
  14. claude_mpm/dashboard/analysis_runner.py +52 -25
  15. claude_mpm/dashboard/static/built/components/activity-tree.js +1 -1
  16. claude_mpm/dashboard/static/built/components/code-tree.js +2 -0
  17. claude_mpm/dashboard/static/built/components/code-viewer.js +2 -0
  18. claude_mpm/dashboard/static/built/components/event-viewer.js +1 -1
  19. claude_mpm/dashboard/static/built/dashboard.js +1 -1
  20. claude_mpm/dashboard/static/built/socket-client.js +1 -1
  21. claude_mpm/dashboard/static/css/code-tree.css +330 -1
  22. claude_mpm/dashboard/static/dist/components/activity-tree.js +1 -1
  23. claude_mpm/dashboard/static/dist/components/code-tree.js +1 -1
  24. claude_mpm/dashboard/static/dist/components/event-viewer.js +1 -1
  25. claude_mpm/dashboard/static/dist/dashboard.js +1 -1
  26. claude_mpm/dashboard/static/dist/socket-client.js +1 -1
  27. claude_mpm/dashboard/static/js/components/activity-tree.js +212 -13
  28. claude_mpm/dashboard/static/js/components/code-tree.js +1999 -821
  29. claude_mpm/dashboard/static/js/components/event-viewer.js +58 -19
  30. claude_mpm/dashboard/static/js/dashboard.js +15 -3
  31. claude_mpm/dashboard/static/js/socket-client.js +74 -32
  32. claude_mpm/dashboard/templates/index.html +9 -11
  33. claude_mpm/services/agents/memory/memory_format_service.py +3 -1
  34. claude_mpm/services/cli/agent_cleanup_service.py +1 -4
  35. claude_mpm/services/cli/startup_checker.py +0 -1
  36. claude_mpm/services/core/cache_manager.py +0 -1
  37. claude_mpm/services/socketio/event_normalizer.py +64 -0
  38. claude_mpm/services/socketio/handlers/code_analysis.py +502 -0
  39. claude_mpm/services/socketio/server/connection_manager.py +3 -1
  40. claude_mpm/tools/code_tree_analyzer.py +843 -25
  41. claude_mpm/tools/code_tree_builder.py +0 -1
  42. claude_mpm/tools/code_tree_events.py +113 -15
  43. {claude_mpm-4.1.10.dist-info → claude_mpm-4.1.11.dist-info}/METADATA +2 -1
  44. {claude_mpm-4.1.10.dist-info → claude_mpm-4.1.11.dist-info}/RECORD +48 -41
  45. {claude_mpm-4.1.10.dist-info → claude_mpm-4.1.11.dist-info}/WHEEL +0 -0
  46. {claude_mpm-4.1.10.dist-info → claude_mpm-4.1.11.dist-info}/entry_points.txt +0 -0
  47. {claude_mpm-4.1.10.dist-info → claude_mpm-4.1.11.dist-info}/licenses/LICENSE +0 -0
  48. {claude_mpm-4.1.10.dist-info → claude_mpm-4.1.11.dist-info}/top_level.txt +0 -0
@@ -51,6 +51,12 @@ class ActivityTree {
51
51
  }
52
52
  }
53
53
 
54
+ // Clear any existing text content that might be in the container
55
+ if (this.container.textContent && this.container.textContent.trim()) {
56
+ console.log('Clearing existing text content from container:', this.container.textContent);
57
+ this.container.textContent = '';
58
+ }
59
+
54
60
  console.log('Activity tree container found:', this.container);
55
61
 
56
62
  // Check if the container is visible before initializing
@@ -63,6 +69,10 @@ class ActivityTree {
63
69
  // Initialize even if tab is not active, but don't render until visible
64
70
  if (!tabPanel.classList.contains('active')) {
65
71
  console.log('Activity tab not active, initializing but deferring render');
72
+ // Clear any text content that might be showing
73
+ if (this.container.textContent && this.container.textContent.trim()) {
74
+ this.container.textContent = '';
75
+ }
66
76
  // Set up basic structure but defer visualization
67
77
  this.setupControls();
68
78
  this.initializeTreeData();
@@ -71,28 +81,97 @@ class ActivityTree {
71
81
  return;
72
82
  }
73
83
 
84
+ // Clear container before creating visualization
85
+ if (this.container.textContent && this.container.textContent.trim()) {
86
+ console.log('Clearing container text before creating visualization');
87
+ this.container.textContent = '';
88
+ }
89
+
74
90
  this.setupControls();
75
91
  this.createVisualization();
76
92
 
77
93
  if (!this.svg || !this.treeGroup) {
78
94
  console.error('Failed to create D3 visualization elements');
95
+ // Show error message in container
96
+ if (this.container) {
97
+ this.container.innerHTML = '<div style="padding: 20px; text-align: center; color: #e53e3e;">⚠️ Failed to create visualization. Please refresh the page.</div>';
98
+ }
79
99
  return;
80
100
  }
81
101
 
82
102
  this.initializeTreeData();
83
- this.update(this.root);
103
+
104
+ // Only update if we have a valid root
105
+ if (this.root) {
106
+ this.update(this.root);
107
+ } else {
108
+ console.warn('Root not created, skipping initial update');
109
+ }
110
+
84
111
  this.subscribeToEvents();
85
112
 
86
113
  this.initialized = true;
87
114
  console.log('Activity tree initialization complete');
88
115
  }
89
116
 
117
+ /**
118
+ * Force show the tree visualization
119
+ */
120
+ forceShow() {
121
+ console.log('ActivityTree.forceShow() called');
122
+
123
+ // Ensure container is available
124
+ if (!this.container) {
125
+ this.container = document.getElementById('activity-tree-container') || document.getElementById('activity-tree');
126
+ if (!this.container) {
127
+ console.error('Cannot find activity tree container');
128
+ return;
129
+ }
130
+ }
131
+
132
+ // Clear any text content
133
+ if (this.container.textContent && this.container.textContent.trim()) {
134
+ console.log('Clearing text from container:', this.container.textContent);
135
+ this.container.innerHTML = '';
136
+ }
137
+
138
+ // Create visualization if needed
139
+ if (!this.svg) {
140
+ this.createVisualization();
141
+ }
142
+
143
+ // Initialize tree data if needed
144
+ if (!this.root) {
145
+ this.initializeTreeData();
146
+ }
147
+
148
+ // Update the tree
149
+ if (this.root && this.svg && this.treeGroup) {
150
+ this.update(this.root);
151
+ }
152
+
153
+ // Ensure the SVG is visible
154
+ if (this.svg) {
155
+ const svgNode = this.svg.node();
156
+ if (svgNode) {
157
+ svgNode.style.display = 'block';
158
+ svgNode.style.visibility = 'visible';
159
+ }
160
+ }
161
+ }
162
+
90
163
  /**
91
164
  * Render the visualization when tab becomes visible (called when switching to Activity tab)
92
165
  */
93
166
  renderWhenVisible() {
94
167
  console.log('ActivityTree.renderWhenVisible() called');
95
168
 
169
+ // Ensure the container is clean
170
+ if (this.container && this.container.textContent && this.container.textContent.trim() && !this.svg) {
171
+ console.log('Clearing text content before rendering:', this.container.textContent);
172
+ this.container.textContent = '';
173
+ }
174
+
96
175
  if (!this.initialized) {
97
176
  console.log('Not initialized yet, calling initialize...');
98
177
  this.initialize();
@@ -103,8 +182,14 @@ class ActivityTree {
103
182
  if (!this.svg) {
104
183
  console.log('Creating deferred visualization...');
105
184
  this.createVisualization();
106
- if (this.svg && this.treeGroup) {
185
+ if (this.svg && this.treeGroup && this.root) {
107
186
  this.update(this.root);
187
+ } else if (!this.root) {
188
+ console.warn('No root node available, initializing tree data...');
189
+ this.initializeTreeData();
190
+ if (this.root && this.svg && this.treeGroup) {
191
+ this.update(this.root);
192
+ }
108
193
  }
109
194
  }
110
195
 
@@ -112,6 +197,12 @@ class ActivityTree {
112
197
  if (this.root && this.svg) {
113
198
  console.log('Updating tree with current data...');
114
199
  this.update(this.root);
200
+ } else {
201
+ console.warn('Cannot update tree - missing components:', {
202
+ hasRoot: !!this.root,
203
+ hasSvg: !!this.svg,
204
+ hasTreeGroup: !!this.treeGroup
205
+ });
115
206
  }
116
207
  }
117
208
 
@@ -163,6 +254,10 @@ class ActivityTree {
163
254
  // Check if D3 is available
164
255
  if (typeof d3 === 'undefined') {
165
256
  console.error('D3.js is not loaded! Cannot create activity tree visualization.');
257
+ // Try to display an error message in the container
258
+ if (this.container) {
259
+ this.container.innerHTML = '<div style="padding: 20px; text-align: center; color: #e53e3e;">⚠️ D3.js is not loaded. Cannot create visualization.</div>';
260
+ }
166
261
  return;
167
262
  }
168
263
 
@@ -173,8 +268,8 @@ class ActivityTree {
173
268
 
174
269
  console.log('Creating D3 visualization with dimensions:', { width: this.width, height: this.height });
175
270
 
176
- // Clear any existing SVG
177
- d3.select(this.container).select('svg').remove();
271
+ // Clear any existing content (including text)
272
+ d3.select(this.container).selectAll('*').remove();
178
273
 
179
274
  // Create SVG
180
275
  this.svg = d3.select(this.container)
@@ -230,6 +325,10 @@ class ActivityTree {
230
325
  // Check if D3 is available
231
326
  if (typeof d3 === 'undefined') {
232
327
  console.error('ActivityTree: D3 is not available - cannot create hierarchy!');
328
+ // Try to display an error message
329
+ if (this.container) {
330
+ this.container.innerHTML = '<div style="padding: 20px; text-align: center; color: #e53e3e;">⚠️ Waiting for D3.js to load...</div>';
331
+ }
233
332
  return;
234
333
  }
235
334
 
@@ -238,6 +337,9 @@ class ActivityTree {
238
337
  this.root.y0 = 0;
239
338
 
240
339
  console.log('ActivityTree: Root node created:', this.root);
340
+
341
+ // Update stats immediately after creating root
342
+ this.updateStats();
241
343
  }
242
344
 
243
345
  /**
@@ -665,23 +767,74 @@ class ActivityTree {
665
767
  update(source) {
666
768
  console.log('ActivityTree: update() called with source:', source);
667
769
 
770
+ // Check if D3 is available
771
+ if (typeof d3 === 'undefined') {
772
+ console.error('ActivityTree: Cannot update - D3.js not loaded');
773
+ return;
774
+ }
775
+
668
776
  // Check if visualization is ready
669
777
  if (!this.svg || !this.treeGroup) {
670
778
  console.warn('ActivityTree: Cannot update - SVG not initialized');
671
- return;
779
+ // Try to create visualization if container exists
780
+ if (this.container) {
781
+ console.log('Attempting to create visualization from update()');
782
+ this.createVisualization();
783
+ // Check again after creation attempt
784
+ if (!this.svg || !this.treeGroup) {
785
+ console.error('Failed to create visualization in update()');
786
+ return;
787
+ }
788
+ } else {
789
+ return;
790
+ }
672
791
  }
673
792
 
674
793
  if (!this.treeLayout) {
675
794
  console.warn('ActivityTree: Cannot update - tree layout not initialized');
795
+ // Try to create tree layout
796
+ if (typeof d3 !== 'undefined') {
797
+ this.treeLayout = d3.tree().size([this.height, this.width]);
798
+ console.log('Created tree layout in update()');
799
+ } else {
800
+ return;
801
+ }
802
+ }
803
+
804
+ // Ensure source has valid data
805
+ if (!source || !source.data) {
806
+ console.error('ActivityTree: Invalid source in update()', source);
807
+ return;
808
+ }
809
+
810
+ // Ensure we have a valid root
811
+ if (!this.root) {
812
+ console.error('ActivityTree: No root node available for update');
676
813
  return;
677
814
  }
678
815
 
679
816
  // Compute the new tree layout
680
- const treeData = this.treeLayout(this.root);
817
+ let treeData;
818
+ try {
819
+ treeData = this.treeLayout(this.root);
820
+ } catch (error) {
821
+ console.error('ActivityTree: Error computing tree layout:', error);
822
+ return;
823
+ }
824
+
681
825
  const nodes = treeData.descendants();
682
826
  const links = treeData.links();
683
827
 
684
828
  console.log(`ActivityTree: Updating tree with ${nodes.length} nodes`);
829
+
830
+ // Check if we actually have the tree container
831
+ if (nodes.length === 1 && this.container) {
832
+ // Only root node exists, ensure container shows the tree
833
+ const svgElement = this.container.querySelector('svg');
834
+ if (!svgElement) {
835
+ console.warn('SVG element not found in container after update');
836
+ }
837
+ }
685
838
 
686
839
  // Normalize for fixed-depth
687
840
  nodes.forEach((d) => {
@@ -969,13 +1122,33 @@ class ActivityTree {
969
1122
  * Update statistics
970
1123
  */
971
1124
  updateStats() {
1125
+ // Check if we have a valid root node
1126
+ if (!this.root || !this.root.data) {
1127
+ console.warn('ActivityTree: Cannot update stats - root not initialized');
1128
+ // Set default values
1129
+ const nodeCountEl = document.getElementById('node-count');
1130
+ const activeCountEl = document.getElementById('active-count');
1131
+ const depthEl = document.getElementById('tree-depth');
1132
+
1133
+ if (nodeCountEl) nodeCountEl.textContent = '1';
1134
+ if (activeCountEl) activeCountEl.textContent = '0';
1135
+ if (depthEl) depthEl.textContent = '0';
1136
+ return;
1137
+ }
1138
+
972
1139
  const nodeCount = this.countNodes(this.root);
973
1140
  const activeCount = this.countActiveNodes(this.root.data);
974
1141
  const depth = this.getTreeDepth(this.root);
975
1142
 
976
- document.getElementById('node-count').textContent = nodeCount;
977
- document.getElementById('active-count').textContent = activeCount;
978
- document.getElementById('tree-depth').textContent = depth;
1143
+ const nodeCountEl = document.getElementById('node-count');
1144
+ const activeCountEl = document.getElementById('active-count');
1145
+ const depthEl = document.getElementById('tree-depth');
1146
+
1147
+ if (nodeCountEl) nodeCountEl.textContent = nodeCount;
1148
+ if (activeCountEl) activeCountEl.textContent = activeCount;
1149
+ if (depthEl) depthEl.textContent = depth;
1150
+
1151
+ console.log(`ActivityTree: Stats updated - Nodes: ${nodeCount}, Active: ${activeCount}, Depth: ${depth}`);
979
1152
  }
980
1153
 
981
1154
  /**
@@ -1081,6 +1254,14 @@ const setupActivityTreeListeners = () => {
1081
1254
  // Store instance globally for dashboard access
1082
1255
  window.activityTreeInstance = activityTree;
1083
1256
  }
1257
+
1258
+ // Ensure the container is ready and clear any text
1259
+ const container = document.getElementById('activity-tree-container') || document.getElementById('activity-tree');
1260
+ if (container && container.textContent && container.textContent.trim()) {
1261
+ console.log('Clearing text from activity tree container before init:', container.textContent);
1262
+ container.textContent = '';
1263
+ }
1264
+
1084
1265
  // Always try to initialize when tab becomes active, even if instance exists
1085
1266
  // Small delay to ensure DOM is ready and tab is visible
1086
1267
  setTimeout(() => {
@@ -1097,9 +1278,13 @@ const setupActivityTreeListeners = () => {
1097
1278
  if (tabName === 'activity') {
1098
1279
  console.log('Activity tab button clicked, initializing tree...');
1099
1280
  initializeActivityTree();
1100
- // Also call renderWhenVisible to ensure proper rendering
1281
+ // Also call renderWhenVisible and forceShow to ensure proper rendering
1101
1282
  if (activityTree) {
1102
- setTimeout(() => activityTree.renderWhenVisible(), 150);
1283
+ setTimeout(() => {
1284
+ activityTree.renderWhenVisible();
1285
+ // Force show to ensure SVG is visible
1286
+ activityTree.forceShow();
1287
+ }, 150);
1103
1288
  }
1104
1289
  }
1105
1290
  });
@@ -1110,9 +1295,13 @@ const setupActivityTreeListeners = () => {
1110
1295
  if (e.detail && e.detail.newTab === 'activity') {
1111
1296
  console.log('Tab changed to activity, initializing tree...');
1112
1297
  initializeActivityTree();
1113
- // Also call renderWhenVisible to ensure proper rendering
1298
+ // Also call renderWhenVisible and forceShow to ensure proper rendering
1114
1299
  if (activityTree) {
1115
- setTimeout(() => activityTree.renderWhenVisible(), 150);
1300
+ setTimeout(() => {
1301
+ activityTree.renderWhenVisible();
1302
+ // Force show to ensure SVG is visible
1303
+ activityTree.forceShow();
1304
+ }, 150);
1116
1305
  }
1117
1306
  }
1118
1307
  });
@@ -1120,8 +1309,18 @@ const setupActivityTreeListeners = () => {
1120
1309
  // Check if activity tab is already active on load
1121
1310
  const activeTab = document.querySelector('.tab-button.active');
1122
1311
  if (activeTab && activeTab.getAttribute('data-tab') === 'activity') {
1312
+ console.log('Activity tab is active on load, initializing tree...');
1123
1313
  initializeActivityTree();
1124
1314
  }
1315
+
1316
+ // Also check the tab panel directly
1317
+ const activityPanel = document.getElementById('activity-tab');
1318
+ if (activityPanel && activityPanel.classList.contains('active')) {
1319
+ console.log('Activity panel is active on load, initializing tree...');
1320
+ if (!activityTree) {
1321
+ initializeActivityTree();
1322
+ }
1323
+ }
1125
1324
 
1126
1325
  // Export for debugging
1127
1326
  window.activityTree = () => activityTree; // Expose instance getter for debugging