Problem
Currently the interview command has issues with interleaved output when the agent streams text between tool calls. The spinner and streaming text conflict, causing garbled output.
Current Workaround
We guard spinner operations with a textOutputStarted flag - once text streaming begins, the spinner stays stopped. Tool calls are still displayed but without the animated spinner.
Solution: Ink (React for Terminals)
Based on research, both Claude Code and Gemini CLI use Ink for their terminal UI. This is the industry standard for TypeScript-based AI CLI tools.
Key Benefits
<Static> component for tool calls that scroll while status bar stays put
- Declarative state management (no more
textOutputStarted hack)
- Component isolation - spinner and content don't interfere
- Future-proof for more complex UI features
Implementation Plan
- Install dependencies:
ink, ink-spinner, react
- Create component structure in
src/cli/components/:
InterviewUI.tsx - Root component
StatusBar.tsx - Sticky spinner at bottom
ToolCallList.tsx - Scrolling tool calls using <Static>
StreamingOutput.tsx - Text delta accumulator
- Refactor
interview.ts to use declarative React state
- Test across terminals (iTerm, Terminal.app)
Files Affected
src/cli/commands/interview.ts - Main interview TUI logic
src/utils/ui.ts - UI utilities
package.json - Dependencies
References
Linear Issue: ANS-449