claude-mpm 4.1.11__py3-none-any.whl → 4.1.13__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 (41) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/INSTRUCTIONS.md +8 -0
  3. claude_mpm/cli/__init__.py +1 -1
  4. claude_mpm/cli/commands/monitor.py +88 -627
  5. claude_mpm/cli/commands/mpm_init.py +127 -107
  6. claude_mpm/cli/commands/mpm_init_handler.py +24 -23
  7. claude_mpm/cli/parsers/mpm_init_parser.py +34 -28
  8. claude_mpm/core/config.py +18 -0
  9. claude_mpm/core/instruction_reinforcement_hook.py +266 -0
  10. claude_mpm/core/pm_hook_interceptor.py +105 -8
  11. claude_mpm/dashboard/static/built/components/activity-tree.js +1 -1
  12. claude_mpm/dashboard/static/built/components/code-tree.js +1 -1
  13. claude_mpm/dashboard/static/built/dashboard.js +1 -1
  14. claude_mpm/dashboard/static/built/socket-client.js +1 -1
  15. claude_mpm/dashboard/static/css/activity.css +1239 -267
  16. claude_mpm/dashboard/static/css/dashboard.css +511 -0
  17. claude_mpm/dashboard/static/dist/components/activity-tree.js +1 -1
  18. claude_mpm/dashboard/static/dist/components/code-tree.js +1 -1
  19. claude_mpm/dashboard/static/dist/components/module-viewer.js +1 -1
  20. claude_mpm/dashboard/static/dist/dashboard.js +1 -1
  21. claude_mpm/dashboard/static/dist/socket-client.js +1 -1
  22. claude_mpm/dashboard/static/js/components/activity-tree.js +1193 -892
  23. claude_mpm/dashboard/static/js/components/build-tracker.js +15 -13
  24. claude_mpm/dashboard/static/js/components/code-tree.js +534 -143
  25. claude_mpm/dashboard/static/js/components/module-viewer.js +21 -7
  26. claude_mpm/dashboard/static/js/components/unified-data-viewer.js +1066 -0
  27. claude_mpm/dashboard/static/js/connection-manager.js +1 -1
  28. claude_mpm/dashboard/static/js/dashboard.js +227 -84
  29. claude_mpm/dashboard/static/js/socket-client.js +2 -2
  30. claude_mpm/dashboard/templates/index.html +100 -23
  31. claude_mpm/services/agents/deployment/agent_template_builder.py +11 -7
  32. claude_mpm/services/cli/socketio_manager.py +39 -8
  33. claude_mpm/services/infrastructure/monitoring.py +1 -1
  34. claude_mpm/services/socketio/handlers/code_analysis.py +83 -136
  35. claude_mpm/tools/code_tree_analyzer.py +290 -202
  36. {claude_mpm-4.1.11.dist-info → claude_mpm-4.1.13.dist-info}/METADATA +1 -1
  37. {claude_mpm-4.1.11.dist-info → claude_mpm-4.1.13.dist-info}/RECORD +41 -39
  38. {claude_mpm-4.1.11.dist-info → claude_mpm-4.1.13.dist-info}/WHEEL +0 -0
  39. {claude_mpm-4.1.11.dist-info → claude_mpm-4.1.13.dist-info}/entry_points.txt +0 -0
  40. {claude_mpm-4.1.11.dist-info → claude_mpm-4.1.13.dist-info}/licenses/LICENSE +0 -0
  41. {claude_mpm-4.1.11.dist-info → claude_mpm-4.1.13.dist-info}/top_level.txt +0 -0
@@ -104,7 +104,7 @@ class EnhancedConnectionManager {
104
104
  timeout: 20000,
105
105
  transports: ['websocket', 'polling'],
106
106
  pingInterval: 25000,
107
- pingTimeout: 60000
107
+ pingTimeout: 20000
108
108
  });
109
109
 
110
110
  this.setupSocketHandlers();
@@ -26,6 +26,7 @@ import { ExportManager } from '@components/export-manager.js';
26
26
  import { WorkingDirectoryManager } from '@components/working-directory.js';
27
27
  import { FileToolTracker } from '@components/file-tool-tracker.js';
28
28
  import { BuildTracker } from '@components/build-tracker.js';
29
+ import { UnifiedDataViewer } from '@components/unified-data-viewer.js';
29
30
  class Dashboard {
30
31
  constructor() {
31
32
  // Core components (existing)
@@ -163,14 +164,22 @@ class Dashboard {
163
164
  // Set the socket client for receiving updates
164
165
  this.buildTracker.setSocketClient(this.socketClient);
165
166
 
166
- // Mount to header - find the best location
167
- const headerTitle = document.querySelector('.header-title');
168
- if (headerTitle) {
169
- // Insert after the title and status badge
170
- this.buildTracker.mount(headerTitle);
171
- } else {
172
- console.warn('Could not find header-title element for build tracker');
173
- }
167
+ // Mount to header with retry logic for DOM readiness
168
+ const mountBuildTracker = () => {
169
+ const headerTitle = document.querySelector('.header-title');
170
+ if (headerTitle) {
171
+ // Insert after the title and status badge
172
+ this.buildTracker.mount(headerTitle);
173
+ console.log('BuildTracker mounted successfully');
174
+ } else {
175
+ console.warn('Header-title element not found for build tracker, will retry');
176
+ // Retry after a short delay if DOM is still being constructed
177
+ setTimeout(mountBuildTracker, 100);
178
+ }
179
+ };
180
+
181
+ // Try to mount immediately, with retry logic if needed
182
+ mountBuildTracker();
174
183
 
175
184
  // Make available globally for debugging
176
185
  window.buildTracker = this.buildTracker;
@@ -445,7 +454,7 @@ class Dashboard {
445
454
  }
446
455
 
447
456
  /**
448
- * Render agents tab with hierarchical view
457
+ * Render agents tab with flat chronological view
449
458
  */
450
459
  renderAgents() {
451
460
  const agentsList = document.getElementById('agents-list');
@@ -455,17 +464,12 @@ class Dashboard {
455
464
  const searchText = document.getElementById('agents-search-input')?.value || '';
456
465
  const agentType = document.getElementById('agents-type-filter')?.value || '';
457
466
 
458
- // Build filters object
459
- const filters = {};
460
- if (searchText) filters.searchText = searchText;
461
- if (agentType) filters.agentType = agentType;
462
-
463
- // Generate hierarchical HTML
464
- const hierarchyHTML = this.agentHierarchy.render(filters);
465
- agentsList.innerHTML = hierarchyHTML;
467
+ // Generate flat HTML
468
+ const flatHTML = this.renderAgentsFlat(searchText, agentType);
469
+ agentsList.innerHTML = flatHTML;
466
470
 
467
- // Add expand/collapse all buttons if not present
468
- this.addHierarchyControls();
471
+ // Remove hierarchy controls if they exist
472
+ this.removeHierarchyControls();
469
473
 
470
474
  // Update filter dropdowns with available agent types
471
475
  const uniqueInstances = this.agentInference.getUniqueAgentInstances();
@@ -473,45 +477,202 @@ class Dashboard {
473
477
  }
474
478
 
475
479
  /**
476
- * Add hierarchy control buttons
480
+ * Remove hierarchy control buttons (flat view doesn't need them)
477
481
  */
478
- addHierarchyControls() {
479
- const tabFilters = document.querySelector('#agents-tab .tab-filters');
480
- if (!tabFilters) return;
481
-
482
- // Check if controls already exist
483
- if (document.getElementById('hierarchy-controls')) return;
482
+ removeHierarchyControls() {
483
+ const existingControls = document.getElementById('hierarchy-controls');
484
+ if (existingControls) {
485
+ existingControls.remove();
486
+ }
487
+ }
488
+
489
+ /**
490
+ * Render agents as a flat chronological list
491
+ * @param {string} searchText - Search filter
492
+ * @param {string} agentType - Agent type filter
493
+ * @returns {string} HTML for flat agent list
494
+ */
495
+ renderAgentsFlat(searchText, agentType) {
496
+ const events = this.eventViewer.events;
497
+ if (!events || events.length === 0) {
498
+ return '<div class="no-events">No agent events found...</div>';
499
+ }
484
500
 
485
- // Create control buttons
486
- const controls = document.createElement('div');
487
- controls.id = 'hierarchy-controls';
488
- controls.className = 'hierarchy-controls';
489
- controls.innerHTML = `
490
- <button data-action="expand-all"
491
- class="hierarchy-btn hierarchy-expand-all">
492
- Expand All
493
- </button>
494
- <button data-action="collapse-all"
495
- class="hierarchy-btn hierarchy-collapse-all">
496
- Collapse All
497
- </button>
498
- `;
501
+ // Process agent inference to get agent mappings
502
+ this.agentInference.processAgentInference();
503
+ const eventAgentMap = this.agentInference.getEventAgentMap();
499
504
 
500
- // Add safe event listeners
501
- controls.addEventListener('click', (event) => {
502
- const action = event.target.dataset.action;
503
- if (action && window.dashboard && window.dashboard.agentHierarchy) {
504
- if (action === 'expand-all') {
505
- window.dashboard.agentHierarchy.expandAllNodes();
506
- window.dashboard.renderAgents();
507
- } else if (action === 'collapse-all') {
508
- window.dashboard.agentHierarchy.collapseAllNodes();
509
- window.dashboard.renderAgents();
505
+ // Collect all agent events with metadata
506
+ const agentEvents = [];
507
+ events.forEach((event, index) => {
508
+ const inference = eventAgentMap.get(index);
509
+ if (inference && (inference.type === 'subagent' || inference.type === 'main_agent')) {
510
+ // Apply filters
511
+ let includeEvent = true;
512
+
513
+ if (searchText) {
514
+ const searchLower = searchText.toLowerCase();
515
+ includeEvent = includeEvent && (
516
+ inference.agentName.toLowerCase().includes(searchLower) ||
517
+ (event.tool_name && event.tool_name.toLowerCase().includes(searchLower)) ||
518
+ (event.data && JSON.stringify(event.data).toLowerCase().includes(searchLower))
519
+ );
520
+ }
521
+
522
+ if (agentType) {
523
+ includeEvent = includeEvent && inference.agentName.includes(agentType);
524
+ }
525
+
526
+ if (includeEvent) {
527
+ agentEvents.push({
528
+ event,
529
+ inference,
530
+ index,
531
+ timestamp: new Date(event.timestamp)
532
+ });
510
533
  }
511
534
  }
512
535
  });
513
536
 
514
- tabFilters.appendChild(controls);
537
+ if (agentEvents.length === 0) {
538
+ return '<div class="no-events">No agent events match the current filters...</div>';
539
+ }
540
+
541
+ // Generate HTML for each event
542
+ const html = agentEvents.map((item, listIndex) => {
543
+ const { event, inference, index, timestamp } = item;
544
+
545
+ // Determine action/tool
546
+ let action = 'Activity';
547
+ let actionIcon = '📋';
548
+ let details = '';
549
+
550
+ if (event.event_type === 'SubagentStart') {
551
+ action = 'Started';
552
+ actionIcon = '🟢';
553
+ details = 'Agent session began';
554
+ } else if (event.event_type === 'SubagentStop') {
555
+ action = 'Stopped';
556
+ actionIcon = '🔴';
557
+ details = 'Agent session ended';
558
+ } else if (event.tool_name) {
559
+ action = `Tool: ${event.tool_name}`;
560
+ actionIcon = this.getToolIcon(event.tool_name);
561
+
562
+ // Add tool parameters as details
563
+ if (event.data && event.data.tool_parameters) {
564
+ const params = event.data.tool_parameters;
565
+ if (params.file_path) {
566
+ details = params.file_path;
567
+ } else if (params.command) {
568
+ details = params.command.substring(0, 50) + (params.command.length > 50 ? '...' : '');
569
+ } else if (params.pattern) {
570
+ details = `pattern="${params.pattern}"`;
571
+ } else if (params.query) {
572
+ details = `query="${params.query}"`;
573
+ }
574
+ }
575
+ }
576
+
577
+ // Status based on event type
578
+ let status = 'completed';
579
+ if (event.event_type === 'SubagentStart') {
580
+ status = 'active';
581
+ } else if (event.data && event.data.error) {
582
+ status = 'error';
583
+ }
584
+
585
+ return `
586
+ <div class="agent-event-item" data-index="${listIndex}" onclick="window.dashboard.showCardDetails('agents', ${index})">
587
+ <div class="agent-event-header">
588
+ <div class="agent-event-time">${this.formatTimestamp(timestamp)}</div>
589
+ <div class="agent-event-agent">
590
+ ${this.getAgentIcon(inference.agentName)} ${inference.agentName}
591
+ </div>
592
+ <div class="agent-event-action">
593
+ ${actionIcon} ${action}
594
+ </div>
595
+ <div class="agent-event-status status-${status}">
596
+ ${this.getStatusIcon(status)}
597
+ </div>
598
+ </div>
599
+ ${details ? `<div class="agent-event-details">${this.escapeHtml(details)}</div>` : ''}
600
+ </div>
601
+ `;
602
+ }).join('');
603
+
604
+ return `<div class="agent-events-flat">${html}</div>`;
605
+ }
606
+
607
+ /**
608
+ * Get icon for agent type
609
+ */
610
+ getAgentIcon(agentName) {
611
+ const agentIcons = {
612
+ 'PM': '🎯',
613
+ 'Engineer Agent': '🔧',
614
+ 'Research Agent': '🔍',
615
+ 'QA Agent': '✅',
616
+ 'Documentation Agent': '📝',
617
+ 'Security Agent': '🔒',
618
+ 'Ops Agent': '⚙️',
619
+ 'Version Control Agent': '📦',
620
+ 'Data Engineer Agent': '💾',
621
+ 'Test Integration Agent': '🧪'
622
+ };
623
+ return agentIcons[agentName] || '🤖';
624
+ }
625
+
626
+ /**
627
+ * Get icon for tool
628
+ */
629
+ getToolIcon(toolName) {
630
+ const toolIcons = {
631
+ 'Read': '📖',
632
+ 'Write': '✏️',
633
+ 'Edit': '📝',
634
+ 'Bash': '💻',
635
+ 'Grep': '🔍',
636
+ 'Glob': '📂',
637
+ 'LS': '📁',
638
+ 'Task': '📋'
639
+ };
640
+ return toolIcons[toolName] || '🔧';
641
+ }
642
+
643
+ /**
644
+ * Get icon for status
645
+ */
646
+ getStatusIcon(status) {
647
+ const statusIcons = {
648
+ 'active': '🟢',
649
+ 'completed': '✅',
650
+ 'error': '❌',
651
+ 'pending': '🟡'
652
+ };
653
+ return statusIcons[status] || '❓';
654
+ }
655
+
656
+ /**
657
+ * Format timestamp for display
658
+ */
659
+ formatTimestamp(timestamp) {
660
+ return timestamp.toLocaleTimeString('en-US', {
661
+ hour: '2-digit',
662
+ minute: '2-digit',
663
+ second: '2-digit',
664
+ hour12: false
665
+ });
666
+ }
667
+
668
+ /**
669
+ * Escape HTML for safe display
670
+ */
671
+ escapeHtml(text) {
672
+ if (!text) return '';
673
+ const div = document.createElement('div');
674
+ div.textContent = text;
675
+ return div.innerHTML;
515
676
  }
516
677
 
517
678
  /**
@@ -1080,14 +1241,11 @@ async function updateFileViewerModal(modal, filePath, workingDir) {
1080
1241
  working_dir: workingDir
1081
1242
  });
1082
1243
 
1083
- console.log('📄 File viewer request sent:', {
1084
- filePath,
1085
- workingDir
1086
- });
1244
+ // File viewer request sent
1087
1245
 
1088
1246
  // Wait for response
1089
1247
  const result = await responsePromise;
1090
- console.log('📦 File content received:', result);
1248
+ // File content received successfully
1091
1249
 
1092
1250
  // Hide loading
1093
1251
  modal.querySelector('.file-viewer-loading').style.display = 'none';
@@ -1143,7 +1301,7 @@ async function updateFileViewerModal(modal, filePath, workingDir) {
1143
1301
  }
1144
1302
 
1145
1303
  function displayFileContent(modal, result) {
1146
- console.log('📝 displayFileContent called with:', result);
1304
+ // Display file content in modal
1147
1305
  const contentArea = modal.querySelector('.file-viewer-content-area');
1148
1306
  const extensionElement = modal.querySelector('.file-extension');
1149
1307
  const encodingElement = modal.querySelector('.file-encoding');
@@ -1157,7 +1315,7 @@ function displayFileContent(modal, result) {
1157
1315
 
1158
1316
  // Update content with basic syntax highlighting
1159
1317
  if (codeElement && result.content) {
1160
- console.log('💡 Setting file content, length:', result.content.length);
1318
+ // Setting file content
1161
1319
  codeElement.innerHTML = highlightCode(result.content, result.extension);
1162
1320
 
1163
1321
  // Force scrolling to work by setting explicit heights
@@ -1175,12 +1333,7 @@ function displayFileContent(modal, result) {
1175
1333
 
1176
1334
  const availableHeight = modalHeight - headerHeight - toolbarHeight - 40; // 40px for padding
1177
1335
 
1178
- console.log('🎯 Setting file viewer scroll height:', {
1179
- modalHeight,
1180
- headerHeight,
1181
- toolbarHeight,
1182
- availableHeight
1183
- });
1336
+ // Setting file viewer scroll height
1184
1337
 
1185
1338
  wrapper.style.maxHeight = `${availableHeight}px`;
1186
1339
  wrapper.style.overflowY = 'auto';
@@ -1193,7 +1346,7 @@ function displayFileContent(modal, result) {
1193
1346
  // Show content area
1194
1347
  if (contentArea) {
1195
1348
  contentArea.style.display = 'block';
1196
- console.log('✅ File content area displayed');
1349
+ // File content area displayed
1197
1350
  }
1198
1351
  }
1199
1352
 
@@ -1533,7 +1686,7 @@ async function updateGitDiffModal(modal, filePath, timestamp, workingDir) {
1533
1686
  throw new Error(`Server health check failed: ${healthResponse.status} ${healthResponse.statusText}`);
1534
1687
  }
1535
1688
 
1536
- console.log('✅ Server health check passed');
1689
+ // Server health check passed
1537
1690
  } catch (healthError) {
1538
1691
  throw new Error(`Cannot reach server at localhost:${port}. Health check failed: ${healthError.message}`);
1539
1692
  }
@@ -1553,17 +1706,17 @@ async function updateGitDiffModal(modal, filePath, timestamp, workingDir) {
1553
1706
  }
1554
1707
 
1555
1708
  const result = await response.json();
1556
- console.log('📦 Git diff response:', result);
1709
+ // Git diff response received
1557
1710
 
1558
1711
  // Hide loading
1559
1712
  modal.querySelector('.git-diff-loading').style.display = 'none';
1560
1713
 
1561
1714
  if (result.success) {
1562
- console.log('📊 Displaying successful git diff');
1715
+ // Displaying successful git diff
1563
1716
  // Show successful diff
1564
1717
  displayGitDiff(modal, result);
1565
1718
  } else {
1566
- console.log('⚠️ Displaying git diff error:', result);
1719
+ // Displaying git diff error
1567
1720
  // Show error
1568
1721
  displayGitDiffError(modal, result);
1569
1722
  }
@@ -1661,18 +1814,13 @@ function highlightGitDiff(diffText) {
1661
1814
  }
1662
1815
 
1663
1816
  function displayGitDiff(modal, result) {
1664
- console.log('📝 displayGitDiff called with:', result);
1817
+ // Display git diff content
1665
1818
  const contentArea = modal.querySelector('.git-diff-content-area');
1666
1819
  const commitHashElement = modal.querySelector('.commit-hash');
1667
1820
  const methodElement = modal.querySelector('.diff-method');
1668
1821
  const codeElement = modal.querySelector('.git-diff-code');
1669
1822
 
1670
- console.log('🔍 Elements found:', {
1671
- contentArea: !!contentArea,
1672
- commitHashElement: !!commitHashElement,
1673
- methodElement: !!methodElement,
1674
- codeElement: !!codeElement
1675
- });
1823
+ // Elements found for diff display
1676
1824
 
1677
1825
  // Update metadata
1678
1826
  if (commitHashElement) commitHashElement.textContent = `Commit: ${result.commit_hash}`;
@@ -1680,7 +1828,7 @@ function displayGitDiff(modal, result) {
1680
1828
 
1681
1829
  // Update diff content with basic syntax highlighting
1682
1830
  if (codeElement && result.diff) {
1683
- console.log('💡 Setting diff content, length:', result.diff.length);
1831
+ // Setting diff content
1684
1832
  codeElement.innerHTML = highlightGitDiff(result.diff);
1685
1833
 
1686
1834
  // Force scrolling to work by setting explicit heights
@@ -1698,12 +1846,7 @@ function displayGitDiff(modal, result) {
1698
1846
 
1699
1847
  const availableHeight = modalHeight - headerHeight - toolbarHeight - 40; // 40px for padding
1700
1848
 
1701
- console.log('🎯 Setting explicit scroll height:', {
1702
- modalHeight,
1703
- headerHeight,
1704
- toolbarHeight,
1705
- availableHeight
1706
- });
1849
+ // Setting explicit scroll height
1707
1850
 
1708
1851
  wrapper.style.maxHeight = `${availableHeight}px`;
1709
1852
  wrapper.style.overflowY = 'auto';
@@ -1716,7 +1859,7 @@ function displayGitDiff(modal, result) {
1716
1859
  // Show content area
1717
1860
  if (contentArea) {
1718
1861
  contentArea.style.display = 'block';
1719
- console.log('✅ Content area displayed');
1862
+ // Content area displayed
1720
1863
  }
1721
1864
  }
1722
1865
 
@@ -315,7 +315,7 @@ class SocketClient {
315
315
  * Configuration Details:
316
316
  * - autoConnect: true - Immediate connection attempt
317
317
  * - reconnection: true - Built-in reconnection enabled
318
- * - pingInterval: 45000ms - Matches server configuration
318
+ * - pingInterval: 25000ms - Matches server configuration
319
319
  * - pingTimeout: 20000ms - Health check timeout
320
320
  * - transports: ['websocket', 'polling'] - Fallback options
321
321
  *
@@ -351,7 +351,7 @@ class SocketClient {
351
351
  timeout: 20000, // Connection timeout
352
352
  forceNew: true,
353
353
  transports: ['websocket', 'polling'],
354
- pingInterval: 45000, // CRITICAL: Must match server's 45 seconds
354
+ pingInterval: 25000, // CRITICAL: Must match server's 25 seconds
355
355
  pingTimeout: 20000 // CRITICAL: Must match server's 20 seconds
356
356
  });
357
357
 
@@ -331,7 +331,6 @@
331
331
  <div class="activity-controls">
332
332
  <button id="expand-all" class="btn-sm">Expand All</button>
333
333
  <button id="collapse-all" class="btn-sm">Collapse All</button>
334
- <button id="reset-zoom" class="btn-sm">Reset Zoom</button>
335
334
  <select id="time-range">
336
335
  <option value="all">All Time</option>
337
336
  <option value="hour">Last Hour</option>
@@ -359,24 +358,24 @@
359
358
  <div id="activity-tree"></div>
360
359
  <div class="tree-legend">
361
360
  <div class="legend-item">
362
- <span class="legend-icon pm">●</span>
363
- <span>PM</span>
361
+ <span class="legend-icon">📁</span>
362
+ <span>Project Root</span>
364
363
  </div>
365
364
  <div class="legend-item">
366
- <span class="legend-icon todowrite">■</span>
367
- <span>TodoWrite</span>
365
+ <span class="legend-icon pm">🎯</span>
366
+ <span>PM Session</span>
368
367
  </div>
369
368
  <div class="legend-item">
370
- <span class="legend-icon agent">●</span>
371
- <span>Agent</span>
369
+ <span class="legend-icon todowrite">📝</span>
370
+ <span>Todo Item</span>
372
371
  </div>
373
372
  <div class="legend-item">
374
- <span class="legend-icon tool">●</span>
375
- <span>Tool</span>
373
+ <span class="legend-icon agent">🤖</span>
374
+ <span>Agent</span>
376
375
  </div>
377
376
  <div class="legend-item">
378
- <span class="legend-icon file">●</span>
379
- <span>File/Command</span>
377
+ <span class="legend-icon tool">🔧</span>
378
+ <span>Tool</span>
380
379
  </div>
381
380
  </div>
382
381
  </div>
@@ -425,9 +424,6 @@
425
424
  <div class="option-group">
426
425
  <label>Ignore: <input type="text" id="ignore-patterns" placeholder="test*, *.spec.js, node_modules" class="input-compact" style="width: 200px;"></label>
427
426
  </div>
428
- <div class="option-group">
429
- <label><input type="checkbox" id="show-hidden-files"> Show hidden files (dotfiles)</label>
430
- </div>
431
427
  </div>
432
428
  </div>
433
429
  <div id="code-tree-container" class="code-tree-container">
@@ -513,14 +509,95 @@
513
509
  </div>
514
510
 
515
511
  <!-- JavaScript Modules -->
516
- <!-- Load bundled dashboard assets (built with Vite) -->
517
- <script type="module" src="/static/dist/dashboard.js"></script>
518
-
519
- <!-- Activity Tree Module (from Vite build) -->
520
- <script type="module" src="/static/dist/components/activity-tree.js"></script>
521
-
522
- <!-- Code Tree Module (from Vite build) -->
523
- <script type="module" src="/static/dist/components/code-tree.js"></script>
524
- <script type="module" src="/static/dist/components/code-viewer.js"></script>
512
+ <!-- Load bundled dashboard assets (built with Vite) - with proper initialization order -->
513
+ <script type="module">
514
+ // Add timestamp-based cache busting and ensure proper loading order
515
+ const timestamp = Date.now();
516
+
517
+ // Load modules sequentially to ensure dashboard.js loads first
518
+ const loadModule = (src) => {
519
+ return new Promise((resolve, reject) => {
520
+ const script = document.createElement('script');
521
+ script.type = 'module';
522
+ script.src = `${src}?t=${timestamp}`;
523
+ script.onload = resolve;
524
+ script.onerror = reject;
525
+ document.body.appendChild(script);
526
+ });
527
+ };
528
+
529
+ // Load dashboard.js first, then other components
530
+ Promise.all([
531
+ loadModule('/static/dist/dashboard.js'),
532
+ loadModule('/static/dist/components/activity-tree.js'),
533
+ loadModule('/static/dist/components/code-tree.js'),
534
+ loadModule('/static/dist/components/code-viewer.js')
535
+ ]).then(() => {
536
+ console.log('All dashboard modules loaded successfully');
537
+
538
+ // Give modules time to execute and initialize dashboard
539
+ setTimeout(() => {
540
+ console.log('Checking dashboard initialization...');
541
+
542
+ if (window.dashboard) {
543
+ console.log('Dashboard found, checking auto-connect status...');
544
+
545
+ // Force auto-connect if not already connected
546
+ if (window.dashboard.socketManager) {
547
+ const socketManager = window.dashboard.socketManager;
548
+
549
+ if (!socketManager.isConnected() && !socketManager.isConnecting()) {
550
+ console.log('Dashboard loaded but not connected, forcing auto-connect...');
551
+
552
+ // Try to trigger auto-connect manually
553
+ const params = new URLSearchParams(window.location.search);
554
+ socketManager.initializeFromURL(params);
555
+ } else {
556
+ console.log('Dashboard already connected or connecting');
557
+ }
558
+ } else {
559
+ console.warn('Dashboard found but socketManager not available');
560
+ }
561
+ } else {
562
+ console.warn('Dashboard still not initialized after module loading');
563
+
564
+ // Try to manually trigger initialization
565
+ if (document.readyState === 'complete' || document.readyState === 'interactive') {
566
+ console.log('Document ready, attempting to trigger dashboard initialization...');
567
+ document.dispatchEvent(new Event('DOMContentLoaded'));
568
+ }
569
+ }
570
+
571
+ // Debug: Test connection settings button
572
+ const connectionToggleBtn = document.getElementById('connection-toggle-btn');
573
+ if (connectionToggleBtn) {
574
+ console.log('Connection toggle button found, testing functionality...');
575
+
576
+ // Add a debug click handler to ensure the button works
577
+ connectionToggleBtn.addEventListener('click', () => {
578
+ console.log('Connection toggle button clicked (debug handler)');
579
+
580
+ if (window.dashboard && window.dashboard.socketManager) {
581
+ console.log('Calling socketManager.toggleConnectionControls()');
582
+ window.dashboard.socketManager.toggleConnectionControls();
583
+ } else {
584
+ console.log('Manual toggle fallback');
585
+ const controlsRow = document.getElementById('connection-controls-row');
586
+ if (controlsRow) {
587
+ const isVisible = controlsRow.style.display !== 'none';
588
+ controlsRow.style.display = isVisible ? 'none' : 'block';
589
+ connectionToggleBtn.textContent = isVisible ? 'Connection Settings' : 'Hide Settings';
590
+ console.log(`Manually toggled controls visibility: ${!isVisible}`);
591
+ }
592
+ }
593
+ });
594
+ } else {
595
+ console.error('Connection toggle button not found in DOM');
596
+ }
597
+ }, 1000);
598
+ }).catch(error => {
599
+ console.error('Failed to load dashboard modules:', error);
600
+ });
601
+ </script>
525
602
  </body>
526
603
  </html>
@@ -190,7 +190,17 @@ class AgentTemplateBuilder:
190
190
  # Include tools field only if agent is clearly restricted (missing core tools or very few tools)
191
191
  include_tools_field = not has_core_tools or len(agent_tools) < 6
192
192
 
193
- # Build YAML frontmatter using Claude Code's working format + our custom fields
193
+ # Build YAML frontmatter using Claude Code's minimal format
194
+ # ONLY include fields that Claude Code recognizes
195
+ #
196
+ # REMOVED FIELDS for Claude Code compatibility:
197
+ # - model, color, version, type, source, author
198
+ # These fields caused Claude Code to silently fail agent discovery
199
+ #
200
+ # CLAUDE CODE COMPATIBLE FORMAT:
201
+ # - name: kebab-case agent name (required)
202
+ # - description: when/why to use this agent (required)
203
+ # - tools: comma-separated tool list (optional, only if restricting)
194
204
  frontmatter_lines = [
195
205
  "---",
196
206
  f"name: {claude_code_name}",
@@ -203,12 +213,6 @@ class AgentTemplateBuilder:
203
213
 
204
214
  frontmatter_lines.extend(
205
215
  [
206
- f"model: {model_type}", # Use explicit model type instead of inherit
207
- f"color: {color}",
208
- f"version: {agent_version}",
209
- f"type: {agent_type}",
210
- f"source: {source_info}", # Track which source provided this agent
211
- "author: claude-mpm", # Mark as system-managed agent
212
216
  "---",
213
217
  "",
214
218
  ]