Skip to content

Project Overview

Woojin Kim edited this page Jun 22, 2026 · 2 revisions

프로젝트 소개 (Project Overview)

pytmux 는 Python + Textual 로 만든 tmux 유사 터미널 멀티플렉서입니다. 하나의 터미널 안에서 여러 셸을 패널/탭으로 나눠 쓰고, 앱이나 터미널 창을 닫아도 셸 세션이 계속 살아있게 해 줍니다. 마우스를 1급으로 지원하고, 단축키를 외우지 않아도 메뉴·명령 프롬프트로 거의 모든 동작을 할 수 있다는 점이 특징입니다.

첫 실행 화면


1. 무엇인가

pytmux 는 tmux 처럼 동작하지만, 명령어를 다 외우지 못하는 사람마우스를 좀 더 쓰고 싶은 사람을 위해 만들어졌습니다. 파이썬만 있으면 스크립트 하나로 돌아가므로, tmux 설치·설정이 번거로운 환경(특히 원격 윈도우 환경)에서도 가볍게 쓸 수 있습니다.

단일 서버(데몬)–다중 클라이언트 구조

  • 단일 서버(데몬) 가 셸 PTY 를 보유하고, 여러 클라이언트가 같은 세션에 동시 attach 해 화면을 미러링합니다(최소 크기로 레이아웃 동기화).
  • 서버는 단일 스레드 asyncio 루프로 돌고, 클라이언트와는 길이-프리픽스 프레이밍 기반 IPC 로 통신합니다.
  • 앱을 닫거나(detach) 상위 터미널 창을 닫아도 셸은 데몬에서 계속 돌아가고, 다시 실행하면 이어서 붙습니다(셸 영속성).

계층 모델: 단일 세션

멀티 세션 개념은 사용자 표면에서 제거되었고 항상 하나의 세션으로 시작합니다. 최상위 전환 단위는 (tmux 의 윈도우 역할)이고, 탭마다 단일 윈도우가 종속되며, 그 윈도우를 패널로 분할합니다. 즉 Session → Tab → Window → Pane.

지원 OS

  • macOS / Linux: POSIX PTY 백엔드(Python 3.11 이상 권장).
  • Windows 네이티브: WSL/Cygwin 불필요, ConPTY 백엔드(pip install pywinpty). 실 Windows 11 기기에서 스모크 검증을 마쳤습니다.

Claude Code 토큰 추적 + 원격 페더레이션

Claude 패널

pytmux 는 셸 멀티플렉서에 더해, 패널에서 돌아가는 Claude Code 세션을 위한 기능을 얹고 있습니다 — 실행 중인 탭의 상태 아이콘, 토큰/컨텍스트 사용량 추적, 사용량 리밋 자동 재개, 토큰 과사용 자동 회피 등. 또한 ssh 기반 원격 페더레이션으로 원격 머신의 pytmux 탭을 로컬 탭바에 흡수해 쓸 수 있습니다(tmux-in-tmux 중첩 대신).


2. 핵심 특징

탭 / 패널 / 레이아웃

좌우 패널 분할

  • 패널 분할: 가로/세로 분할, 방향 이동·순환, 줌(전체화면 토글), 번호 점프, swap/rotate, break(새 탭 분리)/join(끌어오기).
  • 레이아웃 프리셋: even-h/v, main-h/v, tiled. 탭별 레이아웃을 이름 슬롯으로 저장/불러오기.
  • 상단 탭바: 탭이 하나여도 항상 표시, 마우스 드래그 재정렬, ESC 방향키 네비, [+]/[x].

다중 탭

  • 활성 패널 테두리: 패널이 둘 이상이면 테두리 박스로 감싸고 활성 패널을 파란색으로 표시.
  • 패널별 스크롤백: copy-mode 진입 없이 휠만으로 과거 출력 확인, 검색·선택 복사·클립보드 연동.
  • 마우스 + 키보드 + 메뉴 세 가지 방식 모두로 제어(우클릭 컨텍스트 메뉴, prefix : 명령 프롬프트, 자동완성·인자 이력).

플러그인 시스템 (delete-to-disable)

시계·달력·디렉토리 트리(ncd)·IME 한/영 배지·Claude Code 통합·프롬프트 히스토리·토큰 사용량 화면·출력 캡처(REC) 등이 모두 pytmuxlib/plugins/<name>/ 디렉토리 하나로 응집된 플러그인입니다. 디렉토리를 지우면 그 기능이 명령·자동완성·렌더 어디에도 안 나타나고 조용히 사라집니다(코어는 플러그인을 직접 import 하지 않고 레지스트리 훅 + getattr 가드로만 닿습니다). :plugins 팝업으로 소프트 on/off 토글도 가능합니다.

자작 VT 파서

pyte 외에 자작 VT 토크나이저(vtparse.py)를 옵션으로 배선해, 대체 화면 버퍼·동기 출력 등 풀스크린 TUI 가 깨지지 않도록 처리합니다.

작업 보존 서버 재시작

restart-server(서버만)·restart-all(서버+클라 동시)·restart-check(드라이런)으로, 열린 패널의 셸·실행 중 프로그램·스크롤백을 살린 채 코드만 새 이미지로 교체합니다. os.execv 인플레이스 re-exec 로 PID 와 상속한 master fd 를 보존해 PTY 를 살립니다.

IME 한/영 배지

우상단에 입력기 한/영 상태를 배지로 표시합니다(macOS 는 TIS 실측, ssh/Linux 는 휴리스틱 폴백). 입력 없이도 즉시 갱신됩니다.

원격 ssh 페더레이션

remote-attach 분홍 탭

remote-attach 로 원격 pytmux 탭을 ssh stdio-proxy 채널 위로 로컬 탭바에 흡수합니다. 원격 패널을 로컬 모델에 미러링하지 않고 per-client 플래그로 통째 릴레이하므로 원격 서버는 무수정입니다. 원격 탭/외곽선은 분홍색으로 구별하고, 경계 횡단 명령은 차단합니다. ssh egress 허용목록(remote_allowed_hosts)으로 나가는 대상을 제한할 수 있습니다.

토큰 회계

  • 활성 Claude 패널 화면에서 컨텍스트 사용률/토큰 수를 추출해 상태줄에 표시하고, 클릭하면 노트북 탭(기간/계정/세션/한도/대사/경고) 토큰 사용량 팝업이 열립니다.
  • 숨은 /usage 프로브 세션으로 실측 한도 숫자를 얻어, 시간 뷰는 시각별 5h 한도 계단식 막대, 한도 뷰는 실측 막대 + 리셋 카운트다운을 보여줍니다.
  • 저장 백엔드는 stdlib sqlite3(usagedb, WAL) 라 신규 의존성이 없습니다.
  • token-saver 로 토큰 과사용 자동 회피를 토글합니다(컨텍스트 잔량 임계 시 자동 정리, 실측 한도 게이트, fail-open 안전장치, 무장된 자동 동작 카운트다운/취소).

3. 아키텍처 한눈에

코어는 pytmuxlib/ 패키지이고, pytmux.py 가 얇은 진입점입니다. 개념적으로 네 갈래로 나뉩니다.

서버측

  • server.py — Server 본체(서버 믹스인을 동적 베이스로 합성).
  • serverio.py — IPC / flush 루프 / 명령 디스패치 / 레이아웃 메시지.
  • serverpty.py — PTY·패널 생성, feed 드레인, EOF, 중첩 탐지.
  • servertree.py — split/kill/move/swap/rotate/break/join 트리 조작.
  • serverpersist.py — 레이아웃·resume·opts 영속 + os.execv 재시작.
  • serverremote.pyRemoteLink 페더레이션.

일부 서버 메서드는 server.py 에 없고 런타임에 플러그인 믹스인으로 합성됩니다(예: Claude 관련 기능). jump-to-def 가 안 닿으면 해당 플러그인 디렉토리를 봐야 합니다.

클라측

  • client.pybuild_client_app() 팩토리(플러그인은 인스턴스 클로저로 부착).
  • clientwidgets.py — MultiplexerView / TabBar / StatusBar.
  • clientscreens.py — 모달 화면들.
  • clientutil.py — 순수 유틸 / 키맵.
  • clientrender.py — 셀그리드 합성.
  • clientnc.py — NcdScreen(디렉토리 트리).

공통

  • model.py — Session→Tab→Window→PaneNode 트리, 레이아웃·프리셋·줌·화면·대체화면.
  • protocol.py — 길이-프리픽스 프레이밍·상수.
  • ipc.py — 크로스플랫폼 소켓(POSIX AF_UNIX + peer-UID, Windows 루프백 TCP + HMAC 토큰).
  • vtparse.py — VT 파서.
  • pty_backend.py / conpty.py — PTY 백엔드(Windows ConPTY 포함).
  • launcher.py / proc.py / keymap.py / i18n.py — 부트스트랩·프로세스·키맵·다국어.

플러그인

pytmuxlib/plugins/<name>/ 아래에 응집됩니다. plugins/__init__.pyload()→Registry 가 서브패키지를 발견·import 합니다. 훅 계약(전부 duck-typed, 부재 시 no-op)은 이 한 곳에 모여 있고, 플러그인 디렉토리 존재 자체가 발견 조건입니다(delete-to-disable).


4. 개발 연혁 요약

pytmux 는 비교적 짧은 기간에 집중 개발되었습니다. 대략적인 흐름은 다음과 같습니다.

  • 부트스트랩 & tmux 기능 완비 — 단일 파일(~3500줄)에서 클라/서버 구조와 핵심 기능 (줌·탭 rename/kill·명령 프롬프트·설정·스크롤백·마우스·메뉴)으로 시작해, FEATURES 카테고리를 하나씩 돌파. 곧 pytmuxlib 패키지로 분해. 대체 화면 버퍼 지원으로 풀스크린 TUI 깨짐을 해결.
  • 탭 모델 & Claude 통합의 탄생 — 멀티세션을 사용자 표면에서 제거하고 Session→Tab→ Window→Pane 으로 재편. CJK/이모지 와이드문자 렌더 픽스. Claude 상태 아이콘과 best-effort 토큰/컨텍스트 표시, 출력 캡처(REC) 도입.
  • 모바일 UX & Claude 특화 UX — 우클릭 통합 컨텍스트 메뉴, ESC 모드 탭바 네비, 종료 확인 팝업, 프롬프트 히스토리, 토큰 사용량 트리, 백그라운드 탭 완료 알림.
  • Windows 네이티브 포트(ConPTY) — WSL/Cygwin 없이 PTY·이벤트 루프·프로세스/시그널·IPC 네 서브시스템을 추상층 뒤로. Proactor 가 ConPTY 파이프에 add_reader 불가 → TCP 루프백 + 패널별 reader 스레드. 실 Windows 11 박스 검증.
  • 작업 보존 재시작(re-exec)os.execv 인플레이스 재시작으로 살아 있는 셸/프로그램·PTY 를 보존한 채 서버 코드만 교체. CLOEXEC 불변식과 스크롤백 스냅샷 복원을 정교하게 처리.
  • LLM 친화 모듈화 & 성능 블리츠 — 클라/서버를 작은 모듈로 분해(클라 −46%, 서버 믹스인 −60~80%). 3-OS CI 매트릭스와 벤치 하니스. 행 단위 screen-delta 등 성능 캠페인.
  • 토큰 가시화 & 그림자 /usage 프로브 — 토큰 추적·로그·상태줄 배지와 토큰리밋 자동재개, 무장된 자동재개 카운트다운. 헤드리스 /usage 가 한도 숫자를 안 내므로 숨은 pyte-스크랩 세션으로 실측 한도 획득. 보안 패스(연결 인증 토큰, 피어-UID 검증, 권한·입력 클램프). (초기의 컨텍스트 자동 정리·하드스톱 자동 /compact·실측 한도 게이트·예산·모델 힌트 등 과사용 자동 완화는 이후 제거.)
  • 토큰 저장 SQLite 이행 — JSONL→.tokens.db(WAL), 이력 임포트, 세션 기준 묶기, 서버측 GROUP BY 로 정확한 생애 합계.
  • NCD 디렉토리 트리 & 플러그인 시스템 — Norton Change Directory 풍 디렉토리 트리 모달. delete-to-disable 플러그인 계약 설계와 Claude 통합 추출 착수.
  • 플러그인 추출 완료, 토큰 정확성 재설계, i18n — 토큰 기록을 코어→플러그인 완전 분리. 핵심 통찰: footer 스크랩과 /usage 는 의미가 달라 영영 일치시킬 수 없다 → 실측 1차화 + 추정/실측 분리 표기, fail-open 게이트. IME 한/영 배지 플러그인, ko/en 다국어화.
  • 원격/페더레이션 & 중첩 attach — ssh stdio-proxy 기반 원격 attach, env-독립 in-band 중첩 탐지(XTVERSION 프로브), 원격 탭 분홍 구별·경계 횡단 차단. 프롬프트 히스토리를 독립 플러그인으로 재구현.
  • 코드 감사, REC 플러그인화, 플러그인 매니저 — 전체 코드 감사 적용(성능·보안), Windows owned-ConPTY 자식종료 감시자, REC 플러그인 추출, :plugins 관리 팝업, ssh egress 허용목록.

오늘날 pytmux 는 자기호스팅 도구입니다 — pytmux 개발 자체의 일상 도구로, 여러 셸을 패널/탭으로 분할하고 detach 후에도 살아남는 영속 셸로 긴 빌드/SSH 를 유지하며, Claude Code 세션을 구동·추적하고, 원격 머신을 페더레이션으로 흡수하는 데 매일 쓰입니다.


5. 빌드 / 실행 / 테스트 quickstart

설치

pip install -r requirements.txt
# 또는 직접: pip install textual pyte wcwidth
# Windows 는 추가로: pip install pywinpty

실행

python3 pytmux.py        # 서버가 없으면 자동 기동 후 attach, 있으면 attach

pytmux 명령으로 어디서든 실행하려면 래퍼를 설치합니다(POSIX ./install.sh, Windows install.ps1). 설치 후:

pytmux              # attach (없으면 기동)
pytmux ls           # 탭/패널 요약
pytmux kill-server  # 서버와 모든 탭/셸 종료
pytmux cmd new-tab  # 외부에서 서버 제어(split-window -h, rename-tab …)

처음 실행하면 평소 쓰던 셸이 전체 화면으로 뜹니다. Ctrl-b(prefix)를 누른 뒤 명령 키를 누르거나, 마우스/메뉴(prefix Enter 또는 우클릭)·명령 프롬프트(prefix :)로 조작합니다.

테스트

python3 tests/run.py                # 헤드리스로 전체 스위트 실행
python3 tests/run.py test_server    # 특정 모듈만

전체 스위트가 모두 통과(N passed, 0 failed)하는지 요약줄을 확인하세요. run.py 는 실패해도 종료코드가 0 일 수 있으니 요약줄을 봐야 합니다. 서브셋 실행은 플러그인 믹스인 특성상 가짜 실패가 날 수 있어 권위는 항상 전체 스위트입니다.

macOS 헤드리스 CI 러너는 일부 PTY 스위트를 인프라 레벨에서 wedge 시키므로 CI 매트릭스에서 제외했고, macOS 검증은 로컬 실행이 권위입니다. 실 PTY·실 ConPTY(Windows)·실 Claude 패널은 드라이버로 검증할 수 없습니다.

매뉴얼·갤러리의 스크린샷은 실제 클라이언트를 헤드리스로 운전해 SVG 로 자동 생성합니다 (python3 scripts/gen_screenshots.py).


관련 문서

  • User-Manual — 설치부터 패널·탭·마우스·메뉴·명령·Claude 연동·운영까지 상세 사용법.
  • Plugin-System — 플러그인 시스템 개요와 기본 제공 플러그인 소개.
  • Plugin-Authoring-Guide — 플러그인 작성법, 훅 계약, delete-to-disable 원칙.
  • Code-Review — 코드 감사·리뷰 기록.
  • Security-Audit — 보안 검토 항목과 강화 내역.

Clone this wiki locally