tmux: 공통 상태 표시줄, 화면 분할, 원격 접속에서
멀티 에이전트 분업까지
2026년 2월 openclaw에서 영감을 받아 tmux를 쓰기 시작했고, 상태 표시줄과 화면 분할, 원격 개발을 거쳐 멀티 에이전트 분업까지 하나씩 쌓아 왔습니다.
먼저 상태 표시줄부터 손봤습니다
가장 먼저 보완한 것은 상태 표시줄입니다. 쓰고 있던 여러 AI agent CLI의 상태를 하나의 bar에 모았습니다. 2026년 2월 openclaw 에서 영감을 받아 tmux를 쓰기 시작했고, 이것이 첫 실행 단계였습니다.
tmux를 쓰기 시작할 무렵에는 늘 쓰는 CLI에 가끔 시험 삼아 바꿔 쓰는 CLI까지 여러 개를 동시에 사용하고 있었습니다. terminal 창을 몇 개만 더 열어도 엉망이 됐습니다. YouTube의 《tmux 사용과 기본 설정, 입문부터 야근까지 영상 하나로 끝!》 을 따라 명령어에 익숙해진 뒤, 가장 먼저 Claude Code의 statusline을 손봤습니다.
~/.claude/settings.json 설정에서 statusLine.command 를 직접 작성한 statusline.sh:
statusline.sh 에서 하는 일은 다양합니다. session ID, cwd, git branch와 변경한 파일 수, model display name, session cost, context 사용률을 가져옵니다. 이 모든 것을 jq 한 번으로 추출해 매초 15번 fork하는 overhead를 피했습니다.
익숙해지고 나니 더 많은 것을 보고 싶어졌습니다. Claude / Codex / Gemini 각각의 5시간, 7일 한도와 CPU, MEM, DISK, NET도요. 하지만 Claude Code statusline에서는 현재 session만 볼 수 있고, session을 가로지르는 누적 한도는 볼 수 없습니다. 그래서 이 부분을 따로 빼서 tmux 상태 표시줄에 넣었습니다.
~/.tmux.conf 긴 status-format[1]을 하나 만들고, 각 칸에서 직접 작성한 tmux_status.sh 을 호출해 데이터를 가져오고 catppuccin 색상을 입혔습니다.
status-interval 5 5초마다 새로고침합니다. 처음에는 이 script를 Python으로 작성해서 5초마다 interpreter 하나를 fork했고, 13개 칸에 process가 13개씩 생겼습니다. tmux server가 한 번 죽은 뒤 shell + jq로 바꿔 interpreter startup overhead를 줄였습니다.
여기까지 tmux는 제게 그저 “보기 좋은 상태 표시줄 컨테이너”였습니다. 그다음에야 본래 용도인 화면 분할을 쓰기 시작했습니다.
반복해서 쓰는 세 가지 pane 배치
반복해서 쓰는 pane 배치는 세 가지이고, 가장 자주 쓰는 것은 세로 네 칸을 같은 너비로 나누는 방식입니다. 기본 명령어를 익힌 뒤 이 몇 가지로 정착했습니다.
1. 세로 네 칸을 같은 너비로
AI agent CLI 4개가 실제로 동시에 돌아갑니다. 각 칸에는 독립적인 대화 하나씩을 두고 task를 dispatch합니다. 네 칸을 훑어보면 누가 끝났고, 누가 아직 thinking 중이고, 누가 답변을 기다리는지 알 수 있습니다. 너비가 같아서 왼쪽에서 오른쪽으로 1초면 훑을 수 있고, 누가 어디 있는지 외울 필요도 없습니다.
2. 가운데 십자형 4분할
화면이 클 때 씁니다. 네 사분면에 각각 고정된 역할을 둡니다. 지금은 왼쪽 위에 주 대화, 오른쪽 위에 code나 파일 트리 미리보기, 왼쪽 아래에 비교 정보(CLI 기능표, provider/model 사양), 오른쪽 아래에 보조 CLI(qwen 등)를 둡니다.
세로 네 칸과 비교하면 “세로 방향”의 정보 밀도가 높아집니다. 어떤 pane에는 긴 형태(log)가 맞고, 어떤 pane에는 네모난 형태(표, code)가 맞는데, 십자형 배치는 둘 다 담을 수 있습니다.
3. 메인 + 보조 sub-agent 배치
왼쪽의 큰 pane 하나에서 main agent(대부분 Claude Code)를 실행하고, 오른쪽은 가로로 나눈 작은 pane 4개에서 sub-agent나 하위 task를 실행합니다. main이 일을 보내면 오른쪽 pane들이 병렬로 실행됩니다. 상태도 나란히 볼 수 있고, 끝나면 왼쪽에 보고합니다.
이 배치가 뒤에 나올 중계 시스템의 초기 형태입니다. “제가 수동으로 dispatch”하던 것을 “skill이 자동으로 dispatch”하도록 바꾼 것뿐입니다.
연결이 끊길 때마다 처음부터 다시 하는 건 너무 바보 같았습니다
tmux를 설치하기 전에는 ssh로 개발 머신에 접속해 긴 build를 돌리다가 연결이 끊기면 처음부터 다시 해야 했습니다. tmux로 바꾼 뒤에는 이 흐름이 더 이상 끊기지 않았습니다.
그 순간 깨달았습니다. tmux는 화면 분할 도구가 아니라 process를 담는 컨테이너입니다.
그 뒤로 원격 session은 모두 tmux를 거칩니다. host마다 default session 하나를 두고, ssh로 접속하면 먼저 tmux a || tmux new -s default합니다. 아무것도 bare shell에서 직접 실행하지 않습니다.
여기에 tmux-resurrect + tmux-continuum plugin 두 개를 더해 15분마다 전체 layout을 자동으로 snapshot합니다. 재부팅 뒤 tmux가 시작되면 자동으로 restore합니다.~/.tmux.conf 에는 두 줄만 있으면 됩니다.
집에 있는 mac mini를 재부팅해도 돌아와 보면 session이 원래 자리에 그대로 있습니다.
집의 Mac mini, 밖의 MacBook, 이동 중의 iPhone
tmux-resurrect + tmux-continuum 안정화된 뒤 집의 mac mini를 24/7 켜 두고 주 개발 머신으로 삼았습니다.
제 default session은 tmux에서 항상 실행 중입니다. 클라우드 드라이브로 파일을 동기화할 필요도 줄었습니다. 어차피 소스 코드는 모두 그 머신에 있으니까요. MacBook을 들고 외출 → ssh로 집에 접속 → tmux a → 오전에 쓰다 만 prompt를 이어서 작성합니다. 출퇴근길에 idea가 떠오르면 메모 대신 그 session에 바로 입력합니다.
“그 session에 바로 입력”하는 일은 노트북에서는 매끄럽지만, 휴대폰에서는 막혔습니다.
저는 세로 네 칸을 같은 너비로 나눈 배치에서 agent 4개를 보는 데 익숙합니다. 휴대폰으로 ssh 접속하면 너비가 턱없이 부족합니다. 어느 한 칸을 보려 해도 prefix + z zoom in으로 화면을 꽉 채워야 하고, 보고 나면 다시 zoom out해서 다음 칸으로 옮겨야 합니다. agent 하나와 상호작용할 때마다 단계가 두 개씩 늘어나니, 조금만 작업해도 피곤해졌습니다.
tmux-webui를 만들었습니다
휴대폰에서 tmux에 접속하려고 먼저 기존 방법 세 가지를 써 봤지만, 모두 부족했습니다.
iSH
iPhone에서 무료로 쓸 수 있는 Linux shell입니다. 원격 tmux에 ssh attach하는 정도에는 충분하지만, 장기적으로 작업하기에는 어렵습니다. Alpine과 몇 가지 도구만 실행할 수 있기 때문입니다.
Blink Shell(직접 빌드)
App Store 버전은 유료지만 GitHub의 오픈소스 버전은 직접 빌드할 수 있습니다. iOS 개발은 전혀 해 본 적이 없어 sideload 전체 과정을 Claude Code의 도움으로 진행했습니다. free developer account로는 7일마다 다시 서명해야 합니다.
mosh(포기)
네트워크가 바뀌어도 연결이 유지되게 하고 싶었습니다. 이론상으로는 좋지만, 주력 mac의 메모리가 부족해서 mosh-server를 오래 실행하면 메모리를 다 먹고 컴퓨터 전체가 멈춰 버렸습니다.
세 가지가 모두 막힌 뒤 만든 것이 tmux-webui입니다. tmux pane을 브라우저에 직접 옮겨 ssh client와 mosh의 번거로움을 건너뛰었습니다. 이 생각은 Claude Code가 자체 remote 모드를 내놓기 전부터 했습니다. 나중에 remote가 나왔어도 저는 여전히 tmux를 더 자주 씁니다.
native iOS app 대신 web을 선택한 이유는 현실적입니다. Xcode도, TestFlight도, 연간 99달러도 필요 없습니다. 브라우저가 있는 기기라면 무엇이든 쓸 수 있습니다. 대신 auth와 트래픽 암호화는 직접 처리해야 해서 이 부분은 Cloudflare Tunnel에 맡겼습니다.
기능은 몇 가지입니다. 모든 sessions / windows / panes 목록 보기, pane을 탭해 실시간 출력 보기, 터치 제스처로 좌우 넘기기, 두 손가락으로 확대·축소하기, PWA를 홈 화면에 설치해 app처럼 쓰기입니다. 터치 기능은 Blink Shell에서 배웠습니다. 앞서 한 달 넘게 써 봐서 어떤 gesture를 매일 쓰고 어떤 것은 demo용인지 알고 있었습니다. 입력 쪽에는 skill 자동 완성 palette도 붙여 한눈에 호출 가능한 것을 볼 수 있게 했습니다.
의외로 가장 편리한 것은 이미지 업로드였습니다.휴대폰으로 사진을 찍거나 스크린샷을 찍어 webui에 끌어다 놓으면 백엔드가 uploads/ 에 저장하고 로컬 경로를 돌려줍니다. 그 경로를 현재 agent pane에 붙여 넣으면 agent가 Read로 바로 읽을 수 있습니다. 출퇴근길에 본 흥미로운 디자인, 버그 스크린샷, 화이트보드의 스케치를 그 자리에서 agent에게 보내고 계속 질문할 수 있습니다. 집에 돌아갈 때까지 기다릴 필요가 없습니다.
다시 multi-agent로 돌아와, 이번에는 tmux pane을 cell로 썼습니다
multi-agent를 만들기로 한 데에는 다섯 가지 이유가 있었고, 가장 큰 이유는 주 context를 잡무로 채우고 싶지 않았기 때문입니다.
주 context를 압축하지 않기
다른 agent에게 맡긴 세부 작업(자료 검색, test 실행, boilerplate 작성)으로 main의 context가 가득 차지 않습니다. 남은 공간은 주 에이전트의 추론이 정말 필요한 부분에 쓸 수 있습니다.
같은 요구사항을 여러 번 말하지 않기
한곳에서 지시하면 각 CLI에 일이 배분됩니다. terminal 세 개를 열고 CLI 세 개에 같은 prompt를 반복해서 붙여 넣을 필요가 없습니다.
병렬 처리로 속도 높이기(git worktree와 함께)
하나의 task를 병렬로 처리할 수 있는 하위 작업(여러 브랜치에서 시도, N개 PR 동시 진행)으로 나눕니다. pane마다 git worktree 하나씩 배정해 작업 디렉터리가 서로 간섭하지 않게 합니다. 원래 한 줄로 이어지던 작업 시간을 겹쳐 놓는 셈입니다.
이유가 분명해진 뒤 기존 방법의 한계를 점검했습니다. 간단한 것부터 깊은 것까지 세 가지입니다.
Headless 모드
claude -p,codex -p 같은 방식입니다. 빠르고 스크립트로 작성하기 쉽지만 기능이 줄어듭니다. skill이 로드되지 않고, MCP가 연결되지 않으며, 직접 만든 agent도 사용할 수 없습니다. 호출할 때마다 처음부터 시작하므로 대화 맥락도 이어지지 않습니다. 독립적인 task에는 괜찮지만 상태를 공유하는 협업에는 부족합니다.
제가 원하는 것은 “CLI를 넘나들며 모든 기능을 쓰는 multi-agent”입니다. 같은 task 안에서 CLI별 강점에 따라 일을 맡기고, 각각 자신의 skill / MCP를 쓰면서 서로 소통하는 방식입니다. 기존 세 가지 방법으로는 불가능해서 tmux pane을 바탕으로 직접 한 층을 쌓기로 했습니다. 저는 이 시스템을 tmux-relay이라고 부릅니다. 아래에서 말하는 “중계 시스템”은 모두 이것을 가리킵니다.
구성은 세 층입니다
맨 아래에는 작업 window 하나가 있고 pane은 상시 실행하지 않습니다. main agent가 task에 맞는 CLI를 고른 뒤에야 pane을 열어 그 CLI를 시작합니다. 어떤 CLI가 적합한지는 커뮤니티 평가와 제가 직접 써 보며 형성한 선호도를 바탕으로 판단합니다. 다 쓰면 그대로 두었다가, 너무 오래 유휴 상태이면 회수합니다.
idle 상태인지 판단할 때는 그 순간 pane 화면을 봅니다. agent가 입력을 기다리는지 실행 중인지를 출력 내용으로 구분합니다. lock이나 기록은 유지하지 않고 매번 다시 확인합니다.
idle 판단 기능은 현재 Claude Code pane에서만 검증했습니다.prompt와 처리 중 표시 문구는 CLI마다 다르므로, 다른 CLI를 지원하려면 각각 판단 규칙을 작성해야 합니다.
완료 알림에는 polling을 쓰지 않고 tmux 자체 hook 메커니즘을 씁니다. pane이 종료되면 대기 중인 dispatcher를 깨웁니다.
이 시스템에는 team agent의 마지막 한 조각이 아직 없습니다. pane끼리 직접 서로를 부를 수 없다는 점입니다. 그래서 publish/subscribe 방식의 작은 서비스인 session-channel 를 따로 만들어 보완했습니다. pane은 channel을 통해 서로 소통하고 중개자를 거치지 않아도 됩니다.
tmux는 CLI를 넘나드는 agent의 다리가 됩니다
send-keys + capture-panewait-for + Stop hooktmux a 어떤 기기에서든 연결할 수 있습니다trade-off도 분명히 밝혀야 합니다
send-keys는 일반 텍스트라 typed schema가 없습니다. stdout JSON Lines로 보완합니다.- pane buffer에는 history-limit(저는 10000줄로 설정)이 있어 긴 task의 중간 출력이 잘릴 수 있습니다.
- tmux는 본래 message bus가 아니므로 message reliability는 직접 처리해야 합니다(signal file + retry).
- 모든 기능을 쓰는 모드는 headless보다 리소스를 많이 씁니다. pane 여러 개에서 각각 전체 기능을 갖춘 CLI를 실행하면 메모리가 금세 소진됩니다.
추가 팁: context가 거의 찼을 때 handoff하기
이 방법은 “여러 pane을 동시에 실행할 수 있는” 환경에서만 가능합니다. 어느 session의 context 사용률이 70-80%에 이르면 더 쓰다가 compact한 뒤 품질이 떨어질 수 있습니다. 이때 새 tmux pane을 열고 같은 CLI를 시작한 다음, 거의 찬 session으로 돌아가 이렇게 말합니다.
작성한 뒤 새 pane에서 handoff.md 을 읽고 작업을 이어갑니다. 기존 session은 자연스럽게 compact되거나 종료됩니다. CLI session 하나가 스스로 compact하면 잃어버린 미묘한 맥락을 이어받을 곳이 없지만, 여러 pane이 있으면 이어받을 agent가 있습니다.
이 시스템으로 얻은 것은 “지금 누가 무엇을 하는지 언제든 볼 수 있고”+“CLI 종류에 구애받지 않으며”+“context를 이어받을 때 놓치지 않는 것”입니다. multi-agent debug가 막히면 tmux를 엽니다. 각 agent가 어느 prompt에서 막혔는지 한눈에 보입니다.
QA agent 하나를 상시 실행해 API 대신 구독을 씁니다
일상적인 QA에는 구독형 CLI를 tmux pane에서 실행하는 편이 token당 과금되는 API보다 훨씬 저렴합니다. multi-agent 시스템은 “task가 들어올 때만 작업을 맡기는” 용도지만 QA는 다른 상황입니다. agent에게 일을 시키기보다는 조사하고, 함께 생각하고, 현재 상태를 정리하도록 요청하는 것입니다. 이 부분을 API(Anthropic / OpenAI / Google API)로 처리하면 많이 물어볼수록 비용이 늘어납니다.
저는 tmux pane 하나에서 구독형 CLI(Claude Code, Codex, Gemini 모두 월 요금제가 있습니다)를 상시 실행하고, 휴대폰에서 직접 만든 dashboard widget으로 질문을 보냅니다. 뒤에서는 마찬가지로 send-keys 로 그 pane에 입력하지만, 과금은 “구독 정액”이지 “token당 과금”이 아닙니다.
그림 속 캐릭터 이미지는 Live2D로 만들었습니다. 마우스를 움직이면 시선이 따라오고 agent의 답변이 streaming되는 동안 입도 함께 움직입니다. 순전히 시각적인 디테일이지만 오래 대화하다 보면 실제로 조금은 곁에 있는 느낌이 듭니다.
API 과금 vs 구독 + tmux pane
- API 사용:질문할 때마다 token 단위로 과금되어 많이 물으면 요금이 치솟습니다. 장점은 시간대별 한도가 없고 무제한으로 병렬 실행할 수 있다는 것입니다.
- tmux pane + CLI 구독 사용:월 요금이 고정되어 있고, 5시간 / 7일 한도를 다 쓰면 거기서 멈추므로 예상치 못한 요금은 없습니다. 대신 한도가 엄격하고 병렬 실행을 무한정 늘릴 수 없습니다.
tmux pane이 이 방식의 핵심입니다. CLI의 “대화형 모드”를 원격에서 send-keys로 호출할 수 있는 접점으로 바꿔 기기 어디에서든 사용할 수 있게 해 줍니다.
지금 제 stack은 이렇습니다
집의 mac mini에서 default session이 24/7 실행됩니다. 아침에는 서재에서 컴퓨터를 켜고 ssh attach한 뒤, 외출할 때 detach하고, 출퇴근길에는 휴대폰 PWA로 연결하고, 밖에서는 MacBook으로 바꿉니다. 그동안 같은 session을 끊김 없이 계속 씁니다. 상태 표시줄에는 CLI별 한도와 시스템 상태가 보입니다. multi-agent가 필요한 task는 중계 시스템에 조율을 맡기고, 저는 결과를 보고 결정만 내리면 됩니다.
지난 3개월을 돌아보면 상태 표시줄에서 화면 분할, 원격 접속, multi-agent 오케스트레이션으로 이어지는 각 단계는 처음부터 계획한 것이 아니었습니다. 그때그때 불편한 점을 해결하려고 손을 댔고, 끝나면 다음 불편한 점을 살폈습니다. tmux를 줄곧 바닥에 두고 바꾸지 않은 이유는 매번 필요한 만큼은 해 줬기 때문입니다.
이 시스템은 원래 저 혼자 쓰려고 만들었습니다. 앞으로 하나씩 정리해 오픈소스로 공개할 예정입니다.tmux-webui,tmux-relay,session-channel…각 도구의 경계를 깔끔하게 나누고, 문서를 명확히 쓰고, 단독 설치가 가능할 때까지 의존성을 줄이겠습니다. 구체적인 일정은 정하지 않았습니다. 하나가 끝나면 하나씩 공개하겠습니다.
꼭 필요한 조건을 체크하고 어떤 방식이 먼저 제외되는지 보세요
headless, sub agent, team agent를 소개한 세 카드에는 제가 직접 쓰며 막혔던 지점을 적었습니다. 여러분의 조건으로 바꾸면 먼저 제외되는 방식은 다를 수 있습니다.아래에서 꼭 필요한 조건을 체크하면 다섯 행짜리 표가 나옵니다. 이 글에서 언급한 다섯 가지 실행 방식이 각각 한 행을 차지하고, 제외된 칸에는 그 이유가 되는 본문 원문을 바로 표시합니다. 모든 처리는 브라우저에서 실행됩니다. 무엇을 붙여 넣을 필요도 없고 데이터가 밖으로 전송되지도 않습니다.
판단 기준은 모두 본문에서 가져왔습니다. 각 칸의 제외 이유는 본문 문장을 그대로 인용합니다. headless 관련 두 문장은 〈Headless 모드〉 카드에, sub agent와 team agent는 각각의 카드에, 중계 시스템 관련 문장은 〈trade-off도 분명히 밝혀야 합니다〉와 idle 판단 부분에 있습니다. 원래 다른 방식을 설명한 인용문을 다른 행에 적용한 칸에는 괄호로 그 사실을 밝힙니다. 이 한계는 2026년 2월부터 3개월 동안 한 사람이 자신의 mac에서 해당 CLI들을 사용하며 관찰한 결과이지, 각 CLI의 사양서가 아닙니다. 본문에서 언급하지 않은 칸은 모두 “확인할 수 없음”으로 표시하고 임의의 기본값을 채우지 않습니다. 그 칸에 표시되는 문구에는 따옴표가 없습니다. 본문에 무엇이 없는지 설명하는 말이지 본문의 원문이 아니기 때문입니다.
한 가지부터 고르세요. 네 가지를 동시에 시작하지 마세요
이 글에는 활용 방식 네 가지가 나옵니다. 대부분 한꺼번에 모두 도입하면 막힙니다. 순서를 잘못 고르면 환경을 어지럽힌 뒤 되돌리기도 번거로워집니다.
개발 환경과 지금 가장 불편한 점을 AI에 알려주고, 어느 방식부터 시도하는 것이 좋은지와 첫 주에 구체적으로 할 일 3가지를 골라 달라고 하세요.
더 읽을거리
지난 3개월 동안 실제로 참고했고 설계 결정에도 영향을 준 자료입니다.
| 자료 | 중요한 이유 |
|---|---|
| tmux man page | 처음부터 끝까지 읽으면 평소에 쓰지 않던 기능이 얼마나 많은지 알게 됩니다.pipe-pane / capture-pane -p / wait-for 이렇게 간과했던 primitive가 이후 CLI를 넘나드는 오케스트레이션의 기반이 됐습니다. |
| 《tmux 사용과 기본 설정, 입문부터 야근까지 영상 하나로 끝!》 | 지난 3개월 동안 제 tmux 기본기를 주로 익힌 영상입니다. 중국어로 되어 있고, 실습 위주이며 군더더기가 없습니다. |
| openclaw | 제가 tmux를 접하게 된 출발점입니다. openclaw 자체는 tmux가 아니라 process spawn을 쓰지만, “여러 agent가 함께 일하게 하기”라는 발상은 여기에서 얻었습니다. |
| Blink Shell | iOS의 고품질 SSH client입니다. 터치 제스처 설계도 뛰어나서, 그 제스처를 나중에 tmux-webui에 옮겼습니다. |
| iSH | iPhone에서 무료로 쓸 수 있는 Linux shell입니다. mac mini에 ssh attach하려고 처음 써 본 도구입니다. |
| mosh | 네트워크가 바뀔 때 ssh 연결이 끊기는 문제를 해결하려 했지만 메모리 요구량이 커서 주력 머신에서는 원활하게 실행되지 않아 결국 포기했습니다. |