feat(shuma): captura acotada + reproceso de salidas vía stdin
shuma-exec: cota dura de memoria. CommandSpec.capture_limit (bytes): pasado el tope se emite RunEvent::Truncated una vez y el resto se descarta —pero el pipe se sigue drenando, así el proceso no se bloquea y termina normal. CommandSpec.stdin_data alimenta un texto por la entrada estándar (escrito en su propio hilo). shuma-session: CommandRun.truncated. shuma-shell: tope de captura de 8 MiB por comando. Cada card con salida muestra «⤳ reprocesar» — al pulsarlo, el próximo comando filtra esa salida capturada (vía stdin) sin re-ejecutar el original; un banner marca el modo. Las cards truncadas avisan «⚠ truncado». shuma-exec: 12 tests (incluye truncado y reproceso por stdin). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -60,6 +60,8 @@ pub struct CommandRun {
|
||||
pub exit_code: Option<i32>,
|
||||
/// Salida — cada línea sabe si es de stdout o de stderr.
|
||||
pub output: Vec<OutputLine>,
|
||||
/// `true` si la salida superó el tope de captura y se descartó parte.
|
||||
pub truncated: bool,
|
||||
/// Segundo Unix en que arrancó.
|
||||
pub started_at: u64,
|
||||
/// Segundo Unix en que terminó.
|
||||
@@ -167,12 +169,20 @@ impl WorkSession {
|
||||
status: RunStatus::Running,
|
||||
exit_code: None,
|
||||
output: Vec::new(),
|
||||
truncated: false,
|
||||
started_at: now,
|
||||
finished_at: None,
|
||||
});
|
||||
id
|
||||
}
|
||||
|
||||
/// Marca que la salida de un comando se truncó al tope de captura.
|
||||
pub fn mark_truncated(&mut self, id: RunId) {
|
||||
if let Some(r) = self.run_mut(id) {
|
||||
r.truncated = true;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run(&self, id: RunId) -> Option<&CommandRun> {
|
||||
self.history.iter().find(|r| r.id == id)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user