- Create agent-evolution/ directory with standalone dashboard - Add interactive HTML dashboard with agent/model matrix - Add heatmap view for agent-model compatibility scores - Add recommendations tab with optimization suggestions - Add Gitea integration preparation (history timeline) - Add Docker configuration for deployment - Add build scripts for standalone HTML generation - Add sync scripts for agent data synchronization - Add milestone and issues documentation - Add skills and rules for evolution sync - Update AGENTS.md with dashboard documentation - Update package.json with evolution scripts Features: - 28 agents with model assignments and fit scores - 8 models with benchmarks (SWE-bench, RULER, Terminal) - 11 recommendations for model optimization - History timeline with agent changes - Interactive modal windows for model details - Filter and search functionality - Russian language interface - Works offline (file://) with embedded data Docker: - Dockerfile for standalone deployment - docker-compose.evolution.yml - docker-run.sh/docker-run.bat scripts NPM scripts: - sync:evolution - sync and build dashboard - evolution:open - open in browser - evolution:dashboard - start dev server Status: PAUSED - foundation complete, Gitea integration pending
117 lines
4.2 KiB
JavaScript
117 lines
4.2 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* Build standalone HTML with embedded data
|
|
* Run: node agent-evolution/scripts/build-standalone.cjs
|
|
*/
|
|
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
const DATA_FILE = path.join(__dirname, '../data/agent-versions.json');
|
|
const HTML_FILE = path.join(__dirname, '../index.html');
|
|
const OUTPUT_FILE = path.join(__dirname, '../index.standalone.html');
|
|
|
|
try {
|
|
// Read data
|
|
console.log('📖 Reading data from:', DATA_FILE);
|
|
const data = JSON.parse(fs.readFileSync(DATA_FILE, 'utf-8'));
|
|
console.log(' Found', Object.keys(data.agents).length, 'agents');
|
|
|
|
// Read HTML
|
|
console.log('📖 Reading HTML from:', HTML_FILE);
|
|
let html = fs.readFileSync(HTML_FILE, 'utf-8');
|
|
|
|
// Step 1: Replace EMBEDDED_DATA
|
|
const startMarker = '// Default embedded data (minimal - updated by sync script)';
|
|
const endPattern = /"sync_sources":\s*\[[^\]]*\]\s*\}\s*\};/;
|
|
|
|
const startIdx = html.indexOf(startMarker);
|
|
const endMatch = html.match(endPattern);
|
|
|
|
if (startIdx === -1) {
|
|
throw new Error('Start marker not found in HTML');
|
|
}
|
|
if (!endMatch) {
|
|
throw new Error('End pattern not found in HTML');
|
|
}
|
|
|
|
const endIdx = endMatch.index + endMatch[0].length + 1;
|
|
|
|
// Create embedded data
|
|
const embeddedData = `// Embedded data (generated ${new Date().toISOString()})
|
|
const EMBEDDED_DATA = ${JSON.stringify(data, null, 2)};`;
|
|
|
|
// Replace the section
|
|
html = html.substring(0, startIdx) + embeddedData + html.substring(endIdx);
|
|
|
|
// Step 2: Replace entire init function
|
|
// Find the init function start and end
|
|
const initStartPattern = /\/\/ Initialize\s*\n\s*async function init\(\) \{/;
|
|
const initStartMatch = html.match(initStartPattern);
|
|
|
|
if (initStartMatch) {
|
|
const initStartIdx = initStartMatch.index;
|
|
|
|
// Find matching closing brace (count opening and closing)
|
|
let braceCount = 0;
|
|
let inFunction = false;
|
|
let initEndIdx = initStartIdx;
|
|
|
|
for (let i = initStartIdx; i < html.length; i++) {
|
|
if (html[i] === '{') {
|
|
braceCount++;
|
|
inFunction = true;
|
|
} else if (html[i] === '}') {
|
|
braceCount--;
|
|
if (inFunction && braceCount === 0) {
|
|
initEndIdx = i + 1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// New init function
|
|
const newInit = `// Initialize
|
|
async function init() {
|
|
// Use embedded data directly (works with file://)
|
|
agentData = EMBEDDED_DATA;
|
|
|
|
try {
|
|
document.getElementById('lastSync').textContent = formatDate(agentData.lastUpdated);
|
|
document.getElementById('agentCount').textContent = agentData.evolution_metrics.total_agents + ' agents';
|
|
document.getElementById('historyCount').textContent = agentData.evolution_metrics.agents_with_history + ' with history';
|
|
|
|
if (agentData.evolution_metrics.total_agents === 0) {
|
|
document.getElementById('lastSync').textContent = 'No data - run sync:evolution';
|
|
return;
|
|
}
|
|
|
|
renderOverview();
|
|
renderAllAgents();
|
|
renderTimeline();
|
|
renderRecommendations();
|
|
renderMatrix();
|
|
} catch (error) {
|
|
console.error('Failed to render dashboard:', error);
|
|
document.getElementById('lastSync').textContent = 'Error rendering data';
|
|
}
|
|
}`;
|
|
|
|
html = html.substring(0, initStartIdx) + newInit + html.substring(initEndIdx);
|
|
}
|
|
|
|
// Write output
|
|
fs.writeFileSync(OUTPUT_FILE, html);
|
|
|
|
console.log('\n✅ Built standalone dashboard');
|
|
console.log(' Output:', OUTPUT_FILE);
|
|
console.log(' Agents:', Object.keys(data.agents).length);
|
|
console.log(' Size:', (fs.statSync(OUTPUT_FILE).size / 1024).toFixed(1), 'KB');
|
|
console.log('\n📊 Open in browser:');
|
|
console.log(' Windows: start agent-evolution\\index.standalone.html');
|
|
console.log(' macOS: open agent-evolution/index.standalone.html');
|
|
console.log(' Linux: xdg-open agent-evolution/index.standalone.html');
|
|
} catch (error) {
|
|
console.error('❌ Error:', error.message);
|
|
process.exit(1);
|
|
} |