Paseo는 여러 AI 코딩 에이전트를 내 컴퓨터에서 동시에 실행하고, 어떤 기기에서든 원격으로 조종하는 셀프호스팅(self-hosted) 도구입니다. Claude Code, OpenAI Codex, GitHub Copilot, OpenCode, Pi — 이 다섯 에이전트를 똑같은 화면·똑같은 조작법으로 다룹니다.
핵심은 daemon(데몬)이라는 작은 로컬 서버입니다. 이 데몬이 내 개발 머신에서 에이전트들을 진짜 터미널 프로세스로 돌리고, iOS 앱·안드로이드 앱·데스크톱 앱(Electron)·웹·CLI 같은 클라이언트들이 WebSocket으로 데몬에 접속합니다. 그래서 책상에서 작업을 시작하고, 화장실 가서 폰으로 진행 상황을 확인하고, 터미널에서 스크립트로 자동화하는 게 전부 같은 작업에 대해 가능합니다.
클라우드형 AI 코딩 서비스가 '남의 공장에 일감을 보내는' 방식이라면, Paseo는 공장(에이전트 실행)은 내 집(내 머신)에 그대로 두고, 리모컨(클라이언트)만 여러 개 만들어 어디서든 같은 공장을 조종하는 방식입니다.
그래서 내 dev 환경·내 API 키·내 설정·내 코드가 한 번도 내 머신을 떠나지 않습니다. 리모컨끼리는 종단간 암호화된 신호만 주고받죠. Paseo는 텔레메트리·추적·강제 로그인이 전혀 없다고 못 박습니다(privacy-first).
2025~2026년은 "코딩 에이전트 1개를 잘 쓰는 법"에서 "여러 에이전트를 동시에·원격으로 부리는 법"으로 관심이 옮겨간 시기입니다. Paseo는 이 흐름의 한가운데 있는 오케스트레이션 + 모바일 리모트 컨트롤 도구라 빠르게 떴습니다. TrendShift는 절대 스타 수가 아니라 언급(mention) 모멘텀으로 순위를 매기는데, Paseo는 베타임에도 #18에 올랐습니다.
Claude Code를 돌려놓고 회의에 가면, 다 끝났는지 막혔는지 알 길이 없습니다. 도구를 두 개 쓰면 창도 두 개, 조작법도 제각각. 긴 작업(테스트 풀스위트, 리팩터링)은 자리를 지켜야만 확인이 됩니다.
에이전트는 머신에서 계속 돌고, 폰으로 진행을 보고 후속 지시("테스트도 추가해줘")를 던집니다. 다섯 제공자를 한 인터페이스로 통일하고, 손이 바쁘면 음성으로 받아쓰게 합니다.
| 비교 축 | 클라우드 에이전트 (Devin류·웹 IDE) | 단일 CLI 도구 (Claude Code 단독) | Paseo |
|---|---|---|---|
| 실행 위치 | 제공사 서버(샌드박스) | 내 머신 | 내 머신(셀프호스팅) |
| 제공자 | 대개 1개에 고정 | 1개 | 5개를 한 화면에서 |
| 원격 조종 | 웹만 | 없음(로컬 터미널) | iOS·안드·웹·데스크톱·CLI |
| 프라이버시 | 코드가 서버로 전송 | 로컬 | 로컬 + E2EE relay |
| 음성 제어 | 일부 | 없음 | 내장(Realtime API) |
| 라이선스 | 대개 폐쇄 | 도구별 | AGPL-3.0 오픈소스 |
또 하나 영리한 점: Paseo 자신이 MCP 서버이자 Skill 묶음이라는 것입니다. npx skills add getpaseo/paseo로 설치하면, 한 에이전트가 Paseo를 도구처럼 호출해 다른 에이전트들을 오케스트레이션합니다. 예: /paseo-handoff(Claude로 계획 → Codex로 구현 인계), /paseo-loop(합격 기준까지 반복하는 Ralph 루프), /paseo-committee(서로 대조되는 두 에이전트로 근본원인 분석), /paseo-advisor(작업 자체는 위임하지 않고 두 번째 의견용 어드바이저 에이전트를 띄움). 에이전트가 에이전트를 부리는 구조죠.
Paseo는 npm workspaces 모노레포입니다. 언어는 전부 TypeScript, 패키지는 10개. 역할별로 끊어서 봅시다.
packages/server)모든 것의 두뇌. 에이전트 프로세스를 띄우고, WebSocket API를 열고, MCP 서버 역할까지 합니다.
| 분류 | 기술 | 역할 |
|---|---|---|
| 웹 서버 | Express + ws | HTTP API + WebSocket /ws 실시간 양방향 채널 |
| 에이전트 실행 | node-pty + @xterm/headless | 각 에이전트를 진짜 PTY(가상 터미널) 프로세스로 띄워 입출력 중계 |
| 에이전트 통합 | @agentclientprotocol/sdk (ACP) | 여러 에이전트를 표준 프로토콜로 추상화 |
| 제공자 SDK | @anthropic-ai/claude-agent-sdk, @opencode-ai/sdk, ai(Vercel) | Claude Code·OpenCode 등 각 엔진 직접 구동 |
| 도구 프로토콜 | @modelcontextprotocol/sdk | Paseo를 MCP 서버로 노출(스킬·툴) |
| 음성 | openai(Realtime), sherpa-onnx-node, silero_vad.onnx | 클라우드 STT/TTS + 로컬 VAD(말 시작·끝 감지) |
| 인증·설정 | bcryptjs, zod, ajv, zod-to-json-schema | 비밀번호 해싱, 설정 스키마 검증·JSON Schema 생성 |
| 보조 | pino(로깅), qrcode(페어링 QR), lru-cache, p-limit, tree-kill | 로그·QR 페어링·동시 실행 제한·프로세스 정리 |
놀라운 점: iOS·안드로이드·웹·데스크톱이 전부 한 코드베이스(packages/app)에서 나옵니다. Expo로 만들고, 데스크톱은 그 웹 빌드를 Electron으로 감쌉니다.
| 분류 | 기술 | 역할 |
|---|---|---|
| 프레임워크 | Expo 54 + React Native 0.81 + React 19 | iOS·안드·웹 단일 코드 |
| 라우팅 | expo-router | 파일 기반 라우팅 |
| 상태관리 | zustand + @tanstack/react-query | 클라이언트 상태 + 서버 데이터 캐싱 |
| 터미널 표시 | @xterm/xterm (+ webgl·fit·search 애드온) | 앱 안에서 에이전트 터미널을 그대로 렌더 |
| 애니·UI | react-native-reanimated, unistyles, gesture-handler, @gorhom/bottom-sheet, @dnd-kit | 제스처·드래그·시트 등 네이티브급 UX |
| 음성 입력 | @getpaseo/expo-two-way-audio(자체 네이티브 모듈), expo-audio | 양방향 오디오 스트리밍 |
| 데스크톱 | Electron 41 + electron-builder + electron-updater | 웹앱 + 데몬을 하나의 설치형 앱으로 패키징·자동 업데이트 |
| 분류 | 기술 | 역할 |
|---|---|---|
| 원격 연결 | @getpaseo/relay (tweetnacl, base64-js, ws, cloudflare-adapter) | 외부망에서 클라이언트↔데몬을 종단간 암호화(NaCl)로 중계. Cloudflare Workers에도 배포 가능 |
| 공유 계약 | @getpaseo/protocol (zod) | 서버·클라이언트가 공유하는 와이어 타입·스키마 단일 출처 |
| JS 툴체인 | oxlint + oxfmt (Rust 기반 Oxc) | ESLint·Prettier보다 수십 배 빠른 린트·포맷 |
| 타입체크 | tsgo / @typescript/native-preview | 네이티브(Go) TypeScript 컴파일러 프리뷰로 typecheck 가속 |
| 테스트 | vitest + playwright | 유닛·통합·E2E(브라우저 자동화) |
| 모노레포 관리 | npm workspaces, concurrently, lefthook, knip | 병렬 빌드·git 훅·미사용 코드 탐지 |
"실행 두뇌(데몬)"와 "보는 화면(클라이언트)"을 완전히 분리했습니다. 데몬은 127.0.0.1:6767에서 WebSocket을 열고, 클라이언트는 그저 접속해서 상태를 구독하고 명령을 보냅니다. 덕분에 클라이언트가 죽어도 작업은 계속되고, 동시에 여러 기기가 같은 작업을 봅니다. 서버·클라이언트가 공유하는 메시지 모양은 packages/protocol(zod 스키마)이 단일 출처라, 한쪽만 바뀌어 깨지는 일을 막습니다.
각 에이전트를 API로만 호출하는 게 아니라 node-pty로 진짜 가상 터미널 프로세스를 띄웁니다. 그래서 에이전트가 기대하는 그대로의 환경(컬러·커서·인터랙티브 입력)이 재현되고, 출력은 @xterm/headless로 파싱돼 클라이언트의 xterm.js 화면에 그대로 흐릅니다. 작업마다 git worktree로 디렉터리를 격리해 여러 에이전트를 충돌 없이 병렬로 굴립니다.
API 호출만 하는 방식이 "에이전트에게 메모를 건네는" 것이라면, PTY 방식은 "에이전트에게 진짜 터미널 책상을 하나씩 차려주는" 것입니다. 책상(worktree)이 따로라 옆 사람 작업을 엎지 않죠.
ACP(Agent Client Protocol)는 에디터·클라이언트가 코딩 에이전트와 대화하기 위한 공개 표준입니다. Paseo는 ACP SDK로 제공자별 차이를 한 겹 감싸서, Claude든 Codex든 같은 메시지 규약으로 다룹니다. 새 에이전트가 ACP를 지원하면 Paseo는 큰 수정 없이 흡수할 수 있는 구조죠. (catalog 버전 드리프트를 자동 점검하는 스크립트까지 있습니다.)
외부망(LTE의 폰 → 집 데스크톱)에서 붙을 때는 relay가 다리를 놓습니다. 중요한 건 relay가 내용을 못 본다는 것: tweetnacl(NaCl 암호)로 클라이언트와 데몬이 종단간 암호화한 패킷만 통과시킵니다. relay 자체는 paseo-relay로 셀프호스팅하거나 Cloudflare Workers에 올릴 수 있고, 기본은 ws://, TLS는 옵트인입니다.
relay는 기본적으로 평문 ws://입니다. 공개망에 노출한다면 README의 nginx + Let's Encrypt 예시처럼 PASEO_RELAY_USE_TLS=true로 반드시 TLS를 켜야 합니다. (E2EE가 내용은 가리지만, 전송 계층 보안은 별개 문제입니다.)
| 패키지 | 한 줄 설명 |
|---|---|
| protocol | 서버·클라이언트가 주고받는 메시지의 타입과 검증 규칙. 여기가 바뀌면 양쪽이 같이 따라감 |
| client | 프로토콜 위에 올린 클라이언트 SDK. 앱·CLI가 공통으로 씀 |
| server | 데몬 본체. 에이전트 프로세스·WebSocket·MCP·음성 파이프라인이 전부 여기 |
| app | Expo 기반 멀티플랫폼 클라이언트. 데스크톱의 화면도 이 웹빌드 |
| desktop | Electron으로 앱+데몬을 묶은 설치형 데스크톱. 자동 업데이트 포함 |
| cli | paseo run/ls/attach/send 등 헤드리스 제어. 서버·CI에 적합 |
| relay | 외부망 연결용 E2EE 중계. 별도 셀프호스팅도 가능 |
| highlight / expo-two-way-audio / website | 각각 코드 하이라이트, 오디오 네이티브 모듈, 공식 사이트 |
코드를 처음 연다면 protocol → client → server(daemon) → cli 순서를 권합니다. "어떤 메시지가 오가는가(protocol)"를 먼저 잡으면, 데몬과 CLI가 그 메시지를 어떻게 만들고 처리하는지가 술술 읽힙니다. 앱(app)은 UI 분량이 커서 맨 뒤로.
"한 곳에서 실행, 여러 곳에서 관찰"하는 구조를 zod로 타입을 고정한 메시지 규약 위에 올리는 법. 연결 재접속, 상태 동기화, 명령/이벤트 분리 같은 실전 패턴이 들어 있습니다.
CLI 도구를 코드로 띄우고, 출력을 파싱하고, 입력을 보내는 PTY 제어. 에이전트뿐 아니라 모든 인터랙티브 CLI 자동화의 기초입니다.
python REPL을 띄워 "2+2"를 보내고 결과만 뽑아오는 미니 래퍼 만들기. ANSI 코드는 strip-ansi로 제거.iOS·안드·웹·Electron까지 한 코드베이스로 커버하는 전략. expo-router·unistyles·reanimated로 네이티브급 UX를 유지하면서 코드 중복을 없애는 방법을 볼 수 있습니다.
expo start --web로 웹, expo run:ios로 모바일에 동시에 띄워보기. 같은 화면이 양쪽에 뜨는 걸 확인.중계 서버가 내용을 못 보게 하는 E2EE의 실제 구현. 키 교환·박스 암호화 같은 개념을 작은 라이브러리로 체험할 수 있습니다.
box로 두 peer가 키쌍을 교환하고, 중간 "릴레이"가 평문을 못 읽는 걸 콘솔로 증명해보기.모든 오디오를 서버로 보내지 않고, 로컬 VAD(silero_vad.onnx)로 "말이 시작/끝났는지"만 먼저 감지해 비용·지연·프라이버시를 줄이는 하이브리드 설계.
oxlint·oxfmt(Rust)와 tsgo(Go 기반 TS 컴파일러 프리뷰)로 린트·포맷·타입체크를 수십 배 빠르게. 대형 모노레포에서 CI 시간을 어떻게 줄이는지 엿볼 수 있습니다.
| 항목 | 요구사항 |
|---|---|
| OS | macOS · Windows · Linux (데몬은 Node가 도는 곳이면 됨) |
| 런타임 | Node.js (Expo 54·RN 0.81 기준 LTS 권장). npm workspaces 사용 |
| 에이전트 CLI | 최소 1개 설치·로그인 필요 — Claude Code / Codex / Copilot CLI / OpenCode / Pi 중 |
| 음성(선택) | OpenAI API 키(Realtime STT/TTS). VAD는 로컬 모델이라 키 불필요 |
| 네트워크 | 데몬 기본 127.0.0.1:6767. 같은 LAN이면 직접, 외부망이면 relay 경유 |
| 상태 디렉터리 | ~/.paseo (환경변수 PASEO_HOME으로 변경 가능) |
| 설치 난이도 | 데스크톱 앱은 "열면 데몬 자동 실행"으로 가장 쉬움. CLI는 npm i -g @getpaseo/cli |
가장 쉬운 시작: 데스크톱 앱을 받아 열면 데몬이 알아서 뜹니다. 폰을 붙이려면 설정의 QR을 스캔하면 끝. 서버·원격 머신이라면 CLI 경로(paseo 실행 → 터미널에 뜬 QR로 연결)가 적합합니다.
CLI로 데몬을 띄우고 다른 기기에서 접속하는 가장 기본 흐름을 체험합니다.
npm install -g @getpaseo/cli
paseo # 터미널에 QR 코드가 뜸 → 폰/웹에서 스캔
paseo ls # 현재 돌고 있는 에이전트 목록
제공자/모델을 골라 작업을 던지고, 출력을 스트리밍으로 보고, 후속 지시를 붙입니다.
paseo run --provider claude/opus-4.6 "implement user authentication"
paseo attach abc123 # 실시간 출력 스트리밍
paseo send abc123 "also add tests" # 후속 작업 추가
서로 다른 제공자를 별도 git worktree에서 동시에 돌려, 결과를 비교해봅니다(병렬·격리 체감).
paseo run --provider claude/opus-4.6 --worktree try-claude "리팩터링 A안"
paseo run --provider codex/gpt-5.4 --worktree try-codex "리팩터링 B안"
paseo ls # 둘이 충돌 없이 각자 디렉터리에서 도는지 확인
Paseo 스킬을 설치하고, 한 대화 안에서 핸드오프/위원회 패턴을 실험합니다.
npx skills add getpaseo/paseo
# 이후 에이전트 대화에서:
# /paseo-handoff → Claude로 계획 짜고 Codex로 구현 인계
# /paseo-loop → 합격 기준 충족까지 반복 (Ralph 루프)
# /paseo-committee→ 대조되는 두 에이전트로 근본원인 분석
# /paseo-advisor → 작업 위임 없이 두 번째 의견용 어드바이저 에이전트 호출
집 데스크톱의 데몬에 외부망 폰으로 안전하게 붙는 풀 셋업. nginx + Let's Encrypt로 TLS를 입힙니다.
# 데몬을 공개 relay 엔드포인트와 함께 시작
PASEO_RELAY_ENDPOINT=127.0.0.1:8080 \
PASEO_RELAY_PUBLIC_ENDPOINT=relay.example.com:443 \
PASEO_RELAY_USE_TLS=true \
paseo daemon start
# nginx는 /ws 경로를 127.0.0.1:8080으로 WebSocket 프록시
외부 노출 전, 방화벽·인증(데몬의 페어링/비밀번호)·TLS를 모두 점검하세요. relay를 평문으로 공개망에 두지 말 것.
| 주차 | 주제 | 핵심 학습 + 실습 |
|---|---|---|
| 1주차 | 실시간 통신 기반 | WebSocket(ws) + zod 메시지 규약. "데몬-클라이언트" 미니 구현(과제 본문 실습 ①). 재접속·상태 동기화 개념 |
| 2주차 | 프로세스/터미널 제어 | node-pty + xterm.js. 인터랙티브 CLI 자동화, ANSI 파싱, child process 생명주기·정리(tree-kill) |
| 3주차 | 에이전트 통합 표준 | ACP·MCP 개념과 SDK. "제공자 추상화"란 무엇인가, 도구를 LLM에 노출하는 법. 간단한 MCP 서버 작성 |
| 4주차 | 멀티플랫폼 + 보안 | Expo로 웹·모바일 동시 빌드 / tweetnacl E2EE / Electron 패키징. 작은 "리모트 컨트롤 앱" 완성 |
각 주차는 Paseo의 한 패키지와 1:1로 대응합니다(1주=protocol·client, 2주=server, 3주=server의 agent·mcp, 4주=app·relay·desktop). 끝나면 Paseo 코드의 어느 부분을 봐도 "여기가 그 개념이구나"가 보입니다.
127.0.0.1:6767./paseo-loop 스킬이 이를 구현(선택적 검증자 포함).