jacewiki 🌳

warren

최근 수정 시각: 2026-08-28 22:20:10

분류: | AI | 유틸리티

1. 개요

warren은 바니·나비·후추봇 세 PC에서 돌아가는 Claude Code / Codex 세션을 폰 한 화면에서 관제하는 개인용 콕핏이다. Termux로 4분할 tmux를 폰에서 다루던 고통을 없애려고 2026-07-15에 시작했다.

구조가 담백하다. 바니 PC에 허브 서버 한 대(의존성 없는 순수 Node)만 띄우고, 나비·후추봇에는 아무것도 설치하지 않는다 — 허브가 Tailscale SSH로 원격 tmux를 읽고 쓴다. 폰은 Tailscale VPN으로 붙어 HTTP와 SSE로 상태를 받는다.

핵심은 상태 감지다. Claude Code의 Notification·Stop 훅과 Codex의 notify가 허브의 /api/hook으로 이벤트를 밀어 넣어 "입력·승인 대기" 순간을 즉시 잡고, 훅이 없는 환경에서도 capture-pane 휴리스틱으로 폴백한다. 판정은 working → waiting → 최근 훅 → 최근 출력 → idle 순으로 5단계를 밟는다.

2026-0708에 걸쳐 crossbell의 메신저 계열 기능을 네 단계(P1P4)로 흡수하면서 작업 칸반·권한 릴레이·웹 푸시를 전부 가져왔고, 이후 야간 자율 개발 사이클(mochi·council)과 밤 보고서까지 얹혀 단순 관제 도구를 넘어선 개인 개발 파이프라인의 허브가 됐다.

2. 핵심 기능

무엇을 하는가
PANES pane 목록과 스크롤백(ANSI→HTML). 💬 토글을 켜면 Claude Code transcript를 말풍선 대화 뷰로 파싱하고, 목록 자체가 메신저 채팅 목록처럼 바뀐다(마지막 메시지 미리보기·미읽음 배지·📌 고정·스와이프 숨김).
WAIT 대기 중인 pane의 승인 다이얼로그를 구조 파싱해 실제 선택지 버튼을 그린다. 숫자 선택·자유 입력·다중 토글·번호 없는 폼 네 갈래를 각각 다르게 전송한다.
MULTI 로컬 tmux 스플릿처럼 pane 여러 개를 동시에 본다. 모바일 2분할·PC 최대 4분할, 하단 입력 고정. 활성 슬롯만 풀 폴링하고 나머지는 미리보기 캐시를 재활용해 부하를 늘리지 않는다.
BOARD ideation → qna → work → done 작업 칸반(ideabox에서 crossbell을 거쳐 이관). 질문 4타입, 청사진 첨부, 작업 큐의 경합 없는 pickup.
SESS 세 머신의 세션 파일 전체를 목록·검색하고 말풍선으로 읽는다. 폰에서 잡세션을 정리할 수 있고, 라이브·최근 활동 2중 가드와 PIN이 걸려 있다.
USAGE ccwatch(:8790)를 리버스 프록시해 계정별 세션·주간 사용량 바와 리셋 카운트다운을 warren 주소 하나로 본다.

그 밖에

3. 기술 스택

영역 기술
런타임 Node 24, 의존성 0package.json조차 없다
서버 순수 vanilla JS 단일 프로세스(server.js), 프레임워크 없음
프론트 빌드 없는 vanilla JS PWA(hyperscript), 서비스 워커 + manifest
저장 파일 기반 JSON(data/ — 카드·읽음 커서·마크·제목·푸시 구독·야간 사이클), tmp+rename 원자적 쓰기
원격 Tailscale SSH로 tmux 폴링·send-keys (원격 머신에 설치물 없음)
호스팅 바니 PC WSL의 systemd user 서비스 + cloudflared 터널
인증 전송·삭제·릴레이용 PIN 게이트 + 경계는 tailnet과 Cloudflare Access

4. 개발 배경

폰으로 tmux를 만지는 일은 언제나 손해 보는 장사였다. 화면은 좁고, 손가락은 굵고, 정작 필요한 건 "지금 어떤 세션이 나를 기다리는가" 하나뿐인데 그걸 알려면 창을 하나하나 열어봐야 했다.

warren은 그 질문에만 답하도록 만들어졌다. 그래서 첫 화면이 pane 목록이고, 대기 중인 세션이 맨 위로 올라오고, 승인 다이얼로그는 텍스트가 아니라 누를 수 있는 버튼으로 나온다. 여기에 흡수와 확장이 겹치면서 지금은 관제 화면이자 작업 보드이자 야간 자율 개발의 관제탑이 됐다.

이름은 토끼굴(warren) — 바니🐰의 굴이라는 뜻이다.

5. 링크

6. 관련 문서