Skip to content

Latest commit

 

History

History
199 lines (129 loc) · 7.98 KB

File metadata and controls

199 lines (129 loc) · 7.98 KB

VT Code FAQ

Based on best practices from Ratatui and terminal UI development, this FAQ addresses common questions about VT Code architecture and usage.

Terminal & TUI

Why don't I see duplicate key events on Windows?

VT Code correctly filters key events to only process KeyEventKind::Press, avoiding duplicate events from both press and release.

See src/tui.rs:153:

if key.kind == KeyEventKind::Press {
    let _ = _event_tx.send(Event::Key(key));
}

This pattern is cross-platform compatible (Windows, macOS, Linux).

Why should VT Code use tokio/async?

VT Code uses Tokio for:

  1. Event multiplexing - Handling terminal events, ticks, and renders concurrently without blocking
  2. Multi-tool execution - Running MCP tools, PTY sessions, and API calls in parallel
  3. Lifecycle hooks - Running shell commands asynchronously during agent events

The architecture uses tokio::select! to multiplex:

  • Terminal input (blocking read in spawned task)
  • Frame rate ticks (60 FPS)
  • Event processing ticks (4 Hz)

When NOT to use async:

  • Simple one-off CLI tasks (prefer synchronous main loop)
  • Tools that don't need concurrent execution

VT Code's multi-agent coordination and tool execution justify async.

Why use stderr instead of stdout for terminal rendering?

VT Code renders to stderr (via CrosstermBackend::new(std::io::stderr()) in src/tui.rs:73).

Rationale:

  • Allows piping output: vtcode ask "task" | jq doesn't break the TUI
  • Makes the TUI work out-of-the-box in pipes (no special TTY detection needed)
  • Compatible with shell pipelines and CI/CD environments

Can I run multiple terminal.draw() calls in the same loop?

No. VT Code uses a single terminal.draw() call per frame that renders all widgets together. See vtcode-core/src/ui/tui/session.rs:render() method, which orchestrates all UI components in one closure.

How do I pipe output to other tools?

Because VT Code strictly separates data (stdout) from metadata/logging (stderr), you can pipe the output of commands like ask and exec directly.

# Code goes to file, logs stay on screen
vtcode ask "code for a fibonacci function" > fib.py

Use vtcode exec --json to get a pipeable stream of structured events.

How does VT Code handle terminal resizing?

VT Code listens for Event::Resize(x, y) events and updates the layout automatically. The TUI widgets reflow based on the new terminal dimensions—no special handling needed.

Can I change font size in a VT Code terminal?

No, VT Code can't control terminal font size. That's a terminal emulator setting. VT Code adapts to the terminal's actual size via Event::Resize.

Tip: Use tui-big-text or figlet for large ASCII art titles within the TUI.

What characters look weird or display as ?

VT Code assumes a Nerd Font for box-drawing and icon support. Install one of:

Architecture & Design

Is VT Code a library or framework?

VT Code is a tool/agent, not a library or framework.

However, vtcode-core (the Rust crate) is a library you can use in your own Rust projects. The binary (vtcode CLI) uses this library to implement a coding agent.

Philosophy:

  • Library-like: You control the event loop and can extend VT Code's functionality
  • Agent-first: The CLI provides opinionated defaults for common coding tasks

How does VT Code differ from similar tools?

VT Code is an AI coding agent with:

  • Security-first: Execution policies, workspace isolation, tool policies, and tree-sitter-bash command validation
  • Multi-LLM: OpenAI, Anthropic, Gemini, Ollama, LM Studio, etc.
  • Semantic code understanding: LLM-native analysis and navigation across all modern languages
  • Context engineering: Token budget tracking, dynamic context curation
  • Editor integration: Agent Client Protocol (ACP) for Zed, Cursor, etc.

Why does VT Code use async/await extensively?

Reasons:

  1. Tool execution: MCP tools, PTY sessions, API calls run concurrently
  2. Event handling: Terminal input, ticks, renders multiplexed with tokio::select!
  3. Streaming: Real-time AI responses streamed without blocking
  4. Lifecycle hooks: Shell commands execute without blocking the agent loop

Result: VT Code remains responsive even during long-running operations.

How does VT Code manage terminal state?

The fullscreen TUI uses the shared runner in vtcode-tui/src/core_tui/runner/ and writes terminal control sequences through stderr.

  1. Enter: Save cursor position, enable terminal modes (raw mode, bracketed paste, focus events, keyboard enhancements, optional mouse capture), then enter alternate screen.
  2. Running: Process events, update state, and render only the current viewport.
  3. Exit: Stop the event loop, finalize the terminal, leave alternate screen, restore terminal modes in reverse order, and restore the saved cursor position.

The ExternalAppLauncher trait allows suspending the TUI to launch editors, git clients, etc.

Why suspend the TUI to launch external apps?

VT Code suspends the event loop, drains pending terminal events, leaves alternate-screen rendering, launches the external app, and then restores the fullscreen session. The same pattern is used for editor launches and for fullscreen transcript review handoff to native scrollback.

This prevents terminal artifacts and ensures external apps get clean input/output.

How does fullscreen transcript review work?

Press Alt+O while fullscreen rendering is active to open transcript review. VT Code builds a plain-text cache of the full transcript, including expanded collapsed tool payloads, then lets you:

  • search with /, n, and N
  • page through the conversation with Ctrl+U, Ctrl+D, Ctrl+B, and Ctrl+F
  • export to native terminal scrollback with [
  • open the expanded transcript in your editor with v

What should I configure for tmux?

If you want wheel scrolling and click support inside fullscreen rendering, enable tmux mouse mode:

set -g mouse on

VT Code's alternate-screen fullscreen mode is intended for normal tmux sessions. Avoid using it with iTerm2 control mode (tmux -CC), where mouse capture and alternate-screen behavior are unreliable.

Debugging & Troubleshooting

How do I enable debug logging?

Set RUST_LOG environment variable:

RUST_LOG=vtcode_core=debug,vtcode=debug vtcode

Or configure in vtcode.toml:

[debug]
enable_tracing = true
trace_level = "debug"
trace_targets = ["vtcode_core", "vtcode"]

See src/main.rs:244 and src/main.rs:260 for initialization.

How does VT Code handle buffer overruns?

The Ratatui FAQ recommends using area.intersection(buf.area) to prevent out-of-bounds rendering. This is applied in VT Code's widget implementations to clamp rendering to valid regions.

Best practice: Use Rect::intersection() and Rect::clamp() when calculating layouts manually.

Performance & Optimization

What's VT Code's frame and tick rate?

  • Frame rate: 60 FPS (default in src/tui.rs:72)
  • Tick rate: 4 Hz (default in src/tui.rs:71)

Both are configurable via builder methods:

tui.frame_rate(60.0).tick_rate(4.0)

How does VT Code reduce latency?

  1. Async event handling: Non-blocking tokio::select! in src/tui.rs:138
  2. Double buffering: Ratatui only renders diffs, not full redraws
  3. Lazy rendering: Only recompute UI when state changes (not every frame)

Can I use VT Code in a pipe?

Yes. VT Code detects when stdout is a pipe (not a TTY) and adapts:

  • Interactive mode: Full TUI if terminal is available
  • Pipe mode: Text output (if piped)

Check src/main.rs:228 for TTY detection.

See Also