
terminal-browser는 Chromium이 만든 화면을 터미널 안에 표시하는 브라우저다. 코딩 에이전트와 같은 터미널 탭에서 웹을 보거나, SSH를 통해 원격 머신에서 실행 중인 사이트를 로컬 화면으로 미리 볼 수 있다.
설치와 사용
macOS와 Linux에서는 다음 명령으로 설치하거나 Homebrew를 이용할 수 있다. 설치된 버전을 올리려면 terminal-browser upgrade를 실행한다.
curl -fsSL https://terminal-browser.sh/install | bash
brew install terminal-browser
Windows에서는 WSL을 사용해야 한다. Windows에서 Kitty 그래픽 프로토콜을 지원하는 터미널은 매우 제한적이며, 프로젝트가 작동한다고 안내한 터미널은 noctty다. WSL 안에서 설치할 때도 다음 명령을 사용한다.
curl -fsSL https://terminal-browser.sh/install | bash
Claude Code 플러그인 설치 방법은 플러그인 안내에 있다.
terminal-browser를 실행하면 브라우저가 열린다. terminal-browser open <url>은 지정한 주소를 열고, terminal-browser --split right는 오른쪽에 분할 창을 연다. terminal-browser open --ssh <user@host> <url>은 원격 서버를 통해 네트워크 요청을 보내며, terminal-browser open --transparent <url>은 배경색이 없는 페이지에서 터미널 배경이 비치게 한다. terminal-browser ls는 열린 브라우저를 나열하고, terminal-browser action은 열린 브라우저와 상호작용하는 에이전트 브라우저 호환 CLI다. 버전 업데이트에는 terminal-browser upgrade를 쓴다.
프로젝트가 제시한 활용 사례는 코딩 에이전트와 웹사이트를 같은 터미널 탭에 두는 것, 에이전트가 열린 브라우저를 조작하게 하는 것, 에이전트가 만든 HTML 계획을 브라우저에서 열어 옆 분할 창으로 보는 것이다. SSH로 원격 머신에서 실행 중인 웹사이트를 미리 보는 용도도 안내한다.
macOS와 Linux의 주요 단축키는 다음과 같다. 확대·축소·초기화는 터미널 자체의 확대 단축키를 사용한다.
| 동작 | macOS | Linux |
|---|---|---|
| 종료 | ctrl+q 또는 ctrl+c | ctrl+q |
| 새 탭 | cmd+t | ctrl+t |
| 다음/이전 탭 | ctrl+tab / ctrl+shift+tab 또는 cmd+alt+right / cmd+alt+left | ctrl+tab / ctrl+shift+tab 또는 ctrl+pagedown / ctrl+pageup |
| URL 편집 | cmd+l | ctrl+l |
| 명령 팔레트 | cmd+p | ctrl+k 또는 alt+k |
| 페이지에서 찾기 | cmd+shift+f | ctrl+shift+f |
| 다음/이전 검색 결과 | enter / shift+enter | enter / shift+enter |
| 새로고침 | cmd+r | ctrl+r |
| 뒤로/앞으로 | cmd+[ / cmd+] 또는 ctrl+[ / ctrl+] | ctrl+[ / ctrl+] |
| 개발자 도구 | cmd+shift+i 또는 f12 | ctrl+shift+i 또는 f12 |
| 개발자 도구 콘솔 | cmd+alt+j | ctrl+alt+j |
| 복사/붙여넣기/잘라내기 | cmd+c / cmd+v / cmd+x | ctrl+c / ctrl+v / ctrl+x |
| 페이지 녹화 시작/중지 | ctrl+r | ctrl+shift+r |
| 녹화 검토 완료 | ctrl+enter | ctrl+enter |
| 요소 선택 시작(에이전트로 전송) | ctrl+g | ctrl+g |
| 팝업/오버레이 닫기 | escape | escape |
렌더링과 SSH 동작
Chromium이 그린 픽셀을 터미널에 표시하려면 Kitty 그래픽 프로토콜을 지원하는 터미널이 필요하다. 프로젝트는 ghostty, kitty, cmux, vscode 등을 지원 사례로 든다. Chromium의 화면을 읽는 데는 Electron의 오프스크린 렌더링 API를 사용한다. 웹페이지의 시각적 변화가 생기면 화면 전체가 아니라 달라진 영역의 작은 패치만 터미널로 보낸다고 설명한다.
페이지가 입력에 반응하도록 터미널에서 마우스 클릭·위치와 키보드 이벤트를 읽어 Chromium에 합성 이벤트로 전달한다. 터미널에서 가져올 수 없는 입력은 백그라운드 Swift 앱으로 운영체제에서 읽는다. 프로젝트는 이 방식을 통해 부드러운 스크롤과 트랙패드 이벤트를 지원하며, 무한 캔버스를 사용하는 웹사이트도 잘 작동한다고 설명한다.
브라우저 바깥 UI는 Rust 기반 그래픽 엔진 위에 구현했다. UI는 맞춤형 React 렌더러를 사용해 React와 TypeScript로 정의하며, 브라우저 UI와 웹페이지를 같은 캔버스에 그려 UI를 페이지 위에 겹칠 수 있다. 이 동작의 기반은 터미널에서 그래픽 애플리케이션을 만드는 데 쓸 수 있는 JavaScript 라이브러리 pixel로 추상화했다.
SSH를 이용할 때 프로젝트가 권장하는 방식은 terminal-browser --ssh <ssh arguments>다. SSH로 접속한 원격 머신에서 브라우저를 직접 실행하는 방법도 있지만, 웹페이지가 그리는 모든 프레임을 네트워크로 보내야 하고 웹사이트가 반응하기 전에 사용자 입력도 네트워크를 거쳐야 한다. 또한 추가 최적화를 활용하지 못한다. terminal-browser --ssh는 웹사이트를 로컬 기기에서 실행하고 브라우저의 네트워크 요청만 SSH를 통해 원격 머신으로 전달한다. 따라서 원격 머신의 localhost에서 실행 중인 사이트도 로컬 기기에서 열 수 있다.
기존 TUI에 브라우저를 삽입하는 모드도 지원한다. 참고 구현은 examples/embedded에 있다.
텔레메트리와 지원 현황
terminal-browser는 프로젝트 이용자 수를 파악하기 위해 가명 처리된 사용 이벤트를 수집한다고 설명한다. 전송되는 데이터는 ~/.local/state/terminal-browser-*/logs/telemetry.jsonl에 추가 기록되며, 민감하거나 개인을 식별하는 정보가 기기 밖으로 나가는지 확인할 수 있다고 안내한다. 사용 텔레메트리는 다음 중 하나로 끌 수 있다.
DO_NOT_TRACK=1또는TERMINAL_BROWSER_NO_TELEMETRY=1설정- 일반 설정 GUI에서 비활성화
terminal-browser config set telemetry.usage off실행
terminal-browser가 시작되지 않거나 내부에서 예기치 않은 오류가 발생하면 충돌 보고서도 수집한다. 이는 DO_NOT_TRACK=1, TERMINAL_BROWSER_NO_TELEMETRY=1, 설정 GUI 또는 terminal-browser config set telemetry.crashReports off로 끌 수 있다. pixel/을 사용하면 텔레메트리가 활성화되지 않으며 비활성화할 필요도 없다.
로드맵에는 완료된 Linux 지원과 개발 중인 디자인 모드, Chrome 확장 프로그램 지원이 적혀 있다. 프로젝트는 기여 요청(PR)의 설명을 사람이 작성하고 동기를 분명히 밝히며, 병합 가능성을 높이려면 변경 규모를 최소화해 달라고 요청한다. 로컬 개발 환경을 마련하는 방법으로는 코딩 에이전트에 요청하는 것을 권장한다.
터미널 통합 API
terminal-browser는 터미널이 구현할 수 있는 API를 제공한다. 이를 구현한 터미널에서는 새 창이나 분할 창을 열고, 코딩 에이전트에 텍스트를 보내고, 창에 포커스를 옮길 수 있다. 터미널이 API를 직접 구현하지 않아도 내장 구현을 사용할 수 있다.
터미널은 Unix 소켓에서 요청을 기다리고, 실행 중인 셸마다 TERMINAL_BROWSER_TERMINAL_SOCKET=<socket path>를 환경 변수로 설정한다. 예시 소켓 경로는 $TMPDIR/<your-app-id>.terminal-browser.sock이며, 같은 사용자만 연결하도록 해야 한다. 요청은 줄바꿈으로 끝나는 JSON 한 줄이고, 응답도 줄바꿈으로 끝나는 JSON 한 줄이다. 요청마다 연결을 새로 만들고 응답 뒤 연결을 닫으므로 세션 상태를 유지할 필요는 없다.
요청에는 메서드, 매개변수, 요청 프로세스 정보가 포함된다. 응답에는 동일한 id와 result 또는 error가 들어간다.
{ "id": "<unique string>", "method": "<name>", "params": { ... }, "caller": { "pid": 12345, "cwd": "/path" } }
{ "id": "<same id>", "result": { ... } }
{ "id": "<same id>", "error": { "message": "..." } }
첫 요청은 항상 hello다. 터미널은 구현한 메서드 목록을 응답으로 보내며, 빠진 메서드에 의존하는 기능은 terminal-browser가 비활성화한다.
→ { "method": "hello", "params": { "protocol": 1 } }
← { "result": { "name": "my-terminal", "methods": ["getCurrentPane", "split", "listPanes", "neighbor", "sendText", "pasteKey", "focusPane"] } }
창(pane)은 { "id": string, "tab": string } 형식이다. id는 창을 식별하는 안정적인 값이고, tab은 화면에 함께 표시되는 모든 창이 공유한다.
| 메서드 | 매개변수 | 결과 | 사용 기능 |
|---|---|---|---|
getCurrentPane | { tty, cwd } | { pane } 또는 { pane: null } | ls, new-tab, --split 위치 선택 |
split | { from: pane, direction, command: string[], size, tty } | {} | --split |
listPanes | { tty } | { panes: [{ id, tab, tty, command }] } | 코딩 에이전트 창 찾기 |
neighbor | { from: pane, direction } | { pane } 또는 { pane: null } | 기존 브라우저 옆에 열기 |
sendText | { pane, text } | {} | 페이지 내용을 코딩 에이전트에 보내기 |
pasteKey | { pane } | {} | 이미지 보내기 |
focusPane | { pane } | {} | 브라우저와 에이전트 사이 이동 |
direction은 right, left, down, up 중 하나다. size는 새 창이 차지할 공간의 비율(예: 0.4)이며, 기본값을 쓰려면 null로 지정한다. split은 호출자의 cwd에서 새 창을 열고 command를 실행한다. command는 셸에서 인용 처리를 해야 하는 인자 배열이다.
getCurrentPane은 호출자의 tty를 받지만, 멀티플렉서나 코딩 에이전트 래퍼 같은 중첩 PTY 안에서는 해당 TTY를 소유한 창이 없을 수 있다. 일치하는 창이 없으면 caller.pid의 조상 프로세스를 따라가며 체인에서 가장 먼저 나타나는 TTY의 창을 반환한다. listPanes 항목에는 각 창의 TTY와 전경 프로세스 명령줄이 포함되며, 알 수 없으면 명령줄은 null이다. pasteKey는 브래킷 붙여넣기가 아니라 문자 그대로의 ctrl+v 키 입력(바이트 0x16)을 전달해야 코딩 에이전트가 이를 키 입력으로 인식하고 클립보드를 읽는다.
각 응답에 대해 terminal-browser가 허용하는 정확한 형식은 shared/src/terminal-socket.ts에 있다. 모든 메서드에 응답하는 Node.js 기반 최소 터미널 예시는 shared/test/terminal-socket.test.js의 fakeTerminal이다.
API를 직접 구현하지 않은 터미널을 위해 ghostty, kitty, wezterm, cmux, tmux, vscode, tty7, herdr, supacode용 내장 구현도 제공한다. 구현은 pixel/packages/pixel/src/terminal/terminals에 있으며, 각 터미널의 스크립팅 CLI를 사용해 같은 작업을 수행한다. 다른 터미널이나 멀티플렉서를 추가하려면 해당 위치에 Terminal을 구현하는 파일을 넣고 terminals/index.ts에 등록한다. 인터페이스는 pixel/packages/pixel/src/terminal/terminal.ts에 있다.
프로젝트는 Kitty 그래픽 프로토콜을 개발한 kitty 프로젝트와, 터미널 안에 Chromium을 삽입하려 한 첫 시도인 awrit에 감사를 표한다.
댓글 (0)
로그인하면 이 기사에 내 생각을 남길 수 있어요