/** * CLAUDE.md Migration Wizard * Handles multi-step migration of CLAUDE.md rules to database */ let analysisResult = null; let selectedCandidates = []; // Initialize document.addEventListener('DOMContentLoaded', () => { initializeEventListeners(); checkAuth(); }); /** * Initialize all event listeners */ function initializeEventListeners() { // Step 1: Upload document.getElementById('file-upload').addEventListener('change', handleFileUpload); document.getElementById('analyze-btn').addEventListener('click', analyzeClaudeMd); // Step 2: Review document.getElementById('back-to-upload-btn').addEventListener('click', () => goToStep(1)); document.getElementById('create-rules-btn').addEventListener('click', createSelectedRules); // Step 3: Results document.getElementById('migrate-another-btn').addEventListener('click', () => goToStep(1)); // Tab switching document.querySelectorAll('.tab-btn').forEach(btn => { btn.addEventListener('click', (e) => switchTab(e.target.dataset.tab)); }); // Logout document.getElementById('logout-btn').addEventListener('click', logout); } /** * Check authentication */ async function checkAuth() { const token = localStorage.getItem('auth_token'); if (!token) { window.location.href = '/admin/login.html'; } } /** * Handle file upload */ function handleFileUpload(event) { const file = event.target.files[0]; if (!file) return; const reader = new FileReader(); reader.onload = (e) => { document.getElementById('claude-md-content').value = e.target.result; showToast('File loaded successfully', 'success'); }; reader.onerror = () => { showToast('Failed to read file', 'error'); }; reader.readAsText(file); } /** * Analyze CLAUDE.md content */ async function analyzeClaudeMd() { const content = document.getElementById('claude-md-content').value.trim(); if (!content) { showToast('Please upload or paste CLAUDE.md content', 'error'); return; } const analyzeBtn = document.getElementById('analyze-btn'); analyzeBtn.disabled = true; analyzeBtn.textContent = 'Analyzing...'; try { const response = await apiRequest('/api/admin/rules/analyze-claude-md', { method: 'POST', body: JSON.stringify({ content }) }); if (!response.success) { throw new Error(response.message || 'Analysis failed'); } analysisResult = response.analysis; displayAnalysisResults(analysisResult); goToStep(2); } catch (error) { console.error('Analysis error:', error); showToast(error.message || 'Failed to analyze CLAUDE.md', 'error'); } finally { analyzeBtn.disabled = false; analyzeBtn.textContent = 'Analyze CLAUDE.md'; } } /** * Display analysis results */ function displayAnalysisResults(analysis) { // Update statistics document.getElementById('stat-total').textContent = analysis.totalStatements; document.getElementById('stat-high-quality').textContent = analysis.quality.highQuality; document.getElementById('stat-needs-clarification').textContent = analysis.quality.needsClarification; document.getElementById('stat-too-nebulous').textContent = analysis.quality.tooNebulous; // Reset selected candidates selectedCandidates = []; // Display high-quality candidates (auto-selected) const highQualityList = document.getElementById('high-quality-list'); const highQualityCandidates = analysis.candidates.filter(c => c.quality === 'HIGH'); if (highQualityCandidates.length > 0) { highQualityList.innerHTML = highQualityCandidates.map((candidate, index) => `
${escapeHtml(candidate.sectionTitle)}
${candidate.quadrant} ${candidate.persistence}

Original:

${escapeHtml(candidate.originalText)}

Suggested:

${escapeHtml(candidate.suggestedRule.text)}

${candidate.suggestedRule.variables && candidate.suggestedRule.variables.length > 0 ? `
${candidate.suggestedRule.variables.map(v => ` \${${v}} `).join('')}
` : ''}
Clarity: ${candidate.suggestedRule.clarityScore}% Scope: ${candidate.suggestedRule.scope}
`).join(''); // Auto-select high-quality candidates highQualityCandidates.forEach(c => selectedCandidates.push(c)); } else { highQualityList.innerHTML = '

No high-quality candidates found.

'; } // Display needs clarification candidates const needsClarificationList = document.getElementById('needs-clarification-list'); const needsClarificationCandidates = analysis.candidates.filter(c => c.quality === 'NEEDS_CLARIFICATION'); if (needsClarificationCandidates.length > 0) { needsClarificationList.innerHTML = needsClarificationCandidates.map((candidate, index) => `
${escapeHtml(candidate.sectionTitle)}
${candidate.quadrant} ${candidate.persistence}

Original:

${escapeHtml(candidate.originalText)}

Suggested:

${escapeHtml(candidate.suggestedRule.text)}

${candidate.analysis.issues && candidate.analysis.issues.length > 0 ? `

Issues:

    ${candidate.analysis.issues.map(issue => `
  • ${escapeHtml(issue)}
  • `).join('')}
` : ''}
`).join(''); } else { needsClarificationList.innerHTML = '

No candidates needing clarification.

'; } // Display too nebulous candidates const tooNebulousList = document.getElementById('too-nebulous-list'); const tooNebulousCandidates = analysis.candidates.filter(c => c.quality === 'TOO_NEBULOUS'); if (tooNebulousCandidates.length > 0) { tooNebulousList.innerHTML = tooNebulousCandidates.map(candidate => `

${escapeHtml(candidate.sectionTitle)}

${escapeHtml(candidate.originalText)}

${candidate.improvements && candidate.improvements.length > 0 ? `

Suggestions:

    ${candidate.improvements.map(imp => `
  • ${escapeHtml(imp)}
  • `).join('')}
` : ''}
`).join(''); } else { tooNebulousList.innerHTML = '

No too-nebulous statements.

'; } // Display redundancies const redundanciesList = document.getElementById('redundancies-list'); if (analysis.redundancies && analysis.redundancies.length > 0) { redundanciesList.innerHTML = analysis.redundancies.map((group, index) => `

Redundancy Group ${index + 1}

${group.rules.map(rule => `

• ${escapeHtml(rule)}

`).join('')}

Suggested Merge:

${escapeHtml(group.mergeSuggestion)}

`).join(''); } else { redundanciesList.innerHTML = '

No redundancies detected.

'; } } /** * Toggle candidate selection */ function toggleCandidate(candidate, checked) { if (checked) { selectedCandidates.push(candidate); } else { selectedCandidates = selectedCandidates.filter(c => c.originalText !== candidate.originalText); } // Update button text document.getElementById('create-rules-btn').textContent = `Create Selected Rules (${selectedCandidates.length})`; } /** * Create selected rules */ async function createSelectedRules() { if (selectedCandidates.length === 0) { showToast('Please select at least one rule to create', 'error'); return; } const createBtn = document.getElementById('create-rules-btn'); createBtn.disabled = true; createBtn.textContent = 'Creating...'; try { const response = await apiRequest('/api/admin/rules/migrate-from-claude-md', { method: 'POST', body: JSON.stringify({ selectedCandidates }) }); if (!response.success) { throw new Error(response.message || 'Migration failed'); } displayMigrationResults(response.results); goToStep(3); } catch (error) { console.error('Migration error:', error); showToast(error.message || 'Failed to create rules', 'error'); createBtn.disabled = false; createBtn.textContent = `Create Selected Rules (${selectedCandidates.length})`; } } /** * Display migration results */ function displayMigrationResults(results) { const summaryDiv = document.getElementById('results-summary'); summaryDiv.innerHTML = `
Total Requested: ${results.totalRequested}
Successfully Created: ${results.created.length}
${results.failed.length > 0 ? `
Failed: ${results.failed.length}
` : ''}
${results.created.length > 0 ? `

Created Rules:

${results.created.map(rule => `
${escapeHtml(rule.id)}

${escapeHtml(rule.text.substring(0, 80))}${rule.text.length > 80 ? '...' : ''}

`).join('')}
` : ''} ${results.failed.length > 0 ? `

Failed Rules:

${results.failed.map(fail => `

${escapeHtml(fail.candidate.substring(0, 60))}...

Error: ${escapeHtml(fail.error)}

`).join('')}
` : ''}
`; } /** * Switch between tabs */ function switchTab(tabName) { // Update tab buttons document.querySelectorAll('.tab-btn').forEach(btn => { if (btn.dataset.tab === tabName) { btn.classList.add('active', 'border-indigo-600', 'text-indigo-600'); btn.classList.remove('border-transparent', 'text-gray-500'); } else { btn.classList.remove('active', 'border-indigo-600', 'text-indigo-600'); btn.classList.add('border-transparent', 'text-gray-500'); } }); // Update tab content document.querySelectorAll('.tab-content').forEach(content => { content.classList.add('hidden'); }); document.getElementById(`${tabName}-tab`).classList.remove('hidden'); } /** * Navigate to a specific step */ function goToStep(stepNumber) { // Hide all steps [1, 2, 3].forEach(num => { document.getElementById(`step-${num}-content`).classList.add('hidden'); }); // Show target step document.getElementById(`step-${stepNumber}-content`).classList.remove('hidden'); // Update step indicators [1, 2, 3].forEach(num => { const indicator = document.getElementById(`step-${num}-indicator`); const title = document.getElementById(`step-${num}-title`); if (num < stepNumber) { // Completed step indicator.className = 'flex-shrink-0 w-10 h-10 flex items-center justify-center rounded-full bg-green-600 text-white font-semibold'; indicator.innerHTML = ''; title.classList.add('text-gray-900'); title.classList.remove('text-gray-500'); } else if (num === stepNumber) { // Current step indicator.className = 'flex-shrink-0 w-10 h-10 flex items-center justify-center rounded-full bg-indigo-600 text-white font-semibold'; indicator.textContent = num; title.classList.add('text-gray-900'); title.classList.remove('text-gray-500'); } else { // Future step indicator.className = 'flex-shrink-0 w-10 h-10 flex items-center justify-center rounded-full bg-gray-200 text-gray-500 font-semibold'; indicator.textContent = num; title.classList.remove('text-gray-900'); title.classList.add('text-gray-500'); } }); // Reset form if going back to step 1 if (stepNumber === 1) { document.getElementById('claude-md-content').value = ''; document.getElementById('file-upload').value = ''; analysisResult = null; selectedCandidates = []; } } /** * Logout */ function logout() { localStorage.removeItem('auth_token'); window.location.href = '/admin/login.html'; } // Utility functions function escapeHtml(text) { const div = document.createElement('div'); div.textContent = text; return div.innerHTML; } function getQuadrantColor(quadrant) { const colors = { STRATEGIC: 'bg-purple-100 text-purple-800', OPERATIONAL: 'bg-green-100 text-green-800', TACTICAL: 'bg-yellow-100 text-yellow-800', SYSTEM: 'bg-blue-100 text-blue-800', STORAGE: 'bg-gray-100 text-gray-800' }; return colors[quadrant] || 'bg-gray-100 text-gray-800'; } function getPersistenceColor(persistence) { const colors = { HIGH: 'bg-red-100 text-red-800', MEDIUM: 'bg-orange-100 text-orange-800', LOW: 'bg-yellow-100 text-yellow-800' }; return colors[persistence] || 'bg-gray-100 text-gray-800'; }