Files
Agents-Orchestrator/public/index.html
Frederico Castro 2f7a9d4c56 Implementação completa de funcionalidades pendentes
- Settings persistentes (modelo padrão, workdir, max concurrent)
- Import/export de agentes via JSON
- Agendamentos persistentes com restore no startup
- Edição de agendamentos e tarefas existentes
- Filtros e busca em todas as seções
- Isolamento de WebSocket por clientId
- Autenticação via AUTH_TOKEN e CORS configurável
- Graceful shutdown com cancelamento de execuções
- Correção: --max-tokens removido (flag inválida do CLI)
- Correção: pipeline agora verifica exit code e propaga erros
- Correção: streaming de output em pipelines via WebSocket
- Permission mode bypassPermissions como padrão
- Página de configurações do sistema
- Contagem diária de execuções no dashboard
- Histórico de execuções recentes
2026-02-26 01:24:51 -03:00

964 lines
42 KiB
HTML

<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Agents Orchestrator</title>
<link rel="stylesheet" href="css/styles.css" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet" />
</head>
<body>
<div class="layout">
<aside class="sidebar">
<div class="sidebar-logo">
<div class="sidebar-logo-icon">
<i data-lucide="bot"></i>
</div>
<span class="sidebar-logo-text">Agents Orchestrator</span>
</div>
<nav class="sidebar-nav">
<ul class="sidebar-nav-list">
<li class="sidebar-nav-item">
<a href="#" class="sidebar-nav-link" data-section="dashboard">
<i data-lucide="layout-dashboard"></i>
<span>Dashboard</span>
</a>
</li>
<li class="sidebar-nav-item">
<a href="#" class="sidebar-nav-link" data-section="agents">
<i data-lucide="cpu"></i>
<span>Agentes</span>
</a>
</li>
<li class="sidebar-nav-item">
<a href="#" class="sidebar-nav-link" data-section="tasks">
<i data-lucide="list-checks"></i>
<span>Tarefas</span>
</a>
</li>
<li class="sidebar-nav-item">
<a href="#" class="sidebar-nav-link" data-section="schedules">
<i data-lucide="clock"></i>
<span>Agendamentos</span>
</a>
</li>
<li class="sidebar-nav-item" data-section="pipelines">
<a class="sidebar-nav-link" href="#" data-section="pipelines">
<i data-lucide="git-merge" class="nav-icon"></i>
<span>Pipelines</span>
</a>
</li>
<li class="sidebar-nav-item">
<a href="#" class="sidebar-nav-link" data-section="terminal">
<i data-lucide="terminal"></i>
<span>Terminal</span>
</a>
</li>
<li class="sidebar-nav-item">
<a href="#" class="sidebar-nav-link" data-section="settings">
<i data-lucide="settings"></i>
<span>Configurações</span>
</a>
</li>
</ul>
</nav>
<div class="sidebar-footer">
<div class="ws-status" id="ws-status">
<span class="ws-indicator ws-indicator--disconnected" id="ws-indicator"></span>
<span class="ws-label" id="ws-label">Desconectado</span>
</div>
</div>
</aside>
<div class="main-wrapper">
<header class="main-header">
<div class="header-breadcrumb">
<h1 class="header-title" id="header-title">Dashboard</h1>
</div>
<div class="header-actions">
<div class="header-badge" id="active-executions-badge" aria-label="Execuções ativas">
<i data-lucide="activity"></i>
<span id="active-executions-count">0</span>
<span class="header-badge-label">ativas</span>
</div>
<button class="btn btn--ghost btn--icon-text" id="system-status-btn" type="button" aria-label="Status do sistema">
<i data-lucide="server"></i>
<span>Sistema</span>
</button>
<button class="btn btn--ghost btn--icon-text" id="import-agent-btn" type="button">
<i data-lucide="upload"></i>
<span>Importar</span>
</button>
<button class="btn btn--primary btn--icon-text" id="new-agent-btn" type="button">
<i data-lucide="plus"></i>
<span>Novo Agente</span>
</button>
</div>
</header>
<main class="main-content">
<section id="dashboard" class="section active" aria-label="Dashboard">
<div class="metrics-grid">
<article class="metric-card">
<div class="metric-card-icon metric-card-icon--indigo">
<i data-lucide="cpu"></i>
</div>
<div class="metric-card-body">
<span class="metric-card-label">Total de Agentes</span>
<span class="metric-card-value" id="metric-total-agents">0</span>
</div>
</article>
<article class="metric-card">
<div class="metric-card-icon metric-card-icon--green">
<i data-lucide="zap"></i>
</div>
<div class="metric-card-body">
<span class="metric-card-label">Agentes Ativos</span>
<span class="metric-card-value" id="metric-active-agents">0</span>
</div>
</article>
<article class="metric-card">
<div class="metric-card-icon metric-card-icon--purple">
<i data-lucide="play-circle"></i>
</div>
<div class="metric-card-body">
<span class="metric-card-label">Execuções Hoje</span>
<span class="metric-card-value" id="metric-executions-today">0</span>
</div>
</article>
<article class="metric-card">
<div class="metric-card-icon metric-card-icon--orange">
<i data-lucide="clock"></i>
</div>
<div class="metric-card-body">
<span class="metric-card-label">Agendamentos</span>
<span class="metric-card-value" id="metric-schedules">0</span>
</div>
</article>
</div>
<div class="dashboard-grid">
<div class="card">
<div class="card-header">
<h2 class="card-title">Atividade Recente</h2>
<button class="btn btn--ghost btn--sm" type="button" id="refresh-activity-btn">
<i data-lucide="refresh-cw"></i>
</button>
</div>
<div class="card-body">
<ul class="activity-list" id="activity-list">
<li class="activity-empty">
<i data-lucide="inbox"></i>
<span>Nenhuma execução recente</span>
</li>
</ul>
</div>
</div>
<div class="card">
<div class="card-header">
<h2 class="card-title">Status do Sistema</h2>
</div>
<div class="card-body">
<ul class="system-status-list" id="system-status-list">
<li class="system-status-item">
<div class="system-status-info">
<i data-lucide="server"></i>
<span>Servidor HTTP</span>
</div>
<span class="badge badge--green">Online</span>
</li>
<li class="system-status-item">
<div class="system-status-info">
<i data-lucide="radio"></i>
<span>WebSocket</span>
</div>
<span class="badge badge--red" id="system-ws-status-badge">Desconectado</span>
</li>
<li class="system-status-item">
<div class="system-status-info">
<i data-lucide="database"></i>
<span>Armazenamento</span>
</div>
<span class="badge badge--green">OK</span>
</li>
<li class="system-status-item">
<div class="system-status-info">
<i data-lucide="terminal"></i>
<span>Claude CLI</span>
</div>
<span class="badge badge--gray" id="system-claude-status-badge">Verificando...</span>
</li>
</ul>
</div>
</div>
</div>
</section>
<section id="agents" class="section" aria-label="Agentes" hidden>
<div class="section-toolbar">
<div class="search-field">
<i data-lucide="search"></i>
<input type="search" placeholder="Buscar agentes..." id="agents-search" aria-label="Buscar agentes" />
</div>
<div class="section-toolbar-actions">
<select class="select" id="agents-filter-status" aria-label="Filtrar por status">
<option value="">Todos os status</option>
<option value="active">Ativo</option>
<option value="inactive">Inativo</option>
</select>
</div>
</div>
<div class="agents-grid" id="agents-grid">
<div class="empty-state" id="agents-empty-state">
<div class="empty-state-icon">
<i data-lucide="bot"></i>
</div>
<h3 class="empty-state-title">Nenhum agente cadastrado</h3>
<p class="empty-state-desc">Crie seu primeiro agente para começar a orquestrar tarefas com Claude.</p>
<button class="btn btn--primary btn--icon-text" type="button" id="agents-empty-new-btn">
<i data-lucide="plus"></i>
<span>Criar Agente</span>
</button>
</div>
</div>
</section>
<section id="tasks" class="section" aria-label="Tarefas" hidden>
<div class="section-toolbar">
<div class="search-field">
<i data-lucide="search"></i>
<input type="search" placeholder="Buscar tarefas..." id="tasks-search" aria-label="Buscar tarefas" />
</div>
<div class="section-toolbar-actions">
<select class="select" id="tasks-filter-category" aria-label="Filtrar por categoria">
<option value="">Todas as categorias</option>
<option value="code-review">Code Review</option>
<option value="security">Segurança</option>
<option value="refactor">Refatoração</option>
<option value="tests">Testes</option>
<option value="docs">Documentação</option>
<option value="performance">Performance</option>
</select>
<button class="btn btn--primary btn--icon-text" type="button" id="tasks-new-btn">
<i data-lucide="plus"></i>
<span>Nova Tarefa</span>
</button>
</div>
</div>
<div class="tasks-grid" id="tasks-grid">
<div class="empty-state" id="tasks-empty-state">
<div class="empty-state-icon">
<i data-lucide="list-checks"></i>
</div>
<h3 class="empty-state-title">Nenhuma tarefa cadastrada</h3>
<p class="empty-state-desc">Crie templates de tarefas para reutilizar em diferentes agentes.</p>
<button class="btn btn--primary btn--icon-text" type="button" id="tasks-empty-new-btn">
<i data-lucide="plus"></i>
<span>Criar Tarefa</span>
</button>
</div>
</div>
</section>
<section id="schedules" class="section" aria-label="Agendamentos" hidden>
<div class="section-toolbar">
<div class="search-field">
<i data-lucide="search"></i>
<input type="search" placeholder="Buscar agendamentos..." id="schedules-search" aria-label="Buscar agendamentos" />
</div>
<div class="section-toolbar-actions">
<select class="select" id="schedules-filter-status" aria-label="Filtrar por status">
<option value="">Todos</option>
<option value="active">Ativo</option>
<option value="paused">Pausado</option>
</select>
<button class="btn btn--primary btn--icon-text" type="button" id="schedules-new-btn">
<i data-lucide="plus"></i>
<span>Novo Agendamento</span>
</button>
</div>
</div>
<div class="card">
<div class="table-wrapper">
<table class="table" id="schedules-table">
<colgroup>
<col style="width: 15%">
<col style="width: 30%">
<col style="width: 18%">
<col style="width: 17%">
<col style="width: 8%">
<col style="width: 12%">
</colgroup>
<thead>
<tr>
<th scope="col">Agente</th>
<th scope="col">Tarefa</th>
<th scope="col">Expressão Cron</th>
<th scope="col">Próxima Execução</th>
<th scope="col">Status</th>
<th scope="col" aria-label="Ações"></th>
</tr>
</thead>
<tbody id="schedules-tbody">
<tr class="table-empty-row">
<td colspan="6">
<div class="empty-state empty-state--inline">
<i data-lucide="clock"></i>
<span>Nenhum agendamento configurado</span>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="card" style="margin-top: 1rem;">
<div class="card-header">
<h2 class="card-title">Histórico de Disparos</h2>
</div>
<div class="card-body" id="schedules-history">
<p class="empty-state-desc">Nenhum disparo registrado</p>
</div>
</div>
</section>
<section id="pipelines" class="section" aria-label="Pipelines" hidden>
<div class="page-title">Pipelines</div>
<div class="page-subtitle">Encadeie agentes para fluxos de trabalho automatizados</div>
<div class="section-toolbar">
<div class="search-field">
<i data-lucide="search" class="search-icon" style="width:16px;height:16px"></i>
<input type="text" placeholder="Buscar pipelines..." id="pipelines-search">
</div>
<div class="section-toolbar-actions">
<button class="btn btn--primary btn--icon-text" type="button" id="pipelines-new-btn">
<i data-lucide="plus"></i>
<span>Novo Pipeline</span>
</button>
</div>
</div>
<div id="pipelines-grid" class="agents-grid">
</div>
</section>
<section id="terminal" class="section" aria-label="Terminal" hidden>
<div class="terminal-wrapper">
<div class="terminal-toolbar">
<div class="terminal-toolbar-left">
<div class="terminal-dot terminal-dot--red"></div>
<div class="terminal-dot terminal-dot--yellow"></div>
<div class="terminal-dot terminal-dot--green"></div>
<span class="terminal-title">Output de Execução</span>
</div>
<div class="terminal-toolbar-right">
<select class="select select--sm" id="terminal-execution-select" aria-label="Selecionar execução">
<option value="">Selecionar execução...</option>
</select>
<div class="terminal-ws-indicator" id="terminal-ws-indicator">
<span class="ws-indicator ws-indicator--disconnected" id="terminal-ws-dot"></span>
<span id="terminal-ws-label">Desconectado</span>
</div>
<button class="btn btn--ghost btn--sm btn--icon-text" type="button" id="terminal-clear-btn" aria-label="Limpar terminal">
<i data-lucide="trash-2"></i>
<span>Limpar</span>
</button>
</div>
</div>
<div class="terminal-output" id="terminal-output" role="log" aria-live="polite" aria-label="Saída do terminal">
<div class="terminal-welcome">
<span class="terminal-prompt">$</span>
<span class="terminal-text">Aguardando execução de agente...</span>
</div>
</div>
</div>
</section>
<section id="settings" class="section" aria-label="Configurações" hidden>
<div class="settings-grid">
<div class="card">
<div class="card-header">
<h2 class="card-title">Configurações Gerais</h2>
</div>
<div class="card-body">
<form class="settings-form" id="settings-form" novalidate>
<div class="form-group">
<label class="form-label" for="settings-default-model">Modelo Padrão</label>
<select class="select" id="settings-default-model" name="defaultModel">
<option value="claude-sonnet-4-6">claude-sonnet-4-6</option>
<option value="claude-opus-4-6">claude-opus-4-6</option>
<option value="claude-haiku-4-5-20251001">claude-haiku-4-5-20251001</option>
</select>
</div>
<div class="form-group">
<label class="form-label" for="settings-default-workdir">Diretório de Trabalho Padrão</label>
<input
type="text"
class="input"
id="settings-default-workdir"
name="defaultWorkdir"
placeholder="/home/fred/projetos"
/>
</div>
<div class="form-group">
<label class="form-label" for="settings-max-concurrent">Execuções Simultâneas Máximas</label>
<input
type="number"
class="input"
id="settings-max-concurrent"
name="maxConcurrent"
min="1"
max="20"
placeholder="5"
/>
</div>
<div class="form-actions">
<button type="submit" class="btn btn--primary">Salvar Configurações</button>
</div>
</form>
</div>
</div>
<div class="card">
<div class="card-header">
<h2 class="card-title">Informações do Sistema</h2>
</div>
<div class="card-body">
<ul class="system-info-list" id="system-info-list">
<li class="system-info-item">
<span class="system-info-label">Versão do Servidor</span>
<span class="system-info-value" id="info-server-version">1.0.0</span>
</li>
<li class="system-info-item">
<span class="system-info-label">Versão do Node.js</span>
<span class="system-info-value font-mono" id="info-node-version">Carregando...</span>
</li>
<li class="system-info-item">
<span class="system-info-label">Versão do Claude CLI</span>
<span class="system-info-value font-mono" id="info-claude-version">Carregando...</span>
</li>
<li class="system-info-item">
<span class="system-info-label">Plataforma</span>
<span class="system-info-value font-mono" id="info-platform">Carregando...</span>
</li>
<li class="system-info-item">
<span class="system-info-label">Tempo Online</span>
<span class="system-info-value font-mono" id="info-uptime">Carregando...</span>
</li>
</ul>
</div>
</div>
</div>
</section>
</main>
</div>
</div>
<div class="modal-overlay" id="agent-modal-overlay" role="dialog" aria-modal="true" aria-labelledby="agent-modal-title" hidden>
<div class="modal modal--lg">
<div class="modal-header">
<h2 class="modal-title" id="agent-modal-title">Novo Agente</h2>
<button class="modal-close" type="button" aria-label="Fechar modal" data-modal-close="agent-modal-overlay">
<i data-lucide="x"></i>
</button>
</div>
<div class="modal-body">
<form class="modal-form" id="agent-form" novalidate>
<input type="hidden" id="agent-form-id" name="id" />
<div class="form-row">
<div class="form-group form-group--grow">
<label class="form-label" for="agent-name">
Nome do Agente
<span class="form-required" aria-hidden="true">*</span>
</label>
<input
type="text"
class="input"
id="agent-name"
name="name"
placeholder="Ex: Revisor de Código"
required
autocomplete="off"
/>
</div>
<div class="form-group">
<label class="form-label" for="agent-status-toggle">Status</label>
<div class="toggle-wrapper">
<input type="checkbox" class="toggle-input" id="agent-status-toggle" name="active" role="switch" />
<label class="toggle-label" for="agent-status-toggle">
<span class="toggle-thumb"></span>
<span class="toggle-text-on">Ativo</span>
<span class="toggle-text-off">Inativo</span>
</label>
</div>
</div>
</div>
<div class="form-group">
<label class="form-label" for="agent-description">Descrição</label>
<textarea
class="textarea"
id="agent-description"
name="description"
rows="2"
placeholder="Descreva brevemente o propósito deste agente"
></textarea>
</div>
<div class="form-group">
<label class="form-label" for="agent-system-prompt">
System Prompt
</label>
<textarea
class="textarea textarea--code"
id="agent-system-prompt"
name="systemPrompt"
rows="6"
placeholder="Você é um especialista em... Seu objetivo é... Sempre responda em português..."
></textarea>
<p class="form-hint">Instruções base que definem o comportamento, personalidade e restrições do agente.</p>
</div>
<div class="form-row">
<div class="form-group form-group--grow">
<label class="form-label" for="agent-model">Modelo</label>
<select class="select" id="agent-model" name="model">
<option value="claude-sonnet-4-6">claude-sonnet-4-6</option>
<option value="claude-opus-4-6">claude-opus-4-6</option>
<option value="claude-haiku-4-5-20251001">claude-haiku-4-5-20251001</option>
</select>
</div>
<div class="form-group form-group--grow">
<label class="form-label" for="agent-workdir">Diretório de Trabalho</label>
<input
type="text"
class="input"
id="agent-workdir"
name="workdir"
placeholder="/home/fred/projetos"
autocomplete="off"
/>
</div>
</div>
<div class="form-row">
<div class="form-group form-group--grow">
<label class="form-label" for="agent-allowed-tools">Ferramentas Permitidas</label>
<input
type="text"
class="input"
id="agent-allowed-tools"
name="allowedTools"
placeholder="Bash,Read,Write,Glob,Grep"
autocomplete="off"
/>
<p class="form-hint">Lista separada por vírgula. Vazio = todas permitidas.</p>
</div>
<div class="form-group">
<label class="form-label" for="agent-max-turns">Max Turns</label>
<input
type="number"
class="input"
id="agent-max-turns"
name="maxTurns"
min="0"
max="100"
value="0"
/>
<p class="form-hint">Limite de turnos agênticos. 0 = sem limite.</p>
</div>
<div class="form-group">
<label class="form-label" for="agent-permission-mode">Permission Mode</label>
<select class="select" id="agent-permission-mode" name="permissionMode">
<option value="">Padrão</option>
<option value="default">default</option>
<option value="plan">plan</option>
<option value="acceptEdits">acceptEdits</option>
<option value="bypassPermissions">bypassPermissions</option>
</select>
</div>
</div>
<div class="form-group">
<label class="form-label" for="agent-tags-input">Tags</label>
<div class="tags-input-wrapper" id="agent-tags-wrapper">
<div class="tags-chips" id="agent-tags-chips"></div>
<input
type="text"
class="tags-input"
id="agent-tags-input"
placeholder="Digite e pressione Enter para adicionar"
autocomplete="off"
/>
</div>
<input type="hidden" id="agent-tags" name="tags" value="[]" />
</div>
</form>
</div>
<div class="modal-footer">
<button class="btn btn--ghost" type="button" data-modal-close="agent-modal-overlay">Cancelar</button>
<button class="btn btn--primary" type="submit" form="agent-form" id="agent-form-submit">Salvar</button>
</div>
</div>
</div>
<div class="modal-overlay" id="execute-modal-overlay" role="dialog" aria-modal="true" aria-labelledby="execute-modal-title" hidden>
<div class="modal modal--md">
<div class="modal-header">
<h2 class="modal-title" id="execute-modal-title">Executar Tarefa</h2>
<button class="modal-close" type="button" aria-label="Fechar modal" data-modal-close="execute-modal-overlay">
<i data-lucide="x"></i>
</button>
</div>
<div class="modal-body">
<form class="modal-form" id="execute-form" novalidate>
<input type="hidden" id="execute-agent-id" name="agentId" />
<div class="form-group" id="execute-agent-select-group">
<label class="form-label" for="execute-agent-select">
Agente
<span class="form-required" aria-hidden="true">*</span>
</label>
<select class="select" id="execute-agent-select" name="agentSelect" required>
<option value="">Selecionar agente...</option>
</select>
</div>
<div class="form-group">
<label class="form-label" for="execute-task-desc">
Descrição da Tarefa
<span class="form-required" aria-hidden="true">*</span>
</label>
<textarea
class="textarea"
id="execute-task-desc"
name="task"
rows="3"
placeholder="Descreva o que o agente deve fazer..."
required
></textarea>
</div>
<div class="form-group">
<label class="form-label" for="execute-instructions">Instruções Adicionais</label>
<textarea
class="textarea textarea--code"
id="execute-instructions"
name="instructions"
rows="3"
placeholder="Contexto adicional, restrições ou preferências..."
></textarea>
</div>
<div class="quick-templates">
<p class="quick-templates-label">Templates rápidos</p>
<div class="quick-templates-grid">
<button class="template-btn" type="button" data-template="Analisar código e detectar bugs, vulnerabilidades e problemas de qualidade. Forneça um relatório detalhado com sugestões de correção.">
<i data-lucide="bug"></i>
<span>Detectar Bugs</span>
</button>
<button class="template-btn" type="button" data-template="Realizar revisão de segurança seguindo as diretrizes OWASP Top 10. Identificar vulnerabilidades, inputs não validados e problemas de autenticação/autorização.">
<i data-lucide="shield"></i>
<span>Revisão OWASP</span>
</button>
<button class="template-btn" type="button" data-template="Refatorar o código para melhorar legibilidade, manutenibilidade e aderência às boas práticas. Manter comportamento funcional intacto.">
<i data-lucide="wand-2"></i>
<span>Refatorar Código</span>
</button>
<button class="template-btn" type="button" data-template="Escrever testes unitários e de integração abrangentes. Garantir cobertura dos casos de sucesso, erro e edge cases.">
<i data-lucide="test-tube-2"></i>
<span>Escrever Testes</span>
</button>
<button class="template-btn" type="button" data-template="Documentar o código com JSDoc/docstrings, README atualizado, exemplos de uso e descrição de APIs públicas.">
<i data-lucide="book-open"></i>
<span>Documentar Código</span>
</button>
<button class="template-btn" type="button" data-template="Analisar e otimizar a performance do código. Identificar gargalos, reduzir complexidade algorítmica e melhorar uso de memória.">
<i data-lucide="gauge"></i>
<span>Otimizar Performance</span>
</button>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button class="btn btn--ghost" type="button" data-modal-close="execute-modal-overlay">Cancelar</button>
<button class="btn btn--primary btn--icon-text" type="submit" form="execute-form" id="execute-form-submit">
<i data-lucide="play"></i>
<span>Executar</span>
</button>
</div>
</div>
</div>
<div class="modal-overlay" id="schedule-modal-overlay" role="dialog" aria-modal="true" aria-labelledby="schedule-modal-title" hidden>
<div class="modal modal--md">
<div class="modal-header">
<h2 class="modal-title" id="schedule-modal-title">Novo Agendamento</h2>
<button class="modal-close" type="button" aria-label="Fechar modal" data-modal-close="schedule-modal-overlay">
<i data-lucide="x"></i>
</button>
</div>
<div class="modal-body">
<form class="modal-form" id="schedule-form" novalidate>
<input type="hidden" id="schedule-form-id" name="id" />
<div class="form-group">
<label class="form-label" for="schedule-agent">
Agente
<span class="form-required" aria-hidden="true">*</span>
</label>
<select class="select" id="schedule-agent" name="agentId" required>
<option value="">Selecionar agente...</option>
</select>
</div>
<div class="form-group">
<label class="form-label" for="schedule-task">
Descrição da Tarefa
<span class="form-required" aria-hidden="true">*</span>
</label>
<textarea
class="textarea"
id="schedule-task"
name="task"
rows="3"
placeholder="Descreva a tarefa que será executada automaticamente..."
required
></textarea>
</div>
<div class="form-group">
<label class="form-label" for="schedule-cron">
Expressão Cron
<span class="form-required" aria-hidden="true">*</span>
</label>
<input
type="text"
class="input input--mono"
id="schedule-cron"
name="cron"
placeholder="0 * * * *"
required
autocomplete="off"
aria-describedby="schedule-cron-hint"
/>
<p class="form-hint" id="schedule-cron-hint">Formato: minuto hora dia-mês mês dia-semana</p>
</div>
<div class="cron-presets">
<p class="cron-presets-label">Presets</p>
<div class="cron-presets-list">
<button class="cron-preset-btn" type="button" data-cron="0 * * * *">
<span class="cron-preset-name">A cada hora</span>
<span class="cron-preset-expr">0 * * * *</span>
</button>
<button class="cron-preset-btn" type="button" data-cron="0 9 * * *">
<span class="cron-preset-name">Diário (09:00)</span>
<span class="cron-preset-expr">0 9 * * *</span>
</button>
<button class="cron-preset-btn" type="button" data-cron="0 9 * * 1">
<span class="cron-preset-name">Semanal (seg 09:00)</span>
<span class="cron-preset-expr">0 9 * * 1</span>
</button>
<button class="cron-preset-btn" type="button" data-cron="0 0 1 * *">
<span class="cron-preset-name">Mensal (dia 1)</span>
<span class="cron-preset-expr">0 0 1 * *</span>
</button>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button class="btn btn--ghost" type="button" data-modal-close="schedule-modal-overlay">Cancelar</button>
<button class="btn btn--primary btn--icon-text" type="submit" form="schedule-form" id="schedule-form-submit">
<i data-lucide="clock"></i>
<span>Agendar</span>
</button>
</div>
</div>
</div>
<div class="modal-overlay" id="pipeline-modal-overlay" role="dialog" aria-modal="true" aria-labelledby="pipeline-modal-title" hidden>
<div class="modal modal--lg">
<div class="modal-header">
<h2 class="modal-title" id="pipeline-modal-title">Novo Pipeline</h2>
<button class="modal-close" type="button" aria-label="Fechar modal" data-modal-close="pipeline-modal-overlay">
<i data-lucide="x"></i>
</button>
</div>
<div class="modal-body">
<form class="modal-form" id="pipeline-form" novalidate>
<input type="hidden" id="pipeline-form-id">
<div class="form-group">
<label class="form-label" for="pipeline-name">
Nome
<span class="form-required" aria-hidden="true">*</span>
</label>
<input class="input" type="text" id="pipeline-name" placeholder="Ex: Análise e Correção de Bugs" required>
</div>
<div class="form-group">
<label class="form-label" for="pipeline-description">Descrição</label>
<textarea class="textarea" id="pipeline-description" rows="2" placeholder="Descreva o objetivo do pipeline..."></textarea>
</div>
<div class="form-group">
<label class="form-label">
Passos do Pipeline
<span class="form-required" aria-hidden="true">*</span>
</label>
<p class="form-hint mb-8">Cada passo usa um agente. O output de um passo vira o input do próximo.</p>
<div id="pipeline-steps-container"></div>
<button class="btn btn--ghost btn--sm mt-8" type="button" id="pipeline-add-step-btn">
<i data-lucide="plus" style="width:14px;height:14px"></i>
Adicionar Passo
</button>
</div>
</form>
</div>
<div class="modal-footer">
<button class="btn btn--ghost" type="button" data-modal-close="pipeline-modal-overlay">Cancelar</button>
<button class="btn btn--primary" type="button" id="pipeline-form-submit">Salvar Pipeline</button>
</div>
</div>
</div>
<div class="modal-overlay" id="pipeline-execute-modal-overlay" role="dialog" aria-modal="true" aria-labelledby="pipeline-execute-title" hidden>
<div class="modal modal--md">
<div class="modal-header">
<h2 class="modal-title" id="pipeline-execute-title">Executar Pipeline</h2>
<button class="modal-close" type="button" aria-label="Fechar modal" data-modal-close="pipeline-execute-modal-overlay">
<i data-lucide="x"></i>
</button>
</div>
<div class="modal-body">
<input type="hidden" id="pipeline-execute-id">
<div class="form-group">
<label class="form-label" for="pipeline-execute-input">
Input Inicial
<span class="form-required" aria-hidden="true">*</span>
</label>
<textarea class="textarea" id="pipeline-execute-input" rows="4" placeholder="Descreva a tarefa inicial para o pipeline..."></textarea>
</div>
</div>
<div class="modal-footer">
<button class="btn btn--ghost" type="button" data-modal-close="pipeline-execute-modal-overlay">Cancelar</button>
<button class="btn btn--primary btn--icon-text" type="button" id="pipeline-execute-submit">
<i data-lucide="play" style="width:14px;height:14px"></i>
<span>Executar</span>
</button>
</div>
</div>
</div>
<div class="modal-overlay" id="confirm-modal-overlay" role="dialog" aria-modal="true" aria-labelledby="confirm-modal-title" hidden>
<div class="modal modal--sm">
<div class="modal-header">
<div class="confirm-modal-icon" id="confirm-modal-icon">
<i data-lucide="alert-triangle"></i>
</div>
<h2 class="modal-title" id="confirm-modal-title">Confirmar Ação</h2>
<button class="modal-close" type="button" aria-label="Fechar modal" data-modal-close="confirm-modal-overlay">
<i data-lucide="x"></i>
</button>
</div>
<div class="modal-body">
<p class="confirm-modal-message" id="confirm-modal-message"></p>
</div>
<div class="modal-footer">
<button class="btn btn--ghost" type="button" data-modal-close="confirm-modal-overlay">Cancelar</button>
<button class="btn btn--danger" type="button" id="confirm-modal-confirm-btn">Confirmar</button>
</div>
</div>
</div>
<div class="modal-overlay" id="export-modal-overlay" role="dialog" aria-modal="true" aria-labelledby="export-modal-title" hidden>
<div class="modal modal--md">
<div class="modal-header">
<h2 class="modal-title" id="export-modal-title">Exportar Agente</h2>
<button class="modal-close" type="button" aria-label="Fechar modal" data-modal-close="export-modal-overlay">
<i data-lucide="x"></i>
</button>
</div>
<div class="modal-body">
<div class="export-code-wrapper">
<div class="export-code-toolbar">
<span class="export-code-label">JSON</span>
<button class="btn btn--ghost btn--sm btn--icon-text" type="button" id="export-copy-btn" aria-label="Copiar JSON">
<i data-lucide="copy"></i>
<span>Copiar</span>
</button>
</div>
<pre class="export-code" id="export-code-content" tabindex="0" aria-label="Dados do agente em formato JSON"></pre>
</div>
</div>
<div class="modal-footer">
<button class="btn btn--ghost" type="button" data-modal-close="export-modal-overlay">Fechar</button>
</div>
</div>
</div>
<div class="modal-overlay" id="import-modal-overlay" role="dialog" aria-modal="true" aria-labelledby="import-modal-title" hidden>
<div class="modal modal--md">
<div class="modal-header">
<h2 class="modal-title" id="import-modal-title">Importar Agente</h2>
<button class="modal-close" type="button" aria-label="Fechar modal" data-modal-close="import-modal-overlay">
<i data-lucide="x"></i>
</button>
</div>
<div class="modal-body">
<div class="form-group">
<label class="form-label" for="import-json-content">JSON do Agente</label>
<textarea
class="textarea textarea--code"
id="import-json-content"
rows="10"
placeholder="Cole aqui o JSON exportado do agente..."
></textarea>
<p class="form-hint">Cole o JSON gerado pela função de exportar agente.</p>
</div>
</div>
<div class="modal-footer">
<button class="btn btn--ghost" type="button" data-modal-close="import-modal-overlay">Cancelar</button>
<button class="btn btn--primary btn--icon-text" type="button" id="import-confirm-btn">
<i data-lucide="upload"></i>
<span>Importar</span>
</button>
</div>
</div>
</div>
<div class="toast-container" id="toast-container" aria-live="assertive" aria-atomic="false" role="region" aria-label="Notificações"></div>
<script src="https://unpkg.com/lucide@latest/dist/umd/lucide.js"></script>
<script src="js/api.js"></script>
<script src="js/components/toast.js"></script>
<script src="js/components/modal.js"></script>
<script src="js/components/terminal.js"></script>
<script src="js/components/agents.js"></script>
<script src="js/components/dashboard.js"></script>
<script src="js/components/tasks.js"></script>
<script src="js/components/schedules.js"></script>
<script src="js/components/pipelines.js"></script>
<script src="js/components/settings.js"></script>
<script src="js/app.js"></script>
<script>
lucide.createIcons();
App.init();
</script>
</body>
</html>