-
Notifications
You must be signed in to change notification settings - Fork 0
Single Session Model
pytmux 는 tmux 와 달리 이름 붙은 여러 세션을 두지 않는다. 하나의 서버(데몬)가 탭·윈도우·패널로 이뤄진 단 하나의 세션을 호스팅하고, 여러 클라이언트가 그 동일한 화면에 붙어 공유한다. 이 페이지는 그 모델이 무엇이고, tmux 와 어떻게 다르며, 무엇을 얻고 무엇을 포기했는지를 솔직하게 정리한다.
flowchart TD
D["서버(데몬, 단일 asyncio 루프)"]
S["Session — 항상 하나. 사용자 표면에서 이름/전환 개념 없음"]
T["Tab — 최상위 전환 단위 (tmux 의 '윈도우' 역할)"]
W["Window — 탭마다 1:1 로 종속되는 렌더 영역"]
P["Pane — 이진 분할 트리의 잎. 셸 1개 = PTY + 화면 버퍼"]
D --> S
S --> T
T --> W
W --> P
즉 Session → Tab → Window → Pane 의 4계층이지만, 사용자가 실제로 다루는 전환 단위는 탭이다. 세션은 항상 하나뿐이라 배경으로 물러나 있다.
tmux 는 여러 개의 이름 붙은 세션을 만들고(new-session -s work), 그 사이를
오가며(switch-client, choose-tree) 쓰는 모델이다. 각 세션은 자기만의 윈도우 목록을
가진다. 강력하지만, 그만큼 사용자가 머릿속에 "세션 → 윈도우 → 패널" 3계층을 늘 들고
있어야 하고, "지금 어느 세션에 붙어 있는가"를 신경 써야 한다.
| tmux | pytmux | |
|---|---|---|
| 최상위 전환 단위 | 이름 붙은 세션 여러 개 | 탭 하나의 줄 (세션은 하나) |
| 작업 공간 분리 | 세션 + 윈도우 | 탭으로 일원화 |
| "어디에 붙어 있나" | 세션 선택 필요 | 항상 그 하나의 세션 |
| attach | attach -t <name> |
이름 없이 단일 세션에 붙음 |
pytmux 는 tmux 의 세션 + 윈도우 두 층이 하던 일을 "탭" 한 층으로 합쳤다. 여러 작업 공간이 필요하면 세션을 새로 파는 대신 탭을 연다. 탭마다 단일 윈도우가 종속되고, 그 윈도우를 패널로 분할한다.
분할은 이진 트리라서 얼마든지 중첩할 수 있다. 한 탭 안에서 좌우·상하 분할을 섞어 원하는 레이아웃을 만든다.
대상 사용 시나리오(원격 개발 머신에서 셸 몇 개 + 빌드/AI 작업 패널을 띄워두는 용도)에서 세션을 여러 개 굴릴 일은 드물었다. 거의 모든 사용자가 세션 하나에 윈도우(탭) 몇 개로 끝났고, 그렇다면 "세션"이라는 한 계층은 사용자에게 외워야 할 개념만 늘리고 실익은 적은 층이었다. 그래서 세션 전환 UI 를 사용자 표면에서 통째로 들어내고, 탭으로 단일화했다. 이 결정은 프로젝트 초기(탭 모델 도입기)에 내려졌고, 이후 모델의 뼈대로 굳었다.
서버는 단일 스레드 asyncio 이벤트 루프 하나로, 모든 패널의 PTY 읽기 → 터미널 에뮬레이션 → dirty 표시 → 클라이언트로의 화면 diff push 를 처리한다. 상태가 하나의 세션 트리로 응집되어 있으면 이 루프가 다뤄야 하는 권위 상태가 단일해진다. 여러 독립 세션을 동시에 들고 그 사이 라우팅·격리를 관리하는 복잡도를 애초에 들이지 않는다. 서버가 레이아웃의 단일 권위자이고 클라이언트는 받은 좌표를 그리기만 하는 구조와도 잘 맞는다.
세션이 하나뿐이면 "여러 클라이언트가 같은 것을 본다"가 기본값이 된다. 별도의 세션 선택·매칭 협상이 없다.
서버(데몬)가 셸 PTY 를 소유하고, 클라이언트(터미널 앱)는 거기에 붙어 화면을 그린다.
- attach: 클라이언트는 이름 없이 그 하나의 세션에 붙는다. 붙는 순간 누적 스트림이 아니라 현재 화면 전체 스냅샷을 받아 즉시 복원한다.
- 다중 클라이언트 미러링: 여러 클라이언트가 동시에 같은 세션에 붙을 수 있다. 모두 같은 탭·패널·레이아웃을 본다(미러링). 레이아웃은 붙은 클라이언트들의 최소 크기에 맞춰 동기화된다.
- detach: 클라이언트가 빠져나가도 서버와 셸은 그대로 남는다. 클라이언트가 0개여도 셸은 계속 돈다(긴 빌드·원격 작업 유지). 다시 실행하면 같은 세션에 이어 붙는다.
- 터미널 창을 닫아도(SIGHUP) 클라이언트만 죽고 데몬은 영향을 받지 않는다.
세션이 하나라서, "어느 세션을 미러링할지"를 고를 필요 없이 붙으면 곧 같은 화면이다.
tmux 에서 세션·윈도우로 하던 일을 pytmux 는 탭과 레이아웃 기능으로 흡수한다.
-
탭 = tmux 의 윈도우 역할.
new-tab(=new-window)·rename-tab·kill-tab, 다음/이전/번호 선택, 마지막 탭 토글, 재정렬/이동을 제공한다. 상단 탭바(tmux 엔 없는 UI)로 마우스 클릭·드래그·키보드로 다룬다. -
탭별 레이아웃 슬롯: 각 탭의 윈도우+패널 트리를 이름 슬롯으로 저장하고
(
layout-save) 현재 탭에 덮어쓰거나 새 탭으로 불러온다(layout-load). tmux 에서 "특정 세션을 특정 레이아웃으로 세팅해 두던" 작업을 저장된 레이아웃을 탭에 불러오는 방식으로 대신한다. - 패널 분리/합치기: 패널을 새 탭으로 떼거나(break) 다른 탭의 패널을 끌어오는(join) 조작으로, 세션 간 윈도우 이동 같은 재배치 욕구를 탭 단위로 충족한다.
솔직히 말하면, 이 모델은 만능이 아니다. 명시적으로 포기한 것이 있다.
-
이름 붙은 다중 세션과 세션 전환:
new-session/switch-client/세션 단위choose-tree가 없다. 완전히 격리된 별개 작업 공간 여러 벌을 세션 이름으로 오가는 워크플로를 쓰던 사용자에겐 직접적인 대체가 없다(탭으로 풀어야 한다). - 세션 단위 격리: 모든 탭이 한 세션 아래 있으므로, 세션 경계로 작업을 칸막이하는 습관은 탭 그룹핑·레이아웃 슬롯으로 우회해야 한다.
대량의 독립 세션을 세션 이름으로 관리하는 헤비 유저라면, 이 단순화가 제약으로 느껴질 수 있다. 그 점은 의도된 트레이드오프다.
- 단순한 멘탈 모델: 외울 계층이 하나 줄었다(세션 선택 불필요).
- 단순한 공유: 다중 클라이언트 미러링이 협상 없이 기본 동작이 된다.
- 단순한 서버: 단일 세션 트리 = 단일 권위 상태라 단일 스레드 asyncio 루프가 다루기 쉽고, 레이아웃 권위가 한 곳에 모인다.
-
세션 보존 재시작: 살아 있는 셸·실행 중 프로그램·스크롤백을 보존한 채 서버 코드만
제자리에서 교체하는 재시작(
restart-server)이, 직렬화·복원 대상이 하나의 세션 트리 라서 더 다루기 쉽다. -
원격 페더레이션과의 궁합: 원격 pytmux 의 탭을 로컬 탭바에 흡수하는 페더레이션
(
remote-attach)이, "여러 세션 중 어느 것을 가져올지"가 아니라 그 하나의 세션을 탭으로 가져오는 단순한 합성이 된다. 중첩 tmux-in-tmux 대신 탭 흡수로 푼다.
요컨대 pytmux 는 "세션을 여러 개 두는 일반성"을 포기하는 대신, 공유·재시작·페더레이션이 한결 단순해지는 쪽을 택했다. 대상 사용 시나리오에서 세션 다중화가 드물다는 관찰이 이 선택을 정당화한다.
소개 · 사용
- Project-Overview
- User-Manual
- Screenshots
- Settings-Popup
- Single-Session-Model
- Tmux-Feature-Comparison
플러그인
Claude Code 플러그인
- Claude-Code-Plugins
- Dev-Guide-claude-code
- Dev-Guide-claude-token-usage-view
- Dev-Guide-claude-prompt-history
- Dev-Guide-claude-resume
- Dev-Guide-claude-disable-feedback
플랫폼 · 성능
품질 · 보안
리뷰·분석 보고서
연혁
기여