diag(tui): trace view_stack push/pop for post-mortem black-screen repro

Maintainer-reported (handoff): after spawning a sub-agent in YOLO, the
transcript renders solid black and scroll keys go dead, but footer +
sidebar still render fine. The shape (black + dead input together)
strongly suggests a `View` is on the stack that returns empty layout
AND intercepts key events at the top level. The fix wants a tighter
repro than we have today.

Add `tracing::debug!` to every push / push_boxed / pop on `ViewStack`
and to the implicit pops in `apply_action` (Close + EmitAndClose).
Each line carries the `ModalKind` and post-action depth, so a future
`RUST_LOG=deepseek_tui::view_stack=debug` capture will show exactly
which view stayed pushed when the symptom recurred.

No behavior change. The handoff explicitly suggested this as the
first-look diagnostic step; we ship the diagnostic now so the next
report comes with evidence.

Refs the unresolved sub-agent black-transcript symptom captured in
session-3 handoff. Will surface to a tracking issue once we have a
concrete repro from the maintainer.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Hunter Bown
2026-05-04 20:17:43 -05:00
parent f6e4f634d4
commit cba5e829fc
+15 -3
View File
@@ -235,18 +235,26 @@ impl ViewStack {
}
pub fn push<V: ModalView + 'static>(&mut self, view: V) {
let kind = view.kind();
self.views.push(Box::new(view));
tracing::debug!(target: "deepseek_tui::view_stack", action = "push", kind = ?kind, depth = self.views.len(), "view pushed");
}
/// Push an already-boxed view back onto the stack. Used by call sites
/// that pop a view, mutate it externally, and need to restore it without
/// the generic `push` re-boxing dance.
pub fn push_boxed(&mut self, view: Box<dyn ModalView>) {
let kind = view.kind();
self.views.push(view);
tracing::debug!(target: "deepseek_tui::view_stack", action = "push_boxed", kind = ?kind, depth = self.views.len(), "view pushed");
}
pub fn pop(&mut self) -> Option<Box<dyn ModalView>> {
self.views.pop()
let popped = self.views.pop();
if let Some(view) = popped.as_ref() {
tracing::debug!(target: "deepseek_tui::view_stack", action = "pop", kind = ?view.kind(), depth = self.views.len(), "view popped");
}
popped
}
pub fn render(&self, area: Rect, buf: &mut Buffer) {
@@ -301,14 +309,18 @@ impl ViewStack {
match action {
ViewAction::None => {}
ViewAction::Close => {
self.views.pop();
if let Some(view) = self.views.pop() {
tracing::debug!(target: "deepseek_tui::view_stack", action = "close", kind = ?view.kind(), depth = self.views.len(), "view closed via action");
}
}
ViewAction::Emit(event) => {
events.push(event);
}
ViewAction::EmitAndClose(event) => {
events.push(event);
self.views.pop();
if let Some(view) = self.views.pop() {
tracing::debug!(target: "deepseek_tui::view_stack", action = "emit_and_close", kind = ?view.kind(), depth = self.views.len(), "view closed via action");
}
}
}
events