6.1 KiB
Implementação — DT-10: Painel de Debug do Comando Gerado
Data: 01/03/2026
Status: ✅ Implementado
Prioridade: Baixa — melhoria de DX para usuário técnico
Arquivos afetados:
src/ui/components/execution_panel.rssrc/ui/app.rsPRD.md(documentação ao concluir)
Objetivo
Exibir, de forma colapsável na ExecutionPanel, o comando exato (ffmpeg … ou mkvmerge …) que foi enviado ao processo externo na última geração. Permite que o usuário técnico inspecione, copie e reproduza o comando manualmente para diagnóstico.
Viabilidade
| Ponto | Situação | ||
|---|---|---|---|
args: Vec<String> já construído antes do spawn |
start_generation() — linha ~244 de app.rs |
||
ExecutionPanel já usa ui.collapsing() |
Padrão reutilizado do "Log detalhado" | ||
| Nenhuma camada nova necessária | Mudanças em 2 arquivos apenas | ||
| Sem impacto em testes existentes | Campo additive — nenhuma assinatura pública muda | ||
| Botão "Copiar" sem dependência adicional | `ui.output_mut( | o | o.copied_text = …)` nativo do egui |
Estimativa: ~30 linhas adicionadas. Risco zero de regressão.
Passo 1 — Campo last_command em ExecutionPanel
Arquivo: src/ui/components/execution_panel.rs
Adicionar o campo à struct:
pub struct ExecutionPanel {
pub state: ExecutionState,
pub log_lines: Vec<String>,
/// Comando completo enviado ao FFmpeg/mkvmerge na última geração.
/// Exemplo: "ffmpeg -i input.mkv -c copy ... output.mkv"
pub last_command: Option<String>,
}
Inicializar em ExecutionPanel::new():
pub fn new() -> Self {
ExecutionPanel {
state: ExecutionState::Idle,
log_lines: Vec::new(),
last_command: None,
}
}
Passo 2 — Formatar e armazenar o comando em app.rs
Arquivo: src/ui/app.rs
Localização: método start_generation(), logo após construir args e antes do thread::spawn
// Formatar comando legível para o painel de debug
let binary = if uses_mkvmerge { "mkvmerge" } else { "ffmpeg" };
let cmd_str = format!(
"{} {}",
binary,
args.iter()
.map(|a| if a.contains(' ') { format!("\"{}\"", a) } else { a.clone() })
.collect::<Vec<_>>()
.join(" ")
);
self.execution_panel.last_command = Some(cmd_str);
Atenção: replicar o mesmo bloco em
start_batch_generation()para cobrir o modo Lote (RF-09).
Passo 3 — Renderizar o painel colapsável em ExecutionPanel::ui()
Arquivo: src/ui/components/execution_panel.rs
Localização: após o bloco "Log detalhado", antes do }); de fechamento do ui.group
if let Some(cmd) = &self.last_command {
ui.collapsing("🛠 Comando gerado", |ui| {
let mut cmd_str = cmd.as_str();
ui.add(
egui::TextEdit::multiline(&mut cmd_str)
.desired_rows(3)
.desired_width(f32::INFINITY)
.font(egui::TextStyle::Monospace),
);
if ui.small_button("📋 Copiar").clicked() {
ui.output_mut(|o| o.copied_text = cmd.clone());
}
});
}
Comportamento esperado:
- Colapsável fechado por padrão — não ocupa espaço visual desnecessário
TextEditsomente leitura (variável local imutável no contexto do egui)- Botão "📋 Copiar" coloca o comando no clipboard do sistema
- Argumento com espaço interno é envolvido em aspas para reprodutibilidade no terminal
Passo 4 — Comportamento de limpeza
last_command não é limpo ao iniciar nova geração — ele é sobrescrito. O usuário vê sempre o comando da execução atual.
last_command não é limpo em cancel_generation() — o usuário pode querer inspecionar o comando de uma geração cancelada.
Não há necessidade de resetar em nenhum outro ponto.
Passo 5 — Atualizar PRD e débitos técnicos
Ao concluir a implementação:
- Marcar DT-10 como
✅ Resolvidona tabela da seção 10 doPRD.md - Remover o item do backlog da seção 11
- Adicionar critério de aceitação na seção 12:
[x] O comando FFmpeg/mkvmerge gerado é exibido em painel colapsável na ExecutionPanel (DT-10)
Ordem de execução recomendada
| # | Passo | Testável após |
|---|---|---|
| 1 | Adicionar campo + init em ExecutionPanel |
cargo check |
| 2 | Renderizar painel colapsável (Passo 3) com valor hardcoded temporário | cargo run — inspeção visual |
| 3 | Wiring em start_generation() (Passo 2) |
cargo run — geração real |
| 4 | Replicar wiring em start_batch_generation() |
cargo run — modo lote |
| 5 | Remover hardcode temporário se usado; cargo test |
33 testes devem continuar passando |
| 6 | Atualizar PRD (Passo 5) | — |
Critério de aceitação
- O painel "🛠 Comando gerado" aparece na
ExecutionPanelapós a primeira geração - O painel está colapsado por padrão
- O conteúdo exibe o binário (
ffmpegoumkvmerge) seguido de todos os argumentos - Argumentos com espaços internos são envolvidos em aspas duplas
- O botão "📋 Copiar" coloca o texto no clipboard
- O comando é exibido também para gerações canceladas
- O painel não aparece antes da primeira geração (estado
Idleinicial) - Modo Lote exibe o comando do último item processado
cargo test— 68 testes passando sem regressão