Summary
Extract a DisplayState abstraction from IndicatifRenderer to separate state tracking from terminal rendering, enabling unit testing of display logic.
Problem
Currently, IndicatifRenderer mixes:
- State tracking - subagent depth, current phase, tool execution status
- Terminal rendering - indicatif progress bars, spinners, colored output
This makes unit testing difficult since we can't test state transitions without mocking terminal output.
Proposed Solution
Create a DisplayState struct that tracks:
- Current subagent nesting depth
- Active phase (decomposition, execution, synthesis)
- Tool execution status
- Token usage
The Renderer trait would consume DisplayState for actual rendering.
/// Terminal-agnostic state machine for display logic
pub struct DisplayState {
pub subagent_depth: usize,
pub current_phase: Option<String>,
pub active_tools: Vec<ToolStatus>,
pub token_usage: Option<TokenUsage>,
}
impl DisplayState {
pub fn on_event(&mut self, update: &AgentUpdate) -> StateChange {
match update.event_type.as_str() {
"subagent_started" => {
self.subagent_depth += 1;
StateChange::SubagentEntered(...)
}
"subagent_completed" => {
self.subagent_depth = self.subagent_depth.saturating_sub(1);
StateChange::SubagentExited(...)
}
// ...
}
}
}
Benefits
- Testable state logic - Can test
DisplayState::on_event() without terminal
- Swappable renderers - Same state, different backends (indicatif, ratatui, plain)
- Clearer separation - State machine vs presentation
Test Cases to Enable
#[test]
fn test_subagent_depth_tracking() {
let mut state = DisplayState::new();
state.on_event(&subagent_started_event("deep_research"));
assert_eq!(state.subagent_depth, 1);
state.on_event(&subagent_completed_event("deep_research"));
assert_eq!(state.subagent_depth, 0);
}
#[test]
fn test_nested_subagents() {
let mut state = DisplayState::new();
state.on_event(&subagent_started_event("developer"));
state.on_event(&subagent_started_event("deep_research"));
assert_eq!(state.subagent_depth, 2);
}
Scope
- Extract state tracking from
gemicro-cli/src/display/indicatif.rs
- Create
gemicro-cli/src/display/state.rs
- Update
IndicatifRenderer to use DisplayState
- Add unit tests for state transitions
Context
Identified during PR #219 (Phase 2 - Subagent Access) when evaluating test coverage gaps. The subagent rendering logic is currently untestable.
🤖 Generated with Claude Code
Summary
Extract a
DisplayStateabstraction fromIndicatifRendererto separate state tracking from terminal rendering, enabling unit testing of display logic.Problem
Currently,
IndicatifRenderermixes:This makes unit testing difficult since we can't test state transitions without mocking terminal output.
Proposed Solution
Create a
DisplayStatestruct that tracks:The
Renderertrait would consumeDisplayStatefor actual rendering.Benefits
DisplayState::on_event()without terminalTest Cases to Enable
Scope
gemicro-cli/src/display/indicatif.rsgemicro-cli/src/display/state.rsIndicatifRendererto useDisplayStateContext
Identified during PR #219 (Phase 2 - Subagent Access) when evaluating test coverage gaps. The subagent rendering logic is currently untestable.
🤖 Generated with Claude Code