Community코딩 & 개발github.com

yankewei/terminal-rendering

임베디드 터미널 렌더링(셀 그리드, VT, 글꼴, 스프라이트, 페인트 캐시)을 설계하고 구현합니다. 터미널 창, PTY 뷰어, 에이전트 TUI 호스트, libghostty-vt / Ghostty 스타일 페인트, 박스 드로잉, Powerline 글리프, Nerd Font 아이콘을 구축하거나 개선할 때, 또는 터미널 출력이 Ghostty / kero / herdr와 비교하여 잘못 보이거나 흐릿하거나 정렬이 맞지 않을 때 사용하세요.

terminal-rendering란 무엇인가요?

이 기술은 터미널 화면을 올바르게 표시하기 위해 네 가지 주요 계층(VT, 메트릭, 페인트, 세션)을 다룹니다. 핵심은 VT 엔진을 사용하여 셀 그리드의 정확성을 보장하고, 글꼴 메트릭과 픽셀 단위의 정확한 계산을 통해 깔끔한 정렬을 유지하며, 형상 기반 박스 드로잉과 폰트 번들링을 통해 Powerline, Nerd Font 아이콘 등이 깨지거나 어긋나지 않도록 하는 것입니다. 이 기술은 Claude Code와 같은 AI 에이전트 TUI 환경에서 필수적이며, Ghostty, kero, herdr, kumu 등 다양한 프로젝트에서 참조 구현을 제공합니다. 실제 페인트 파이프라인은 배경, 스프라이트, 텍스트를 순서대로 그리고, 더티 로우 캐시를 사용하여 프레임 속도를 높입니다. 오류가 발생했을 때 VT 자체를 의심하기보다는 글꼴이나 페인트 계층을 먼저 점검해야 합니다.

지원 대상✓Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/yankewei/skills/tree/HEAD/terminal-rendering

Installed? Explore more 코딩 & 개발 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

터미널 렌더링

터미널 화면은 cols × rows 셀 그리드입니다. 정확성은 VT에서 비롯되고, '아름다움'은 메트릭과 페인트에서 옵니다. 같은 에뮬레이터라도 다른 결과를 보여줄 수 있습니다.

네 가지 계층

계층역할문제 발생 시
1. VT바이트 → 셀 그리드 (커서, 모드, 스크롤백, 대체 화면)깨짐 / 잘못된 크기 / 커서 고정
2. 메트릭글꼴의 셀 너비/높이; cols/rows 및 셀 px로 PTY 크기 조정흔들리는 컬럼, 흐릿한 가장자리
3. 페인트셀 그리기: 배경 실행, 글리프, 스프라이트, 대비간격, 얇은 텍스트, 깨진 TUI 테두리
4. 세션 (선택 사항)지속/원격: 데몬이 VT를 소유, 클라이언트가 프레임 미러링창이 닫히면 스크롤백 사라짐

요약: 정확성은 VT; 미관은 글꼴 + 메트릭 + 셀별 배치 + 기하학적 박스 드로잉; 속도는 더티 로우 캐시.

1. VT (그리드가 정확해야 함)

  • 에이전트 TUI의 경우 직접 만든 ANSI 서브셋보다는 실제 에뮬레이터(예: libghostty-vt)를 선호하세요.
  • 각 셀: 텍스트(자소), fg/bg, 볼드/이탤릭/희미하게, 밑줄/취소선, 와이드 플래그.
  • 처리: 와이드 문자/이모지 너비, 대체 화면, 동기화된 출력(모드 2026), 다음 PTY 읽기 전에 기록되는 쿼리 응답.
  • UI는 그리드의 스냅샷을 읽습니다. 페인트 경로에서 바이트 스트림을 다시 구문 분석하지 마세요.

2. 메트릭

  • 컬럼 너비 ≈ 'M'의 글리프 전진 값(선택적 CellWidth 배수).
  • 행 높이 ≈ 어센트 + 디센트, 이후 × 약 1.15–1.2; 장치 픽셀에 맞춤.
  • 너비를 글꼴 전진 값으로 유지하고, 박스/배경 가장자리를 픽셀에 맞춰 이웃이 틈 없이 만나도록 합니다(글리프가 흔들리지 않도록 셀 너비를 반올림하지 마세요).
  • 크기 조정 시 PTY에 cols, rows, cell_width_px, cell_height_px를 전송합니다(프로그램은 마우스/이미지에 픽셀 크기를 사용).

3. 페인트 (외관이 결정되는 곳)

기존 터미널을 개선할 때 우선 순위:

  1. 고정된 모노 + Nerd 심볼 폰트 제공(예: JetBrains Mono + Symbols Nerd Font). 시스템 기본 모노/누락된 Powerline 아이콘은 에이전트 TUI를 망칩니다.
  2. 박스 / 블록 / 브레일 / Powerline을 글꼴 글리프가 아닌 기하학적 도형으로 그리기 — 글꼴은 행 사이에 간격을 남깁니다. 전체 화면 테두리는 연결되어야 합니다.
  3. 그리드에 글리프 배치: 동일 스타일의 연속 텍스트는 강제 너비 셰이핑 또는 셀별 중앙 정렬. 좁은 셀을 넘는 대체 글리프(이모지)는 축소.
  4. 누락된 PUA / Nerd 아이콘을 심볼 폰트로 라우팅(또는 셀 내에 외곽선 맞춤).
  5. 선택적 개선: 최소-대비(스프라이트/의도적 그래픽 건너뜀), macOS 글꼴 두껍게 하기, 다중 스타일 밑줄, 패딩 색상 확장.

페인트 파이프라인 (프레임당)

  1. 창을 터미널 배경색으로 채웁니다.
  2. 시작점 = 패딩 + 수직 여백/2; 시작점을 장치 픽셀에 맞춥니다.
  3. 행의 Arc/id가 변경된 경우(또는 글꼴/셀 크기 변경/전체 더티)에만 행 연산을 다시 빌드합니다.
  4. 모든 배경 범위, 그 다음 스프라이트, 그 다음 텍스트 실행, 마지막으로 커서 / IME / 오버레이를 그립니다.

행 연산

  • 연속된 동일 배경 셀을 하나의 사각형으로 병합합니다.
  • 하나의 스프라이트 셀 → 기하학적 그리기(herdr / Ghostty의 스프라이트 접근 방식 참조).
  • 그 외에는 동일 스타일의 텍스트 실행을 셰이핑합니다. 좁은 셀의 경우 열이 고정되도록 전진 값을 cell_w로 강제합니다.

VT를 탓하지 말아야 할 경우

테두리에 간격이 생기거나, 아이콘이 네모 상자로 표시되거나, 텍스트가 얇거나 고르지 않지만 그리드 내용이 올바르다면 — 페인트/글꼴을 수정하고 에뮬레이터를 교체하지 마세요.

4. 세션 토폴로지

프로세스 내(단순): PTY → VT → 스냅샷 → UI 페인트.

데몬 + 클라이언트(kero 스타일): 데몬 헤드리스 VT + PTY; Mirror가 현재 화면의 VT 프레임을 인코딩; 클라이언트 VT가 Conn과 함께 셀 단위로 페인트; 창 닫기/원격 연결 시에도 스크롤백 유지.

참조 구현

프로젝트스택참고
GhosttyZig + libghostty-vtVT + 스프라이트 의미론의 원천
herdr-appGPUI + libghostty-vt셀 페인트, 스프라이트, 대비, 번들 폰트
keroMyGo + libghostty-vt미러 프레임, Ghostty 테마, GPU UI
kumuGPUI-kit + libghostty-vt동일한 페인트 아이디어: 스프라이트 + JetBrains + Nerd

체크리스트

터미널 렌더링을 추가하거나 수정할 때:

  • VT가 그리드를 소유; UI는 스냅샷만 페인트
  • 모노 폰트의 셀 메트릭; 크기 조정에 픽셀 셀 크기 포함
  • 번들(또는 보장된) 모노 + Nerd 심볼 폰트
  • 박스 / Powerline / 브레일을 도형으로 그림
  • 더티 로우 페인트 캐시는 행 ID를 키로 사용
  • 커서, IME 및 선택 항목이 셀 좌표에 위치
  • 알려진 TUI(htop, Claude Code, statusline)를 Ghostty와 비교

추가 세부 사항

  • 스프라이트 / 기하학적 범위 및 대비 규칙: paint.md

관련 스킬