AI 활용 노트Last reviewed · 2026-06← 목록

터미널 밖으로 나온 Claude Code

터미널 안에만 살던 대화 기록을 웹으로 꺼냈다. 어느 기기에서든 지난 세션을 검색해 다시 잇고, 폰에서 새 세션을 원격으로 켠다. 집에 켜 둔 컴퓨터 한 대면 된다.

1전체 그림

데이터는 왼쪽에서 오른쪽으로만 흐른다.

원본

기록

Claude Code가 대화 한 턴 한 턴을 기록 파일(JSONL)로 자동 저장. 모든 것의 출발점.

매 1분

변환

순찰 스크립트가 새로 바뀐 기록만 골라 사람이 읽는 웹페이지로 변환.

상시

서빙

작은 파이썬 웹 서버가 변환된 페이지를 내보냄. 죽으면 OS가 자동으로 되살림.

어디서든

열람

사설망(Tailscale)으로 내 모든 기기에서 같은 주소로 접속. 주력은 폰.

↩ 역방향이 하나 있다. 열람 화면의 입력칸에서 보낸 메시지가 서버를 거슬러 올라가 데스크탑에서 새 Claude Code 세션을 켠다(5절). 그 세션이 다시 첫 칸의 기록을 남기고, 1분 뒤 목록에 나타난다. 고리가 닫히는 셈이다.

2원본은 기록 파일 하나, 나머지는 전부 사본

이 시스템의 데이터 규칙은 이 한 줄이 전부다.

원본 — JSONL 기록 파일

Claude Code가 스스로 남기는 표준 기록(~/.claude/projects/ 아래, 세션당 한 파일). 나는 이 파일을 직접 만들지도, 고치지도 않는다. 백업 대상도 이것뿐이다.

사본 — 대시보드의 모든 것

세션별 대화 페이지, 목록, 검색 화면, 분리 저장된 첨부 이미지. 전부 원본에서 기계적으로 다시 만들 수 있는 파생물이라, 통째로 지워도 1분 뒤 되살아난다.

이 규칙이 실무에서 뜻하는 것

· 목록 페이지가 마음에 안 들어도 그 파일을 손으로 고치지 않는다. 어차피 1분 뒤 재생성되며 수정이 사라진다. 바꾸려면 변환기의 템플릿(코드)을 고친다.

· 백업은 원본만 챙긴다. 사본까지 백업하면 용량만 몇 배가 되는데, 어차피 다시 만들 수 있는 것들이다.

· 사고가 나면 원본이 멀쩡한지부터 본다. 멀쩡하면 나머지는 전부 복구 가능한 문제다.

3변환기 — 매 분 도는 순찰 자동

cron(정해진 주기마다 명령을 자동 실행하는 OS 기본 기능)이 1분에 한 번 변환기를 깨운다. 깨어난 변환기가 하는 일은 세 가지다.

바뀐 것만 변환

매번 전체를 다시 만들지 않는다. 이미 변환된 세션은 건너뛰고 새로 바뀐 기록만 처리하기 때문에 1분 주기를 버틴다.

이미지는 밖으로

첨부 사진을 페이지 안에 박지 않고 별도 폴더로 빼서 링크한다. 사진 많은 세션 하나가 4.4MB → 0.4MB로 가벼워졌다.

사라질 뻔한 메시지 구조

답변 생성 중에 내가 보낸 입력(대기열 메시지)은 기록에서 누락되기 쉽다. 변환 단계에서 따로 찾아내 페이지에 살려 둔다.

왜 "대화가 끝나는 순간"이 아니라 "1분마다"인가

처음엔 턴이 끝나는 이벤트(hook)에 변환을 걸었다. 그런데 "끝났다"는 신호가 "기록이 디스크에 다 써졌다"는 보장은 아니었다. 변환기가 반쪽짜리 기록을 읽는 일이 실제로 났다. 이벤트에서 떼어내 1분 주기 순찰로 바꾸자 사라졌다. 즉시성을 1분 내주고 정합성을 산 거래였다.

4서버와 접속 — 작은 서버 하나, 사설망 하나

변환된 페이지를 내보내는 건 상시 켜 둔 데스크탑에서 24시간 떠 있는 한 파일짜리 파이썬 웹 서버다. 꺼지면 OS의 서비스 관리자가 알아서 되살린다(KeepAlive).

서버가 받는 요청들

페이지 서빙목록, 검색 화면, 세션별 대화 페이지, 분리된 이미지
검색검색어가 오면 원본 기록을 직접 훑어 관련도순으로 응답 (AND·OR·NOT·"구문" 지원)
활성 표시지금 켜져 있는 세션을 몇 초 간격 폴링으로 목록에 표시
새 세션 시작역방향 흐름의 입구. 5절에서 펼친다
제목 편집세션 제목을 화면에서 바로 바꿔 저장
요청 로그모든 요청을 파일로 남긴다. 사고가 나면 가장 먼저 여는 곳

접속 — 같은 주소, 내 모든 기기

서버는 한 대뿐이고, 다른 기기는 Tailscale(내 기기들끼리만 직접 연결되는 개인 VPN)이 부여한 사설 IP로 직접 붙는다. 프록시도, 공개 인터넷 배포도 없다.

데스크탑
서버 본체 · 상시 켜 둠
노트북
외출용 브라우저
폰 (주력)
홈 화면에 PWA로 설치
태블릿
브라우저
왜 HTTPS가 아닌가 (그리고 왜 주소를 안 적나)

접속 주소가 사설망 안에만 존재해 공개 인터넷에서는 닿지 않고, 구간 암호화는 Tailscale(WireGuard)이 이미 해 준다. 그래서 인증서·도메인·로그인 관리를 통째로 생략하고 평문 HTTP로 두었다. 개인 도구에서 이만한 유지비 절감이 드물다. 대신 실제 IP나 포트 같은 배포 좌표는 이 문서에 적지 않는다.

5역방향 — 폰에서 새 세션을 켠다

보기만 하는 건 아니다. 화면 아래 입력칸에 글이나 이미지를 넣으면 집의 데스크탑에서 새 Claude Code 세션이 켜진다. 밖에서 제일 많이 쓰는 기능이다.

1
브라우저에서 메시지(+이미지) 입력 → 서버로 전송. 이미지도 요청 본문에 실어 보내므로(base64) 어느 기기에서든 동작한다.
2
서버가 새 세션 ID를 미리 만들고 요청을 접수. 이미지는 본인만 읽을 수 있는 권한의 임시 파일로 저장. 같은 요청이 짧은 간격에 두 번 오면 한 번만 처리한다. 모바일 네트워크의 재전송 때문에 세션이 두 개 생긴 적이 있어서다.
3
서버가 터미널을 열어 그 세션 ID로 Claude Code를 실행. 요청 자체엔 즉시 "접수됨"을 돌려준다. 처음엔 작업이 끝날 때까지 수십 초를 붙들고 있었는데, 폰에서는 멈춘 것처럼 보였다. 접수와 실행을 분리하니 해결됐다.
4
새 세션이 평소처럼 기록 파일을 남긴다 → 1분 뒤 변환 → 목록에 등장. 그 사이엔 "세션 시작 중…" 임시 행이 맨 위에서 자리를 지킨다.

6스스로 돌아가게 하는 장치들

매일 들여다보지 않아도 되도록 감시, 백업, 배포에 안전장치를 하나씩 달았다.

죽음 감지는 바깥에서

변환 순찰이 돌 때마다 외부 하트비트 서비스(healthchecks.io)에 신호를 보낸다. 신호가 끊기면 바깥에서 알림이 온다. 죽은 시스템은 자기 부고를 못 보내니까. 저장 폴더가 지나치게 커져도 경고가 온다.

백업은 원본만, 매주

원본 기록 전체를 압축해 클라우드 드라이브에 저장하고, 최근 몇 주 치만 남기고 자동 회전한다. 사본(페이지·이미지)은 뺐다. 2절의 규칙대로 언제든 다시 만들 수 있어서다.

배포의 함정 하나

변환기 코드를 고치면 전체 재생성을 한 번 돌리고, 서버 프로세스를 확실히 종료한 뒤 재시작한다. 재시작했다고 믿었는데 옛 프로세스가 계속 살아 있던 함정을 한 번 밟았다.

7실제 화면

브라우저로 보는 대시보드를 그대로 본뜬 정지 화면이다. 세션 제목과 시간, 숫자는 전부 가상이고 버튼은 눌리지 않는다.

🔒 http://100.x.x.x:····/ — Tailscale 사설망 (실제 주소·포트는 비공개)
Claude Code 대시보드
총 325개 세션
대화ID조작마지막 대화 ▼시작종료지속메시지
세션 시작 중… ······· 방금
신규 가입 폼 유효성 검사 버그 수정 a3f1c0d9 방금2026-06-09 14:242026-06-09 14:328분23
주간 매출 리포트 자동 집계 스크립트 작성 7b29e8a4 12분 전2026-06-09 14:052026-06-09 14:2116분88
고객 문의 자동 분류 프롬프트 튜닝 c5d70f12 1시간 전2026-06-09 13:022026-06-09 13:4038분142
이미지 업로드 용량 제한 버그 추적 e1846b3a 어제2026-06-08 21:102026-06-08 22:141시간 4분64
위키 전체 검색 기능 추가 90ab2fd7 2일 전2026-06-07 10:482026-06-07 12:031시간 15분117
배포 파이프라인 캐시 정리 + 회의록 요약 템플릿 2f6c9e05 3일 전2026-06-06 09:152026-06-06 09:4631분9
픽셀 마스코트 + 총 세션 수 — 걸어다니는 로봇. 서버가 살아 있다는 표시이자, 솔직히는 그냥 애착.
검색창 — 모든 세션의 대화 내용을 관련도순으로 검색한다(AND·OR·NOT·"구문").
활성 세션 — 지금 켜진 대화만 진한 색으로 뜨고 중지 버튼이 보인다. 나머지는 회색.
활성 버튼 — 흐려진 옛 세션을 그 자리에서 다시 이어 간다(resume).
"세션 시작 중…" — 원격으로 켠 직후, 변환되기 전까지 맨 위를 지키는 임시 행.
하단 입력칸 — 글이나 이미지를 보내면 데스크탑에서 새 대화가 시작된다(5절의 역방향).

8이 구조에서 가져갈 만한 것

다른 시스템에 옮겨 심는다면 스크립트가 아니라 이쪽이다.

원본은 하나, 나머지는 전부 파생물로.

손으로 고치는 건 원본과 그걸 만드는 코드뿐. 파생물을 지워도 되는 것으로 유지하면 백업과 복구, 실험이 전부 싸진다. 백업 대상도 원본 하나로 줄어든다.

"끝났다"는 이벤트는 "저장됐다"는 보장이 아니다.

쓰기 완료를 보장하지 않는 이벤트에 후속 처리를 걸면 경합이 난다. 짧은 주기 순찰(폴링)이 더 단순하고 안전했다. 즉시성을 조금 내주는 대신.

감시는 시스템 바깥에 둔다.

자기 상태를 자기에게 보고시키면 죽는 순간 보고도 같이 죽는다. 신호가 멈추면 알림이 오도록 방향을 뒤집어 외부에서 지켜보게 했다.

개인 도구의 멀티 디바이스는 사설망이 가장 싸다.

공개 배포 없이 내 모든 기기에서 접속이 된다. 인증·도메인·인증서 관리가 통째로 사라지고, 외부에 노출되는 면적은 0이다.

원격 트리거는 접수와 실행을 분리한다.

모바일은 긴 대기를 못 견딘다. 요청에는 즉시 "접수됨"을 돌려주고 실행은 뒤에서 한다. 재전송으로 생기는 중복 요청도 서버 쪽에서 걸러 줘야 한다.

⚠️ 이 문서는 구조 설명용이다. 실제 접속 주소·포트·기기 구성·대화 내용은 포함하지 않으며, 화면 미리보기 속 데이터는 전부 가상이다. 구현 코드는 공개 repo github.com/sidoyu/claude-session-dashboard에 있다.