feat: adicionar painel Agentes BrainSteel Web (Scout, Designer, Outreach, Orchestrator)

This commit is contained in:
Hermes
2026-05-17 20:57:07 +00:00
parent 4824f7eb9b
commit 02d073328a
4 changed files with 897 additions and 1 deletions
+441
View File
@@ -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 = '<p class="text-muted">Nenhum candidato encontrado</p>';
return;
}
const html = targets.map(t => `
<div class="scout-target-card" data-id="${t.id}">
<div class="target-header">
<span class="target-score score-${t.score >= 8 ? 'high' : t.score >= 6 ? 'medium' : 'low'}">${t.score}</span>
<div class="target-info">
<h4>${t.name}</h4>
<a href="${t.url}" target="_blank" class="target-url">${t.url}</a>
</div>
</div>
<div class="target-body">
<p class="target-reason">${t.reason}</p>
<div class="target-meta">
<span><i class="fab fa-instagram"></i> ${t.social}</span>
<span class="target-niche">${t.niche}</span>
</div>
</div>
<div class="target-actions">
<button class="btn btn-sm btn-primary" onclick="selectTargetForDesign(${t.id})">
<i class="fas fa-magic"></i> Redesign
</button>
<button class="btn btn-sm btn-secondary" onclick="openTargetURL(${t.id})">
<i class="fas fa-external-link-alt"></i> Ver Site
</button>
</div>
</div>
`).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
? '<i class="fas fa-spinner fa-spin"></i> Pesquisando...'
: '<i class="fas fa-search"></i> 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
? '<i class="fas fa-spinner fa-spin"></i> Processando...'
: '<i class="fas fa-magic"></i> 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
? '<i class="fas fa-spinner fa-spin"></i> Executando...'
: '<i class="fas fa-play"></i> 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');
});