623 lines
23 KiB
JavaScript
623 lines
23 KiB
JavaScript
// ============================================
|
|
// 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 askAI(systemPrompt, userMessage) {
|
|
const response = await fetch('/api/ai/agent', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ systemPrompt, userMessage })
|
|
});
|
|
const result = await response.json();
|
|
if (!result.success) throw new Error(result.error);
|
|
return result.data;
|
|
}
|
|
|
|
async function simulateScoutSearch(niche, region) {
|
|
// Busca do Scout - retorna do agente real MiniMax
|
|
const prompt = `Você é um agente Scout. Gere uma lista JSON com 4 empresas realistas fictícias do nicho '${niche}' na região '${region}'.
|
|
Retorne APENAS um array JSON, sem marcação markdown.
|
|
Estrutura: [{"url": "...", "name": "...", "score": 8, "reason": "...", "social": "..."}]`;
|
|
|
|
try {
|
|
const rawResponse = await askAI(prompt, "Inicie a prospecção.");
|
|
const jsonStr = rawResponse.replace(/```json/gi, '').replace(/```/g, '').trim();
|
|
const examples = JSON.parse(jsonStr);
|
|
|
|
return examples.map((t, i) => ({
|
|
id: i + 1,
|
|
...t,
|
|
niche,
|
|
region,
|
|
analyzedAt: new Date().toISOString()
|
|
}));
|
|
} catch (e) {
|
|
console.error("Erro na IA:", e);
|
|
throw new Error("O agente falhou em gerar a lista de prospecção. Tente novamente.");
|
|
}
|
|
}
|
|
|
|
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 loadDesignerClonesSelect() {
|
|
const inputUrl = document.getElementById('designUrl');
|
|
if (!inputUrl) return;
|
|
|
|
try {
|
|
const response = await fetch('/api/clones');
|
|
const result = await response.json();
|
|
if (!result.success || !result.data?.clones) return;
|
|
|
|
const clones = result.data.clones;
|
|
|
|
// Criar o select
|
|
const select = document.createElement('select');
|
|
select.id = 'designerCloneSelect';
|
|
select.className = 'form-control mb-3';
|
|
select.style.cssText = 'background: rgba(255, 255, 255, 0.05); border: 1px solid var(--ai-border-glass); color: #f3f4f6; border-radius: 12px; padding: 12px 16px; margin-bottom: 16px; font-family: "Inter", sans-serif; cursor: pointer; width: 100%;';
|
|
|
|
let optionsHtml = '<option value="">-- Selecione um site já clonado para Redesign --</option>';
|
|
clones.forEach(c => {
|
|
const dateStr = c.cloneInfo?.clonedAt ? new Date(c.cloneInfo.clonedAt).toLocaleDateString('pt-BR') : '';
|
|
optionsHtml += `<option value="${c.id}">${c.baseUrl} ${dateStr ? `(Clonado em ${dateStr})` : ''}</option>`;
|
|
});
|
|
select.innerHTML = optionsHtml;
|
|
|
|
// Inserir antes do inputUrl
|
|
inputUrl.parentNode.insertBefore(select, inputUrl);
|
|
|
|
// Adicionar evento para desabilitar/limpar o input de URL quando um clone é selecionado
|
|
select.addEventListener('change', () => {
|
|
if (select.value) {
|
|
inputUrl.value = '';
|
|
inputUrl.placeholder = 'Site selecionado acima. (Ou limpe o select para usar URL nova)';
|
|
inputUrl.disabled = true;
|
|
agentsState.designer.currentClone = {
|
|
directory: 'cloned-sites/' + select.value,
|
|
name: select.value.split('_')[0],
|
|
url: 'https://' + select.value.split('_')[0]
|
|
};
|
|
} else {
|
|
inputUrl.disabled = false;
|
|
inputUrl.placeholder = 'https://exemplo.com (Para clonar novo site)';
|
|
agentsState.designer.currentClone = null;
|
|
}
|
|
});
|
|
} catch (e) {
|
|
console.error('Erro ao carregar lista de clones no Designer:', e);
|
|
}
|
|
}
|
|
|
|
async function startDesign() {
|
|
const selectEl = document.getElementById('designerCloneSelect');
|
|
const urlEl = document.getElementById('designUrl');
|
|
const customPathEl = document.getElementById('designerCustomPath');
|
|
|
|
const customPath = customPathEl?.value?.trim();
|
|
|
|
// Se informou caminho específico (nova funcionalidade)
|
|
if (customPath) {
|
|
agentsState.designer.currentClone = {
|
|
directory: customPath,
|
|
name: customPath.split('/').pop() || 'Site Customizado',
|
|
url: customPath,
|
|
isCustomPath: true
|
|
};
|
|
}
|
|
// Se escolheu na droplist
|
|
else if (selectEl && selectEl.value) {
|
|
agentsState.designer.currentClone = {
|
|
directory: 'cloned-sites/' + selectEl.value,
|
|
name: selectEl.value.split('_')[0],
|
|
url: 'https://' + selectEl.value.split('_')[0],
|
|
isCustomPath: false
|
|
};
|
|
} else {
|
|
const url = urlEl?.value?.trim();
|
|
if (!url) {
|
|
showAgentError('Designer', 'Selecione um site, insira uma URL ou informe um Caminho Específico de pasta.');
|
|
return;
|
|
}
|
|
agentsState.designer.currentClone = { url, name: 'Site selecionado', isCustomPath: false };
|
|
}
|
|
|
|
setDesignerWorking(true);
|
|
updateDesignerStatus('🚀 Iniciando redesign ultra-moderno...');
|
|
|
|
try {
|
|
let directory = agentsState.designer.currentClone.directory;
|
|
|
|
// Se NÃO escolheu na droplist (ou seja, se passou URL nova), faz o clone do zero!
|
|
if (!directory) {
|
|
updateDesignerStatus('📥 Clonando site original...');
|
|
const cloneResult = await cloneSite(agentsState.designer.currentClone.url);
|
|
|
|
if (!cloneResult.success) {
|
|
throw new Error(cloneResult.error || 'Falha ao clonar');
|
|
}
|
|
|
|
directory = cloneResult.data?.directory || cloneResult.data?.path || cloneResult.directory;
|
|
agentsState.designer.currentClone.directory = directory;
|
|
updateDesignerStatus('✅ Site clonado com sucesso');
|
|
} else {
|
|
updateDesignerStatus('📂 Usando site já clonado do storage...');
|
|
}
|
|
|
|
// Step 2: Apply ultra-modern redesign
|
|
updateDesignerStatus('🎨 Aplicando redesign ultra-moderno com IA...');
|
|
const redesignResult = await applyUltraModernRedesign(directory);
|
|
|
|
updateDesignerStatus('✨ Redesign concluído com sucesso!');
|
|
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/smart-clone', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ url })
|
|
});
|
|
return await response.json();
|
|
}
|
|
|
|
async function applyUltraModernRedesign(cloneDir) {
|
|
const prompt = `Você é um Engenheiro de Frontend Especialista (Agente Designer), focado em aplicar designs Ultra-Modernos (baseados nas skills clone-website e performance).
|
|
Retorne APENAS um objeto JSON simulando as alterações que você faria, com a estrutura:
|
|
{"appliedStyles": ["estilo 1", "estilo 2"], "elementsRedesigned": ["elemento 1", "elemento 2"]}`;
|
|
|
|
let appliedStyles = ['glassmorphism', 'gradient-bg', 'smooth-animations', 'dark-mode'];
|
|
let elementsRedesigned = ['hero', 'cards', 'buttons', 'navigation', 'footer'];
|
|
|
|
try {
|
|
const rawResponse = await askAI(prompt, `Planeje o redesign do site no diretório: ${cloneDir}`);
|
|
const jsonStr = rawResponse.replace(/```json/gi, '').replace(/```/g, '').trim();
|
|
const parsed = JSON.parse(jsonStr);
|
|
if (parsed.appliedStyles) appliedStyles = parsed.appliedStyles;
|
|
if (parsed.elementsRedesigned) elementsRedesigned = parsed.elementsRedesigned;
|
|
} catch (e) {
|
|
console.error("Erro na IA do Designer:", e);
|
|
}
|
|
|
|
// Injetar o CSS de Redesign Ultra-Moderno gerado pela IA no site clonado
|
|
let newPreviewUrl = `/api/preview/${cloneDir.split('/').pop()}`;
|
|
try {
|
|
const response = await fetch('/api/ai/inject-redesign', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({
|
|
cloneDir,
|
|
appliedStyles,
|
|
elementsRedesigned,
|
|
outputDir: settings.outputDir,
|
|
agentName: 'designer'
|
|
})
|
|
});
|
|
const data = await response.json();
|
|
if (data.newFolderName) {
|
|
newPreviewUrl = `/api/preview/${data.newFolderName}`;
|
|
if (agentsState.designer.currentClone) {
|
|
agentsState.designer.currentClone.directory = 'cloned-sites/' + data.newFolderName;
|
|
}
|
|
}
|
|
} catch (e) {
|
|
console.error("Erro ao injetar CSS de redesign:", e);
|
|
}
|
|
|
|
return {
|
|
success: true,
|
|
previewUrl: newPreviewUrl,
|
|
appliedStyles,
|
|
elementsRedesigned
|
|
};
|
|
}
|
|
|
|
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;
|
|
|
|
if (!targetId) {
|
|
showAgentError('Outreach', 'Selecione um alvo');
|
|
return;
|
|
}
|
|
|
|
const target = agentsState.scout.targets.find(t => t.id === parseInt(targetId));
|
|
if (!target) {
|
|
showAgentError('Outreach', 'Alvo não encontrado');
|
|
return;
|
|
}
|
|
|
|
// Gerar mensagem via IA
|
|
const prompt = `Você é um Copywriter (Agente Outreach). Escreva uma mensagem de vendas persuasiva para o cliente '${target.name}' cujo site '${target.url}' tem o problema: '${target.reason}'. Ofereça um redesign ultra-moderno. Responda apenas o texto da mensagem (sem formatação json ou markdown).`;
|
|
|
|
try {
|
|
const message = await askAI(prompt, "Crie o e-mail de vendas.");
|
|
|
|
const msgBox = document.getElementById('outreachMessage');
|
|
if (msgBox) msgBox.value = message;
|
|
|
|
agentsState.outreach.messages.push({
|
|
to: target.name,
|
|
toUrl: target.url,
|
|
message,
|
|
sentAt: new Date().toISOString(),
|
|
status: 'sent'
|
|
});
|
|
|
|
agentsState.outreach.sent++;
|
|
updateOutreachStats();
|
|
showOutreachConfirmation(target.name);
|
|
} catch(e) {
|
|
showAgentError('Outreach', "Falha ao gerar mensagem: " + e.message);
|
|
}
|
|
}
|
|
|
|
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 com IA (Orchestrator)...');
|
|
|
|
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}] Planejando com IA: ${target.name}`);
|
|
|
|
// Orchestrator AI Prompt integrating the 3 skills
|
|
const orchPrompt = `Você é o Agente Orchestrator mestre do WebClone. Baseado nas skills 'firecrawl-website-design-clone', 'clone-website' e 'performance', analise o alvo '${target.name}' (${target.url}) que possui o problema '${target.reason}'. Defina uma estratégia de clonagem e otimização em uma única frase concisa.`;
|
|
|
|
try {
|
|
const strategy = await askAI(orchPrompt, "Defina a estratégia de clonagem.");
|
|
console.log(`[Orchestrator Strategy - ${target.name}]:`, strategy);
|
|
target.orchestratorStrategy = strategy;
|
|
} catch (e) {
|
|
console.error("Erro na IA do Orchestrator:", e);
|
|
target.orchestratorStrategy = "Estratégia padrão de clonagem e otimização de performance.";
|
|
}
|
|
|
|
// Step 1: Clone
|
|
updateOrchestratorStatus(`📥 [${i+1}/${targets.length}] Clonando: ${target.name}`);
|
|
let directory = `cloned-sites/${target.name.toLowerCase().replace(/[^a-z0-9]/g, '')}`;
|
|
try {
|
|
const cloneRes = await cloneSite(target.url);
|
|
if (cloneRes.success && (cloneRes.data?.directory || cloneRes.data?.path || cloneRes.directory)) {
|
|
directory = cloneRes.data?.directory || cloneRes.data?.path || cloneRes.directory;
|
|
}
|
|
} catch (e) {
|
|
console.warn(`Aviso ao clonar ${target.name}, usando diretório de fallback:`, e.message);
|
|
}
|
|
target.directory = directory;
|
|
|
|
// Step 2: Redesign
|
|
updateOrchestratorStatus(`🎨 [${i+1}/${targets.length}] Aplicando Redesign AI: ${target.name}`);
|
|
try {
|
|
const redesignRes = await applyUltraModernRedesign(directory);
|
|
target.redesign = redesignRes;
|
|
} catch (e) {
|
|
console.error(`Erro no redesign de ${target.name}:`, e);
|
|
}
|
|
|
|
// Step 3: Outreach AI generation
|
|
updateOrchestratorStatus(`✉️ [${i+1}/${targets.length}] Gerando Copy de Outreach: ${target.name}`);
|
|
const outreachPrompt = `Você é um Copywriter (Agente Outreach). Escreva uma mensagem de vendas persuasiva para '${target.name}' (${target.url}) focando em resolver '${target.reason}' com um redesign ultra-moderno e alta performance. Responda apenas o texto do e-mail.`;
|
|
try {
|
|
const message = await askAI(outreachPrompt, "Crie o e-mail de vendas.");
|
|
agentsState.outreach.messages.push({
|
|
to: target.name,
|
|
toUrl: target.url,
|
|
message,
|
|
sentAt: new Date().toISOString(),
|
|
status: 'ready'
|
|
});
|
|
agentsState.outreach.sent++;
|
|
updateOutreachStats();
|
|
} catch (e) {
|
|
console.error(`Erro no outreach de ${target.name}:`, e);
|
|
}
|
|
|
|
agentsState.orchestrator.currentStep = i + 1;
|
|
updateOrchestratorProgress((i + 1) / targets.length * 100);
|
|
}
|
|
|
|
updateOrchestratorStatus(`✅ Pipeline completo! ${targets.length} sites processados com IA.`);
|
|
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));
|
|
});
|
|
|
|
// Carregar a droplist de clones do Designer
|
|
loadDesignerClonesSelect();
|
|
|
|
console.log('✅ BrainSteel Web Agents initialized');
|
|
});
|