From 93d9027e2c79a60989d566871f323110343a32c2 Mon Sep 17 00:00:00 2001 From: Frederico Castro Date: Thu, 26 Feb 2026 04:01:12 -0300 Subject: [PATCH] =?UTF-8?q?Continua=C3=A7=C3=A3o=20de=20conversa=20no=20te?= =?UTF-8?q?rminal,=20hist=C3=B3rico=20de=20agendamentos,=20webhooks=20e=20?= =?UTF-8?q?melhorias=20gerais?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Terminal com input de chat: após execução, permite continuar conversa com o agente via --resume do CLI, mantendo contexto da sessão (sessionId persistido) - Nova rota POST /api/agents/:id/continue para retomar sessões - Executor com função resume() para spawnar claude com --resume - Histórico de agendamentos agora busca do executionsStore (persistente) com dados completos: agente, tarefa, status, duração, custo e link para detalhes no modal - Execuções de agendamento tagueadas com source:'schedule' e scheduleId - Correção da expressão cron duplicada na UI de agendamentos - cronToHuman trata expressões com minuto específico (ex: 37 3 * * * → Todo dia às 03:37) - Botão "Copiar cURL" nos cards de webhook com payload de exemplo contextual - Webhooks component (webhooks.js) adicionado ao repositório --- package.json | 2 +- public/css/styles.css | 321 ++++++++++++++++++++++++++++++ public/index.html | 117 +++++++++++ public/js/api.js | 20 +- public/js/app.js | 168 +++++++++++++++- public/js/components/dashboard.js | 25 ++- public/js/components/history.js | 40 +++- public/js/components/pipelines.js | 37 +++- public/js/components/schedules.js | 98 +++++++-- public/js/components/terminal.js | 25 +++ public/js/components/webhooks.js | 257 ++++++++++++++++++++++++ server.js | 3 +- src/agents/executor.js | 160 +++++++++++++-- src/agents/manager.js | 74 ++++++- src/agents/pipeline.js | 116 ++++++++++- src/agents/scheduler.js | 2 +- src/routes/api.js | 218 +++++++++++++++++++- src/store/db.js | 1 + 18 files changed, 1609 insertions(+), 75 deletions(-) create mode 100644 public/js/components/webhooks.js diff --git a/package.json b/package.json index 93f9b46..176e463 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "agents-orchestrator", - "version": "1.0.0", + "version": "1.1.0", "description": "Painel administrativo para orquestração de agentes Claude Code", "main": "server.js", "type": "module", diff --git a/public/css/styles.css b/public/css/styles.css index 7dce52d..3813402 100644 --- a/public/css/styles.css +++ b/public/css/styles.css @@ -1029,6 +1029,17 @@ textarea { color: var(--success); } +.terminal-line.user-message { + border-left: 3px solid var(--accent); + padding-left: 8px; + margin: 6px 0; +} + +.terminal-line.user-message .content { + color: var(--accent); + font-weight: 500; +} + .terminal-line.info .content { color: var(--info); } @@ -2004,6 +2015,20 @@ tbody tr:hover td { color: var(--warning); } +.metric-card-icon--yellow { + background-color: rgba(250, 204, 21, 0.12); + color: #facc15; +} + +.metric-card-icon--cyan { + background-color: rgba(6, 182, 212, 0.12); + color: #06b6d4; +} + +.metric-card-value--sm { + font-size: 1.25rem; +} + .metric-card-body { display: flex; flex-direction: column; @@ -2619,6 +2644,55 @@ tbody tr:hover td { color: var(--text-muted); } +.terminal-input-bar { + border-top: 1px solid var(--border); + background-color: #0c0c14; + padding: 10px 16px; +} + +.terminal-input-context { + font-size: 11px; + color: var(--text-muted); + margin-bottom: 6px; + font-family: 'JetBrains Mono', monospace; +} + +.terminal-input-row { + display: flex; + align-items: center; + gap: 8px; +} + +.terminal-input-prompt { + color: var(--accent); + font-family: 'JetBrains Mono', monospace; + font-size: 14px; + font-weight: 600; + flex-shrink: 0; +} + +.terminal-input { + flex: 1; + background: transparent; + border: 1px solid var(--border); + border-radius: 6px; + padding: 8px 12px; + color: var(--text-primary); + font-family: 'JetBrains Mono', monospace; + font-size: 13px; + outline: none; + transition: border-color 0.2s; +} + +.terminal-input:focus { + border-color: var(--accent); +} + +.terminal-input::placeholder { + color: var(--text-muted); + opacity: 0.6; +} + .settings-grid { display: grid; grid-template-columns: repeat(2, 1fr); @@ -3721,3 +3795,250 @@ tbody tr:hover td { padding: 5px 10px; font-size: 12px; } + +.approval-notification { + padding: 12px 16px; + background: linear-gradient(135deg, rgba(245, 158, 11, 0.12), rgba(245, 158, 11, 0.05)); + border: 1px solid rgba(245, 158, 11, 0.3); + border-radius: 0; +} + +.approval-content { + display: flex; + align-items: center; + gap: 12px; +} + +.approval-icon { + color: var(--warning); + flex-shrink: 0; +} + +.approval-icon svg { + width: 20px; + height: 20px; +} + +.approval-text { + flex: 1; + display: flex; + flex-direction: column; + gap: 2px; +} + +.approval-text strong { + font-size: 13px; + color: var(--warning); +} + +.approval-text span { + font-size: 12px; + color: var(--text-secondary); +} + +.approval-actions { + display: flex; + gap: 8px; + flex-shrink: 0; +} + +.webhook-card { + background: var(--bg-card); + border: 1px solid var(--border-primary); + border-radius: 12px; + padding: 16px; + margin-bottom: 12px; + transition: border-color 0.2s; +} + +.webhook-card:hover { + border-color: var(--border-secondary); +} + +.webhook-card-header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 12px; +} + +.webhook-card-identity { + display: flex; + align-items: center; + gap: 8px; +} + +.webhook-card-name { + font-weight: 600; + font-size: 14px; + color: var(--text-primary); +} + +.webhook-card-actions { + display: flex; + gap: 4px; +} + +.webhook-card-body { + display: flex; + flex-direction: column; + gap: 10px; +} + +.webhook-card-target, +.webhook-card-url { + display: flex; + flex-direction: column; + gap: 4px; +} + +.webhook-card-label { + font-size: 11px; + color: var(--text-muted); + text-transform: uppercase; + letter-spacing: 0.05em; +} + +.webhook-card-value { + font-size: 13px; + color: var(--text-secondary); +} + +.webhook-url-field { + display: flex; + align-items: center; + gap: 8px; +} + +.webhook-url-code { + font-family: 'JetBrains Mono', monospace; + font-size: 11px; + color: var(--accent); + background: var(--bg-input); + padding: 6px 10px; + border-radius: 6px; + border: 1px solid var(--border-primary); + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + flex: 1; +} + +.webhook-card-curl { + padding-top: 6px; +} + +.webhook-card-meta { + display: flex; + gap: 16px; + padding-top: 8px; + border-top: 1px solid var(--border-primary); +} + +.webhook-meta-item { + display: flex; + align-items: center; + gap: 4px; + font-size: 12px; + color: var(--text-muted); +} + +.pipeline-step-approval { + display: flex; + align-items: center; + gap: 6px; + font-size: 12px; + color: var(--warning); + cursor: pointer; + padding: 4px 0; +} + +.pipeline-step-approval input[type="checkbox"] { + accent-color: var(--warning); + width: 14px; + height: 14px; + cursor: pointer; +} + +.cost-value { + color: #facc15; + font-family: 'JetBrains Mono', monospace; + font-weight: 500; +} + +.activity-item-cost { + font-family: 'JetBrains Mono', monospace; + font-size: 11px; + color: #facc15; +} + +.history-card-cost { + display: flex; + align-items: center; + gap: 3px; + font-family: 'JetBrains Mono', monospace; + font-size: 12px; + color: #facc15; +} + +.history-card-cost svg { + width: 12px; + height: 12px; +} + +.history-card-duration-group { + display: flex; + align-items: center; + gap: 12px; +} + +.pipeline-step-meta-group { + display: flex; + align-items: center; + gap: 10px; +} + +.pipeline-step-cost { + font-family: 'JetBrains Mono', monospace; + font-size: 12px; + color: #facc15; +} + +.badge-warning { + background-color: rgba(245, 158, 11, 0.15); + color: var(--warning); +} + +.badge--yellow { + background-color: rgba(245, 158, 11, 0.15); + color: var(--warning); +} + +.form-hint-block { + background: var(--bg-tertiary); + border: 1px solid var(--border-primary); + border-radius: 8px; + padding: 12px 14px; + font-size: 12px; + color: var(--text-secondary); +} + +.form-hint-block p { + margin-bottom: 6px; +} + +.form-hint-block p:last-child { + margin-bottom: 0; +} + +.form-hint-code { + font-family: 'JetBrains Mono', monospace; + font-size: 11px; + color: var(--accent); + background: var(--bg-input); + padding: 8px 10px; + border-radius: 6px; + margin-top: 4px; + display: block; + white-space: pre; +} diff --git a/public/index.html b/public/index.html index 96b0b60..a623da6 100644 --- a/public/index.html +++ b/public/index.html @@ -53,6 +53,12 @@ Pipelines +