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.
- claude_mpm/VERSION +1 -1
- claude_mpm/agents/INSTRUCTIONS.md +8 -0
- claude_mpm/cli/__init__.py +1 -1
- claude_mpm/cli/commands/monitor.py +88 -627
- claude_mpm/cli/commands/mpm_init.py +127 -107
- claude_mpm/cli/commands/mpm_init_handler.py +24 -23
- claude_mpm/cli/parsers/mpm_init_parser.py +34 -28
- claude_mpm/core/config.py +18 -0
- claude_mpm/core/instruction_reinforcement_hook.py +266 -0
- claude_mpm/core/pm_hook_interceptor.py +105 -8
- claude_mpm/dashboard/static/built/components/activity-tree.js +1 -1
- claude_mpm/dashboard/static/built/components/code-tree.js +1 -1
- claude_mpm/dashboard/static/built/dashboard.js +1 -1
- claude_mpm/dashboard/static/built/socket-client.js +1 -1
- claude_mpm/dashboard/static/css/activity.css +1239 -267
- claude_mpm/dashboard/static/css/dashboard.css +511 -0
- claude_mpm/dashboard/static/dist/components/activity-tree.js +1 -1
- claude_mpm/dashboard/static/dist/components/code-tree.js +1 -1
- claude_mpm/dashboard/static/dist/components/module-viewer.js +1 -1
- claude_mpm/dashboard/static/dist/dashboard.js +1 -1
- claude_mpm/dashboard/static/dist/socket-client.js +1 -1
- claude_mpm/dashboard/static/js/components/activity-tree.js +1193 -892
- claude_mpm/dashboard/static/js/components/build-tracker.js +15 -13
- claude_mpm/dashboard/static/js/components/code-tree.js +534 -143
- claude_mpm/dashboard/static/js/components/module-viewer.js +21 -7
- claude_mpm/dashboard/static/js/components/unified-data-viewer.js +1066 -0
- claude_mpm/dashboard/static/js/connection-manager.js +1 -1
- claude_mpm/dashboard/static/js/dashboard.js +227 -84
- claude_mpm/dashboard/static/js/socket-client.js +2 -2
- claude_mpm/dashboard/templates/index.html +100 -23
- claude_mpm/services/agents/deployment/agent_template_builder.py +11 -7
- claude_mpm/services/cli/socketio_manager.py +39 -8
- claude_mpm/services/infrastructure/monitoring.py +1 -1
- claude_mpm/services/socketio/handlers/code_analysis.py +83 -136
- claude_mpm/tools/code_tree_analyzer.py +290 -202
- {claude_mpm-4.1.11.dist-info → claude_mpm-4.1.13.dist-info}/METADATA +1 -1
- {claude_mpm-4.1.11.dist-info → claude_mpm-4.1.13.dist-info}/RECORD +41 -39
- {claude_mpm-4.1.11.dist-info → claude_mpm-4.1.13.dist-info}/WHEEL +0 -0
- {claude_mpm-4.1.11.dist-info → claude_mpm-4.1.13.dist-info}/entry_points.txt +0 -0
- {claude_mpm-4.1.11.dist-info → claude_mpm-4.1.13.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-4.1.11.dist-info → claude_mpm-4.1.13.dist-info}/top_level.txt +0 -0
|
@@ -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
|
|
167
|
-
const
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
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
|
|
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
|
-
//
|
|
459
|
-
const
|
|
460
|
-
|
|
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
|
-
//
|
|
468
|
-
this.
|
|
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
|
-
*
|
|
480
|
+
* Remove hierarchy control buttons (flat view doesn't need them)
|
|
477
481
|
*/
|
|
478
|
-
|
|
479
|
-
const
|
|
480
|
-
if (
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
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
|
-
//
|
|
486
|
-
|
|
487
|
-
|
|
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
|
-
//
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1084
|
-
filePath,
|
|
1085
|
-
workingDir
|
|
1086
|
-
});
|
|
1244
|
+
// File viewer request sent
|
|
1087
1245
|
|
|
1088
1246
|
// Wait for response
|
|
1089
1247
|
const result = await responsePromise;
|
|
1090
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1715
|
+
// Displaying successful git diff
|
|
1563
1716
|
// Show successful diff
|
|
1564
1717
|
displayGitDiff(modal, result);
|
|
1565
1718
|
} else {
|
|
1566
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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:
|
|
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:
|
|
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
|
|
363
|
-
<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
|
|
367
|
-
<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
|
|
371
|
-
<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
|
|
375
|
-
<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
|
|
379
|
-
<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"
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
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
|
|
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
|
]
|