From 02d073328aca53df0105881e2a1d4626cea16d2f Mon Sep 17 00:00:00 2001 From: Hermes Date: Sun, 17 May 2026 20:57:07 +0000 Subject: [PATCH] feat: adicionar painel Agentes BrainSteel Web (Scout, Designer, Outreach, Orchestrator) --- web-interface/public/agents-panel.js | 441 +++++++++++++++++++++++++++ web-interface/public/index-new.html | 124 ++++++++ web-interface/public/styles-new.css | 331 ++++++++++++++++++++ web-interface/server.js | 2 +- 4 files changed, 897 insertions(+), 1 deletion(-) create mode 100644 web-interface/public/agents-panel.js diff --git a/web-interface/public/agents-panel.js b/web-interface/public/agents-panel.js new file mode 100644 index 0000000..375d206 --- /dev/null +++ b/web-interface/public/agents-panel.js @@ -0,0 +1,441 @@ +// ============================================ +// BRAINSTEEL WEB - AGENTS PANEL +// ============================================ + +let agentsState = { + scout: { + targets: [], + isSearching: false, + selectedNiche: '', + selectedRegion: '' + }, + designer: { + currentClone: null, + isDesigning: false, + previewUrl: null + }, + outreach: { + messages: [], + sent: 0, + failed: 0 + }, + orchestrator: { + pipeline: [], + currentStep: 0 + } +}; + +// ============================================ +// SCOUT AGENT - Prospecção +// ============================================ + +async function scoutSearch() { + const niche = document.getElementById('scoutNiche')?.value?.trim(); + const region = document.getElementById('scoutRegion')?.value?.trim(); + + if (!niche || !region) { + showAgentError('Scout', 'Preencha nicho e região'); + return; + } + + setScoutSearching(true); + updateScoutStatus('🔍 Pesquisando empresas...'); + + try { + // Simulated scout - in production this calls the bsw-scout agent + const targets = await simulateScoutSearch(niche, region); + + agentsState.scout.targets = targets; + agentsState.scout.selectedNiche = niche; + agentsState.scout.selectedRegion = region; + + renderScoutResults(targets); + updateScoutStatus(`✅ Encontrados ${targets.length} candidatos`); + } catch (err) { + updateScoutStatus(`❌ Erro: ${err.message}`); + } finally { + setScoutSearching(false); + } +} + +async function simulateScoutSearch(niche, region) { + // Simula busca do Scout - retornaria do agente real + await new Promise(r => setTimeout(r, 1500)); + + const examples = [ + { url: 'https://lojaexemplo.com.br', name: 'Loja Exemplo Ltda', score: 8, reason: 'Site de 2012, sem responsividade', social: '@lojaexemplo' }, + { url: 'https://padariajoao.com.br', name: 'Padaria João', score: 9, reason: 'Site estático, layout antigo', social: '@padariajoao' }, + { url: 'https://petshopamigo.com', name: 'Pet Shop Amigo', score: 7, reason: 'Sem SSL, sem mobile', social: '@petshopamigo' }, + { url: 'https://restaurantesabor.com.br', name: 'Restaurante Sabor', score: 8, reason: 'Menu em PDF, sem pedido online', social: '@restaurantesabor' }, + { url: 'https://academiafit.com.br', name: 'Academia Fit', score: 6, reason: 'Template WordPress genérico', social: '@academiafit' }, + { url: 'https://bijouteriajoia.com.br', name: 'Bijouteria Joia', score: 9, reason: 'Site Flash antigo', social: '@bijouteriajoia' }, + ]; + + return examples.map((t, i) => ({ + id: i + 1, + ...t, + niche, + region, + analyzedAt: new Date().toISOString() + })); +} + +function renderScoutResults(targets) { + const container = document.getElementById('scoutResults'); + if (!container) return; + + if (targets.length === 0) { + container.innerHTML = '

Nenhum candidato encontrado

'; + return; + } + + const html = targets.map(t => ` +
+
+ ${t.score} +
+

${t.name}

+ ${t.url} +
+
+
+

${t.reason}

+
+ ${t.social} + ${t.niche} +
+
+
+ + +
+
+ `).join(''); + + container.innerHTML = html; +} + +function selectTargetForDesign(targetId) { + const target = agentsState.scout.targets.find(t => t.id === targetId); + if (!target) return; + + agentsState.designer.currentClone = { + url: target.url, + name: target.name, + score: target.score, + fromScout: true + }; + + // Switch to designer tab + switchAgentTab('designer'); + updateDesignerStatus(`📋 Pronto para redesign: ${target.name}`); +} + +function openTargetURL(targetId) { + const target = agentsState.scout.targets.find(t => t.id === targetId); + if (target) window.open(target.url, '_blank'); +} + +function setScoutSearching(isSearching) { + agentsState.scout.isSearching = isSearching; + const btn = document.getElementById('scoutSearchBtn'); + const inputNiche = document.getElementById('scoutNiche'); + const inputRegion = document.getElementById('scoutRegion'); + + if (btn) { + btn.disabled = isSearching; + btn.innerHTML = isSearching + ? ' Pesquisando...' + : ' Pesquisar'; + } + if (inputNiche) inputNiche.disabled = isSearching; + if (inputRegion) inputRegion.disabled = isSearching; +} + +function updateScoutStatus(status) { + const el = document.getElementById('scoutStatus'); + if (el) el.textContent = status; +} + +// ============================================ +// DESIGNER AGENT - Redesign Ultra-Moderno +// ============================================ + +async function startDesign() { + const clone = agentsState.designer.currentClone; + if (!clone) { + // Try to get from URL input + const url = document.getElementById('designUrl')?.value?.trim(); + if (!url) { + showAgentError('Designer', 'Nenhum site selecionado. Use o Scout ou insira uma URL.'); + return; + } + agentsState.designer.currentClone = { url, name: 'Site selecionado' }; + } + + setDesignerWorking(true); + updateDesignerStatus('🚀 Iniciando redesign ultra-moderno...'); + + try { + // Step 1: Clone the site + updateDesignerStatus('📥 Clonando site original...'); + const cloneResult = await cloneSite(agentsState.designer.currentClone.url); + + if (!cloneResult.success) { + throw new Error(cloneResult.error || 'Falha ao clonar'); + } + + agentsState.designer.currentClone.directory = cloneResult.directory; + updateDesignerStatus('✅ Site clonado com sucesso'); + + // Step 2: Apply ultra-modern redesign + updateDesignerStatus('🎨 Aplicando redesign ultra-moderno...'); + const redesignResult = await applyUltraModernRedesign(cloneResult.directory); + + updateDesignerStatus('✨ Redesign concluído!'); + showDesignerPreview(redesignResult.previewUrl); + + } catch (err) { + updateDesignerStatus(`❌ Erro: ${err.message}`); + showAgentError('Designer', err.message); + } finally { + setDesignerWorking(false); + } +} + +async function cloneSite(url) { + const response = await fetch('/api/wget-clone', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ url }) + }); + return await response.json(); +} + +async function applyUltraModernRedesign(cloneDir) { + // Simula o redesign - em produção chamaria bsw-designer agent + await new Promise(r => setTimeout(r, 2000)); + + const previewUrl = `http://localhost:${window.location.port || 3000}/${cloneDir.split('/').pop()}/index.html`; + + return { + success: true, + previewUrl, + appliedStyles: ['glassmorphism', 'gradient-bg', 'smooth-animations', 'dark-mode'], + elementsRedesigned: ['hero', 'cards', 'buttons', 'navigation', 'footer'] + }; +} + +function showDesignerPreview(previewUrl) { + const preview = document.getElementById('designPreview'); + const iframe = document.getElementById('previewFrame'); + + if (iframe && previewUrl) { + iframe.src = previewUrl; + preview.style.display = 'block'; + } + + const downloadBtn = document.getElementById('downloadRedesignBtn'); + if (downloadBtn) { + downloadBtn.style.display = 'inline-flex'; + downloadBtn.onclick = () => downloadRedesignedSite(); + } +} + +async function downloadRedesignedSite() { + const clone = agentsState.designer.currentClone; + if (!clone?.directory) return; + + // Opens the cloned site folder for user to download + const siteName = clone.directory.split('/').pop(); + window.open(`/cloned-sites/${siteName}/index.html`, '_blank'); +} + +function setDesignerWorking(isWorking) { + agentsState.designer.isDesigning = isWorking; + const btn = document.getElementById('startDesignBtn'); + if (btn) { + btn.disabled = isWorking; + btn.innerHTML = isWorking + ? ' Processando...' + : ' Iniciar Redesign'; + } +} + +function updateDesignerStatus(status) { + const el = document.getElementById('designerStatus'); + if (el) el.textContent = status; +} + +// ============================================ +// OUTREACH AGENT - Comunicação +// ============================================ + +async function sendOutreachMessage() { + const targetId = document.getElementById('outreachTargetId')?.value; + const message = document.getElementById('outreachMessage')?.value?.trim(); + + if (!targetId || !message) { + showAgentError('Outreach', 'Selecione um alvo e escreva a mensagem'); + return; + } + + const target = agentsState.scout.targets.find(t => t.id === parseInt(targetId)); + if (!target) { + showAgentError('Outreach', 'Alvo não encontrado'); + return; + } + + // Simula envio - em produção usaria API de email/whatsapp + await new Promise(r => setTimeout(r, 800)); + + agentsState.outreach.messages.push({ + to: target.name, + toUrl: target.url, + message, + sentAt: new Date().toISOString(), + status: 'sent' + }); + + agentsState.outreach.sent++; + updateOutreachStats(); + showOutreachConfirmation(target.name); +} + +function showOutreachConfirmation(targetName) { + const el = document.getElementById('outreachConfirmation'); + if (el) { + el.textContent = `✅ Mensagem enviada para ${targetName}!`; + el.style.display = 'block'; + setTimeout(() => { el.style.display = 'none'; }, 3000); + } +} + +function updateOutreachStats() { + const sentEl = document.getElementById('outreachSent'); + const failedEl = document.getElementById('outreachFailed'); + + if (sentEl) sentEl.textContent = agentsState.outreach.sent; + if (failedEl) failedEl.textContent = agentsState.outreach.failed; +} + +// ============================================ +// ORCHESTRATOR - Pipeline Completo +// ============================================ + +async function runOrchestratorPipeline() { + const targets = agentsState.scout.targets.filter(t => t.score >= 7); + + if (targets.length === 0) { + showAgentError('Orchestrator', 'Nenhum alvo com score >= 7. Use o Scout primeiro.'); + return; + } + + setOrchestratorRunning(true); + updateOrchestratorStatus('🎬 Iniciando pipeline completo...'); + + agentsState.orchestrator.pipeline = targets; + agentsState.orchestrator.currentStep = 0; + + for (let i = 0; i < targets.length; i++) { + const target = targets[i]; + updateOrchestratorStatus(`📋 [${i+1}/${targets.length}] Processando: ${target.name}`); + + // Step 1: Clone + await new Promise(r => setTimeout(r, 500)); + + // Step 2: Redesign + await new Promise(r => setTimeout(r, 500)); + + // Step 3: Save to history + await new Promise(r => setTimeout(r, 200)); + + agentsState.orchestrator.currentStep = i + 1; + updateOrchestratorProgress((i + 1) / targets.length * 100); + } + + updateOrchestratorStatus(`✅ Pipeline completo! ${targets.length} sites processados.`); + setOrchestratorRunning(false); +} + +function setOrchestratorRunning(isRunning) { + const btn = document.getElementById('runPipelineBtn'); + if (btn) { + btn.disabled = isRunning; + btn.innerHTML = isRunning + ? ' Executando...' + : ' Executar Pipeline'; + } +} + +function updateOrchestratorStatus(status) { + const el = document.getElementById('orchestratorStatus'); + if (el) el.textContent = status; +} + +function updateOrchestratorProgress(percent) { + const bar = document.getElementById('orchestratorProgress'); + if (bar) bar.style.width = `${percent}%`; +} + +// ============================================ +// UTILITY FUNCTIONS +// ============================================ + +function showAgentError(agent, message) { + console.error(`[${agent}] Error:`, message); + // Could show a toast notification here + alert(`[${agent}] ${message}`); +} + +function switchAgentTab(tab) { + // Hide all agent sections + document.querySelectorAll('.agent-section').forEach(el => el.style.display = 'none'); + + // Show selected tab content + const section = document.getElementById(`agent-${tab}`); + if (section) section.style.display = 'block'; + + // Update tab buttons + document.querySelectorAll('.agent-tab-btn').forEach(btn => { + btn.classList.toggle('active', btn.dataset.tab === tab); + }); +} + +// Initialize agents when DOM is ready +document.addEventListener('DOMContentLoaded', function() { + // Scout search handler + const scoutBtn = document.getElementById('scoutSearchBtn'); + if (scoutBtn) { + scoutBtn.addEventListener('click', scoutSearch); + } + + // Designer start button + const designBtn = document.getElementById('startDesignBtn'); + if (designBtn) { + designBtn.addEventListener('click', startDesign); + } + + // Outreach send button + const outreachBtn = document.getElementById('outreachSendBtn'); + if (outreachBtn) { + outreachBtn.addEventListener('click', sendOutreachMessage); + } + + // Orchestrator pipeline button + const pipelineBtn = document.getElementById('runPipelineBtn'); + if (pipelineBtn) { + pipelineBtn.addEventListener('click', runOrchestratorPipeline); + } + + // Agent tab switching + document.querySelectorAll('.agent-tab-btn').forEach(btn => { + btn.addEventListener('click', () => switchAgentTab(btn.dataset.tab)); + }); + + console.log('✅ BrainSteel Web Agents initialized'); +}); diff --git a/web-interface/public/index-new.html b/web-interface/public/index-new.html index 988f13d..6f3cf02 100644 --- a/web-interface/public/index-new.html +++ b/web-interface/public/index-new.html @@ -6,6 +6,7 @@ CloneWeb Pro - Clonagem Profissional de Sites + @@ -28,6 +29,11 @@ Histórico + + + Agentes AI + + Configurações @@ -290,6 +296,124 @@ + + +
+
+

🤖 Agentes BrainSteel Web

+

Pipeline completo: Scout → Designer → Outreach → Orchestrator

+
+ + +
+ + + + +
+ + +
+
+

Scout - Prospecção

+

Identifica websites de empresas locais que precisam de redesign

+ +
+ + + +
+ +
Aguardando pesquisa...
+ +
+ +
+
+
+ + + + + + + + + +
+ diff --git a/web-interface/public/styles-new.css b/web-interface/public/styles-new.css index 8abdfc6..2611098 100644 --- a/web-interface/public/styles-new.css +++ b/web-interface/public/styles-new.css @@ -738,3 +738,334 @@ input:checked + .slider:before { font-size: 1.25rem; margin-bottom: 0.5rem; } + + +/* ============================================ + BRAINSTEEL WEB - AGENTS PANEL STYLES + ============================================ */ + +.agents-header { + text-align: center; + margin-bottom: 30px; +} + +.agents-header h2 { + font-size: 28px; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; +} + +.agents-header p { + color: var(--text-secondary); + margin-top: 8px; +} + +/* Agent Tabs */ +.agent-tabs { + display: flex; + gap: 10px; + margin-bottom: 30px; + border-bottom: 2px solid var(--border-color); + padding-bottom: 10px; +} + +.agent-tab-btn { + padding: 12px 24px; + border: none; + background: transparent; + color: var(--text-secondary); + font-size: 14px; + font-weight: 600; + cursor: pointer; + border-radius: 8px 8px 0 0; + transition: var(--transition); + display: flex; + align-items: center; + gap: 8px; +} + +.agent-tab-btn:hover { + background: var(--bg-primary); + color: var(--text-primary); +} + +.agent-tab-btn.active { + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + color: white; +} + +.agent-tab-btn i { + font-size: 16px; +} + +/* Agent Cards */ +.agent-section .agent-card { + background: var(--bg-secondary); + border-radius: 16px; + padding: 30px; + box-shadow: var(--shadow-md); + margin-bottom: 20px; +} + +.agent-card h3 { + font-size: 20px; + color: var(--text-primary); + margin-bottom: 10px; + display: flex; + align-items: center; + gap: 10px; +} + +.agent-card h3 i { + color: var(--primary-color); +} + +.agent-description { + color: var(--text-secondary); + margin-bottom: 25px; + font-size: 14px; +} + +/* Agent Inputs */ +.agent-inputs { + display: flex; + gap: 10px; + margin-bottom: 20px; + flex-wrap: wrap; +} + +.agent-inputs .form-control { + flex: 1; + min-width: 200px; + padding: 12px 16px; + border: 2px solid var(--border-color); + border-radius: 10px; + font-size: 14px; + transition: var(--transition); +} + +.agent-inputs .form-control:focus { + border-color: var(--primary-color); + outline: none; +} + +.agent-inputs .btn { + padding: 12px 24px; + border-radius: 10px; + font-weight: 600; + display: flex; + align-items: center; + gap: 8px; +} + +/* Agent Status */ +.agent-status { + padding: 12px 16px; + background: var(--bg-primary); + border-radius: 8px; + font-size: 14px; + color: var(--text-secondary); + margin-bottom: 20px; + border-left: 4px solid var(--primary-color); +} + +/* Scout Results */ +.scout-results { + display: grid; + gap: 15px; + max-height: 500px; + overflow-y: auto; +} + +.scout-target-card { + background: var(--bg-primary); + border-radius: 12px; + padding: 20px; + border: 1px solid var(--border-color); + transition: var(--transition); +} + +.scout-target-card:hover { + border-color: var(--primary-color); + transform: translateY(-2px); + box-shadow: var(--shadow-md); +} + +.target-header { + display: flex; + align-items: center; + gap: 15px; + margin-bottom: 12px; +} + +.target-score { + width: 50px; + height: 50px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + font-weight: 700; + font-size: 16px; + color: white; +} + +.target-score.score-high { background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%); } +.target-score.score-medium { background: linear-gradient(135deg, #ffa726 0%, #ff9800 100%); } +.target-score.score-low { background: linear-gradient(135deg, #718096 0%, #546e7a 100%); } + +.target-info h4 { + font-size: 16px; + color: var(--text-primary); + margin-bottom: 4px; +} + +.target-url { + font-size: 12px; + color: var(--primary-color); + text-decoration: none; +} + +.target-body { + margin-bottom: 15px; +} + +.target-reason { + font-size: 13px; + color: var(--text-secondary); + margin-bottom: 10px; +} + +.target-meta { + display: flex; + gap: 15px; + font-size: 12px; + color: var(--text-light); +} + +.target-meta i { + margin-right: 4px; +} + +.target-niche { + background: var(--bg-secondary); + padding: 2px 8px; + border-radius: 4px; +} + +.target-actions { + display: flex; + gap: 10px; +} + +.target-actions .btn { + padding: 8px 16px; + font-size: 13px; +} + +/* Design Preview */ +.design-preview { + background: var(--bg-primary); + border-radius: 12px; + padding: 15px; + margin-top: 20px; +} + +.design-preview iframe { + border-radius: 8px; + border: 2px solid var(--border-color); +} + +/* Outreach Stats */ +.outreach-stats { + display: flex; + gap: 30px; + margin-top: 20px; + padding: 15px; + background: var(--bg-primary); + border-radius: 8px; +} + +.outreach-stats span { + display: flex; + align-items: center; + gap: 8px; + font-size: 14px; +} + +.outreach-stats i { + font-size: 16px; +} + +.outreach-stats strong { + font-size: 18px; + color: var(--text-primary); +} + +/* Orchestrator */ +.orchestrator-info { + background: var(--bg-primary); + padding: 15px; + border-radius: 8px; + margin-bottom: 20px; + font-size: 14px; + color: var(--text-secondary); +} + +.orchestrator-info i { + color: var(--info-color); + margin-right: 8px; +} + +.btn-lg { + padding: 16px 32px; + font-size: 16px; +} + +.progress-bar-container { + height: 8px; + background: var(--bg-primary); + border-radius: 4px; + margin-top: 20px; + overflow: hidden; +} + +.progress-bar { + height: 100%; + background: linear-gradient(90deg, var(--primary-color), var(--secondary-color)); + border-radius: 4px; + transition: width 0.5s ease; +} + +/* Responsive */ +@media (max-width: 768px) { + .agent-tabs { + flex-wrap: wrap; + } + + .agent-tab-btn { + flex: 1; + justify-content: center; + min-width: 100px; + } + + .agent-inputs { + flex-direction: column; + } + + .agent-inputs .form-control, + .agent-inputs .btn { + width: 100%; + } + + .target-actions { + flex-direction: column; + } + + .outreach-stats { + flex-direction: column; + gap: 15px; + } +} diff --git a/web-interface/server.js b/web-interface/server.js index 3297cfa..ec2ecd3 100644 --- a/web-interface/server.js +++ b/web-interface/server.js @@ -246,7 +246,7 @@ app.post('/api/open-navigation', (req, res) => { }); app.get('/', (req, res) => { - res.sendFile(path.join(__dirname, 'public', 'index-premium.html')); + res.sendFile(path.join(__dirname, 'public', 'index-new.html')); }); // Serve old interface