TL;DR
- 여러 코딩 에이전트의 입력 영역 구현을 비교한 결과, 터미널 스크롤백을 보존하려는 에이전트에는 메인 화면이 적합하지만 화면 다시 그리기와 크기 조정 문제가 남음.
- Claude Code, Gemini CLI, Command Code, Codex CLI, pi는 메인 화면을 사용하고 스크롤백을 보존하며, opencode와 Amp는 대체 화면을 사용해 스크롤백을 포기함.
- 메인 화면 렌더링 방식은 Ink 스타일 전체 다시 그리기, 줄 단위 차등 렌더링, 스크롤 영역과 위쪽 삽입의 세 가지임.
- 동기화 출력(DEC 모드 2026)은 렌더링 깜빡임을 줄이는 주요 수단이며, 크기 조정 뒤 기록을 다시 배치하는 문제는 해결되지 않음.
- Rust 기반 에이전트의 선택지는 기존 스크롤 영역에
tui-textarea를 결합하거나,ratatui인라인 뷰포트로 입력창과 상태 표시줄, 팝업을 구성하는 방식임.
대화형 터미널 앱의 두 가지 화면 방식
- Rust로 작은 코딩 에이전트를 유지 관리하며, 터미널 스크롤 영역과 불완전한
termios모드, 직접 만든 줄 편집기로 입력 영역을 구현함. 작동은 하지만 평소 사용하는 에이전트만큼 보기 좋거나 사용감이 좋지 않아, 재작성 전에 다른 에이전트의 구현 방식을 조사함. - 핵심 제약은 전체 화면 터미널 사용자 인터페이스(TUI)를 사용하지 않는 것임. 대화 내용은 터미널 자체의 스크롤백에 남아야 하며, 위로 스크롤하고 터미널 찾기 기능을 쓰고 마우스로 텍스트를 선택할 수 있어야 함. 화면 아래쪽의 프롬프트와 상태 표시줄만 실시간 영역이어야 함.
- 터미널에는 두 개의 화면 버퍼가 있음.
- 메인 화면은 셸이 사용하는 화면이며, 위쪽으로 밀려난 줄은 스크롤백에 들어감.
- 대체 화면(
ESC[?1049h)은vim과htop이 사용하는 고정 격자임. 스크롤백이 없고 종료할 때 이전 내용으로 복구됨. - 에이전트 CLI는 다음 중 하나를 선택해야 함.
- 대체 화면: 앱이 모든 셀을 소유함. 다시 그리기가 쉽고 깜빡임이 없지만, 스크롤·찾기·선택 기능을 앱 안에서 다시 구현해야 함.
- 메인 화면: 완료된 출력은 한 번 출력한 뒤 터미널에 맡기고, 앱은 아래쪽의 작은 영역만 다시 그림. 스크롤백·찾기·선택은 계속 작동하지만, 다시 그릴 때 주의하지 않으면 화면이 깜빡이고 기록이 손상됨.
- Peter Steinberger의 게시물 「The Signature Flicker」가 이 절충을 잘 설명하며, 조사한 자료 가운데 단일 자료로는 가장 유용함. Mario Zechner의
pi구축 글은 두 번째 방식인 메인 화면 구현을 더 깊이 다룸.
에이전트별 구현 방식
- 구현 비교:
- Claude Code:
Ink를 사용하다 자체 차등 렌더러로 전환, 메인 화면, 스크롤백 보존. - Gemini CLI:
Ink, 메인 화면 사용. 대체 화면을 시험했으나 되돌렸으며 스크롤백 보존. - Command Code:
Ink와 React, 메인 화면, 스크롤백 보존. - Codex CLI: Rust의
ratatui와crossterm, 스크롤 영역이 있는 메인 화면, 스크롤백 보존. pi: 자체 라이브러리인pi-tui, 메인 화면, 스크롤백 보존.opencode: Zig 코어와 TypeScript/Solid 기반OpenTUI, 대체 화면, 스크롤백 미보존.- Amp: 자체 렌더러, 대체 화면, 스크롤백 미보존.
- Claude Code에서는
Ink의 전체 다시 그리기로 유명한 깜빡임이 발생함. Anthropic은 렌더러를 다시 작성하면서 React를 컴포넌트 모델로 유지했고, 수정 사항은 2.0.72에 포함됨. 메인 화면을 유지하는 이유로 앱이 자체 선택과 스크롤을 그리면 “브라우저처럼 느껴지지 않을 것”이라고 밝힘. - Gemini CLI는 대체 화면 TUI를 발표한 뒤 일주일 안에 철회함. 사용자는 텍스트를 선택하기 전에 Ctrl-S를 눌러야 하는 점을 싫어함.
- Command Code는 오픈 소스가 아님. npm 패키지는 번들링과 난독화가 적용되어 있지만, 변경 기록에 따르면
Ink를 사용하며 VS Code 터미널에서 Shift+Enter가 작동하도록ink버전을 6.6.0으로 고정함. - Amp는 깜빡임을 없애려고 대체 모드로 이동함. 현재 터미널 찾기 기능은 화면에 있는 텍스트만 검색함.
opencode는 개별 셀을 비교하고 지우기 이스케이프 시퀀스를 보내지 않는OpenTUI를 구축함. 설계는 잘 다듬어져 있지만, 구형 macOS Terminal과 GNOME Terminal에서 알려진 문제가 있음.- 전반적으로 터미널다운 사용감을 중시하는 에이전트는 메인 화면을 유지함. 전체 화면 방식으로 전환한 에이전트는 더 부드러운 다시 그리기를 얻는 대신 스크롤과 선택 기능을 포기함.
메인 화면을 유지하는 세 가지 방식
- 메인 화면을 사용하는 에이전트에서 세 가지 설계를 확인함.
Ink스타일 React 렌더링: 컴포넌트 트리를 문자열로 다시 렌더링하고 이전 프레임 위에 다시 그림. 작성하기는 쉽지만, 너무 많은 영역을 너무 자주 다시 그리는 데서 깜빡임이 발생함.- 줄 단위 차등 렌더링(
pi-tui, Claude Code의 새 렌더러): 이전에 그린 줄을 보관하고 새 프레임과 비교해 달라진 줄만 다시 씀. 각 프레임을 동기화 출력(DEC 모드 2026)으로 감싸 터미널에 한꺼번에 표시함. - 커서가 이미 기록으로 밀려난 줄까지 이동할 수 없다는 한계가 있음. 따라서 뷰포트 위쪽의 내용이 바뀌는 경우, 예를 들어 마크다운 블록의 줄바꿈이 재배치되면 전체를 지우고 다시 그려야 함.
- 줄을 지우면 진행 중인 마우스 선택도 취소됨.
- 스크롤 영역과 위쪽 삽입(Codex CLI): Codex는 작성기, 상태 표시줄, 팝업을 화면 아래쪽의
ratatui뷰포트에 유지함. 기록 셀이 완성되면 렌더링한 줄을 대기열에 넣고insert_history로 뷰포트 위에 삽입함. DECSTBM(ESC[top;bottom r)으로 스크롤 영역을 설정하고 그 영역을 스크롤해 줄이 실제 터미널 스크롤백으로 흘러가게 함. 실시간 영역은 기록을 건드리지 않음.- 이슈 추적기에 기재된 비용은 다음과 같음.
- Zellij에서는 부분 스크롤 영역과 줄 끝까지 지우기를 함께 쓰면 제자리에서 화면을 지우는 동작으로 해석될 수 있어 기록 줄이 손실됨.
- Windows Terminal의 ConPTY에서는 부분 영역 밖으로 밀려난 줄이 스크롤백에 도달하지 않는 경우가 많음.
- 모드 2026을 지원하지 않는 Tabby와 Wave에서는 커서가 상태 표시줄과 작성기 사이를 오가는 현상이 나타남.
- 크기 조정은 어려운 문제임. 앱은 확정된 스크롤백을 재배치할 수 없으므로 Codex는 크기가 바뀐 뒤 메모리의 대화 기록을 다시 렌더링함. 터미널에 따라 화면이 번쩍이거나, 맨 위로 이동하거나, 줄이 중복될 수 있음. Codex는 우회 수단으로 전체 화면 호출기(Ctrl+T)도 제공함.
- Steinberger는 Codex가 대체 화면 TUI 쪽으로 이동해 왔다고도 언급함. 이 설계를 작동하게 만든 Rust 팀조차 포기를 고려함.
Rust 도구 상자
- Rust로 작성한 에이전트에 적용할 인라인 다중 행 입력 영역 후보를 비교함.
ratatui: 다중 행 편집은Viewport::Inline을 통해 위젯으로 구현하고, 프롬프트 위 출력은Terminal::insert_before를 사용함. Codex 설계의 공식 지원 방식임.tui-textarea: 2차원 커서와 실행 취소를 지원함. 호스트가 출력 처리를 맡으며ratatui용 편집기 위젯임.reedline: 다중 행 편집과ExternalPrinter를 지원함. 셸 프롬프트용으로 설계된 Nushell의 줄 편집기임.rustyline: 다중 행 편집은 이어쓰기 줄 수준으로 제한되며, 프롬프트 위 출력 기능은 없음.readline복제 구현임.termwiz LineEditor: 단일 행 편집기이며, 프롬프트 위 출력 기능은 없음.crossterm: 직접 구현해야 하며, 위 도구들이 사용하는 기본 요소를 제공함.- 자체 편집기를 작성하기 전에
reedline포크를 사용함. 셸 프롬프트에는 적합하지만, 상태 표시줄과 완성 팝업이 고정된 작성기는 설계 대상이 아님.
조사 결과와 선택지
- 주로 텍스트를 출력하는 에이전트에는 메인 화면을 유지하는 것이 적절함. Claude Code와 Gemini CLI는 대체 방식을 공개적으로 시험한 뒤 모두 메인 화면으로 돌아옴.
- 편집기와 렌더러는 별개의 문제임. 다중 행 편집, 붙여넣기, 완성 팝업처럼 사용감을 좌우하는 기능은 주로 편집기 문제이고, 깜빡임·기록 손실·크기 조정 흔적처럼 깨져 보이는 문제는 주로 렌더러 문제임. 한쪽을 다른 쪽과 별개로 교체할 수 있음.
- 동기화 출력(모드 2026)은 기본 요건임. 제대로 된 렌더러는 모두 이를 사용함.
- 메인 화면에서 크기 조정 문제를 깔끔하게 해결한 사례는 조사 대상 가운데 없음. 모두 기록을 다시 재생하거나 일부 화면 이상을 받아들임. 구현을 시작하기 전에 둘 중 어느 쪽을 선택할지 결정해야 함.
- 자체 에이전트에는 두 가지 경로가 있음.
- 작은 변경: 기존 스크롤 영역 입력창은 유지하고 편집 코어만
tui-textarea로 교체함. - 큰 변경: Codex처럼
ratatui인라인 뷰포트로 옮겨 작성기, 상태 표시줄, 팝업을 위젯으로 그림. - Codex의
insert_history.rs와textarea.rs는 Apache-2.0 라이선스이며 어느 경로를 택하든 참고할 가치가 있음. - 조사는 웹 검색을 수행하는 AI 에이전트와 함께 진행했고, 주요 주장은 Steinberger의 게시물 및 연결된 자료와 대조함. 각 프로젝트 이슈 추적기의 모든 내용을 다시 검증한 것은 아니므로 구체적인 버그 설명은 변경 기록이 아니라 참고 자료로 다뤄야 함.
댓글 (0)
로그인하면 이 기사에 내 생각을 남길 수 있어요