pi 에이전트에 ‘진짜 IDE’를 두르다: JetBrains/thinkrail 심층 분석 — 세 고리 아키텍처, git worktree 워크스페이스, SPEC.md 스펙 그래프와 v0.2.0 박스 스모크 테스트

한 줄 요약: JetBrains/thinkrail은 오픈소스 코딩 에이전트 pi(npm @earendil-works/pi-coding-agent)를 프로세스 안에서 그대로 돌리고, 그 바깥에 에디터·diff 리뷰·터미널·git worktree 워크스페이스·스펙 그래프를 붙인 “에이전트 중심 IDE”입니다. 라이선스는 Apache-2.0입니다. 핵심 설계 원칙은 하나입니다. 모델, 스킬, 컴팩션, 비용, 세션 상태는 전부 pi가 갖고, ThinkRail은 워크스페이스와 에디터, 그리고 UI와 호스트를 잇는 프로토콜(wire)만 갖습니다. 이 글에서는 저장소의 architecture.md와 모듈별 SPEC.md를 바탕으로 세 고리 구조, worktree 기반 격리, pi-spec-graph의 스펙 도구 7개, 서브에이전트 위임 방식을 살펴봅니다. 이어서 v0.2.0 리눅스 CLI 바이너리를 박스에서 실제로 띄워 WebSocket 프로토콜로 워크스페이스를 만들고 스펙 그래프를 읽어 본 결과를 정리했습니다.

ThinkRail의 세 고리: 얇은 런처(apps/cli·apps/desktop)가 엔진 호스트(packages/server, 채팅마다 in-process pi 세션)를 띄우고, 타입 버전 프로토콜(packages/contracts)을 거쳐 React 19 UI(apps/web)와 연결된다. 모델·스킬·세션 상태는 pi가 소유한다
ThinkRail의 세 고리: 얇은 런처(apps/cli·apps/desktop)가 엔진 호스트(packages/server, 채팅마다 in-process pi 세션)를 띄우고, 타입 버전 프로토콜(packages/contracts)을 거쳐 React 19 UI(apps/web)와 연결된다. 모델·스킬·세션 상태는 pi가 소유한다

1. 트렌딩 배경과 기본 정보

2026-10-27(화) 오후 GitHub Trending 데일리 기준으로 전체 3위, TypeScript 1위(오늘 +1,173)입니다. 같은 시각 전체 1위는 디자인 스킬 Nutlope/hallmark, 2위는 TauricResearch/TradingAgents였습니다. 스타 수는 3,303개로 상위권에서 가장 작은 편입니다. 반면 하루 증가 폭은 1,000개를 넘었습니다. 7월에 만들어진 저장소가 10월 19일 첫 0.2 정식판을 내고 나이틀리를 거의 매일 뽑으면서 주목받는 흐름입니다. JetBrains가 “incubator” 배지를 달아 둔 실험 프로젝트라는 점도 눈여겨볼 만합니다. IntelliJ 계열을 확장한 제품이 아니라, 처음부터 에이전트를 가운데 두고 새로 만든 별도 앱입니다.

항목 값 (2026-10-27 KST 확인) 메모
저장소 JetBrains/thinkrail 홈페이지 thinkrail.ai, JetBrains incubator 프로젝트
라이선스 Apache-2.0 루트 LICENSE. 번들 pi 확장도 각자 LICENSE 포함
스타 / 포크 3,303 / 179 GitHub API, 오후 4시 55분 무렵
트렌딩 데일리 전체 3위 · TypeScript 1위 (+1,173) 스킬·하네스 저장소가 상위권을 차지한 날
생성일 2026-07-08 16:40 KST 약 3.5개월 차
최신 정식 릴리스 v0.2.0 (2026-10-19 05:52 KST) 이전 정식판은 0.1.2~0.1.6
최신 나이틀리 v0.3.0-nightly.6 (2026-10-25 15:49 KST) 릴리스마다 자산 17개, SHA256SUMS 포함
규모 TS/TSX 파일 약 1,630개 · 단위 테스트 파일 441개 · E2E 스펙 133개 · SPEC.md 101개 박스에서 클론 후 직접 셈 (main 8e7ced3)
기여자 / 열린 이슈+PR 26명 / 224건 짧은 기간에 비해 활동량이 많음
런타임 Bun 1.4.4 (고정) · Node.js ≥ 22.19 (pi 엔진 요구) 배포용 CLI는 Bun 단일 바이너리(약 140MB)

2. 어떤 문제를 푸나: “pi는 좋은데 터미널이 불편하다”

goal-and-requirements.md가 밝히는 출발점은 분명합니다. pi는 일부러 작게 만든 확장형 하네스입니다. 그 대가로 처음 쓰는 사람은 익히는 데 오래 걸리고, 익숙한 사람도 에이전트 주변 작업은 터미널에서 하기 번거롭습니다. 문서는 문제를 세 가지로 정리합니다.

  • 병렬 에이전트 충돌: 작업 트리 하나에서 에이전트끼리, 또는 에이전트와 사용자가 서로의 수정을 밟습니다.
  • 리뷰의 어려움: CLI에서는 diff를 읽고, 특정 줄에 코멘트를 달고, 그 피드백을 다시 에이전트에게 넘기기가 불편합니다.
  • 의도의 증발: 채팅에서 내린 결정은 세션과 함께 사라집니다. 다음 세션은 같은 결정을 다시 도출하거나, 반대로 뒤집습니다.

해법도 각각 하나씩입니다. 충돌은 worktree 격리로, 리뷰는 IDE 워크벤치로, 의도는 스펙 그래프로 풉니다. 여기에 원칙이 하나 붙습니다. “pi가 유일한 엔진이다. 두 번째 런타임은 없다(claude-agent-sdk 같은 것 없음).” 또 “에이전트에 영향을 줄 때는 pi에 먹이는 방식만 쓰고, 프롬프트를 직접 조립하지 않는다(Influence by feeding, never by assembling).” 이 두 원칙이 이후 설계 결정을 거의 다 설명합니다.

3. 아키텍처: 세 개의 고리와 얇은 런처

구조는 엔진 호스트 · wire · UI 클라이언트 세 고리로 나뉩니다. 엔진 호스트(packages/server)는 Bun.serve 기반 HTTP+WebSocket 서버입니다. 채팅 하나마다 pi 세션 하나를 createAgentSession으로 같은 프로세스 안에서 만듭니다. git, PTY 터미널(bun-pty), 파일 서빙, 영속 상태(~/.thinkrail)도 호스트가 맡습니다. wire(packages/contracts)는 타입과 아주 작은 순수 런타임(상수, 버전, 가드)만 있는 프로토콜 패키지입니다. UI(apps/web)는 React 19 + Zustand + Tailwind v4이고, contracts에만 의존하며 정적 자산으로 따로 배포할 수 있습니다.

런처는 두 개입니다. apps/cli는 호스트를 띄우고 브라우저를 엽니다. apps/desktop은 Electrobun으로 같은 호스트를 시스템 웹뷰 창에 담습니다. 아키텍처 문서는 “런처는 얇고, 호스트는 라이브러리다”라고 못 박습니다. 기능 하나를 추가할 때는 계약(contracts), 서버의 해당 기능 모듈, 공용 웹 클라이언트, 테스트만 바꿉니다. 런처별로 따로 구현하지 않습니다. 원격 접속은 엔드포인트 파라미터로 해결합니다. 기본값은 same-origin이고, 휴대폰 같은 원격 클라이언트는 Tailscale MagicDNS 이름으로 호스트에 접속합니다. 인증도 앱이 직접 하지 않고 Tailscale ACL과 기기 신원에 맡깁니다(Decision 7).

경로 역할 읽을 때 포인트
architecture.md 최상위 설계 스펙 (약 40KB) 번호 붙은 Decision 목록. 왜 그렇게 했는지까지 적혀 있음
packages/server/src/host/server.ts Bun.serve 라우팅 /ws, /health, 워크트리 파일, blob, 정적 자산 순서로 분기
packages/contracts/src/wsProtocol.ts wire 메서드 맵·채널·에러 코드 main 기준 PROTOCOL_VERSION = 91. 기능별 최소 프로토콜 버전 상수가 따로 있음
packages/spec-graph pi 확장: spec_* 도구 7개 + 스킬 + 상시 규칙 @thinkrail/* 의존 금지. 순수 pi에서도 동작
packages/pi-delegation, pi-subagents 자식 세션 위임 코어 / Agent 도구 부모당 동시 실행 기본 4개(DEFAULT_MAX_CONCURRENT_PER_PARENT)
packages/pi-thinkrail-workflow 워크플로 스킬 9개 + 라우팅 규칙 brainstorming, shipping-a-pr, writing-specs 등
packages/pi-background-commands 세션 소유 백그라운드 명령 dev 서버·감시 프로세스를 채팅에 묶어 관리
thinkrail-extensions/visualize pi 기능 + ./server·./web 두 쪽으로 된 확장 채팅 안 다이어그램·비교표·UI 목업 렌더링
apps/cli, apps/desktop 런처 두 종 엔진 로직 없음. 서로를 띄우지도 않음
pi-compatibility.md pi 업그레이드 대응 기록부 호스트가 pi 내부에 맞춰 넣은 임시 조치와 그 제거 조건

4. 내부 동작 ①: 워크스페이스 = git worktree

데이터 모델은 프로젝트(git 저장소) → 워크스페이스(git worktree, 자체 브랜치와 cwd) → 채팅·파일·터미널입니다. ThinkRail이 만드는 워크스페이스는 ~/.thinkrail/worktrees/<프로젝트>/<이름> 아래 새 worktree로 생깁니다. 그래서 여러 에이전트가 동시에 일해도 사용자의 체크아웃은 건드리지 않습니다. 예외는 일부러 두 개만 뒀습니다. 첫째는 프로젝트 폴더 자체를 쓰는 Default 워크스페이스(kind: "default")입니다. 지울 수도 이름을 바꿀 수도 없고, 사용자가 명시적으로 골라야만 들어갑니다. 둘째는 사용자가 붙인 기존 worktree(kind: "external")입니다. ThinkRail은 이것을 목록에서 뺄 수는 있어도 수정하지는 않습니다.

끝난 워크스페이스는 PR이 머지되거나 닫히면, 또는 일주일 동안 조용하면 프로젝트별 ‘선반(shelf)’으로 자동 정리됩니다. 다시 작업하면 바로 돌아옵니다. PR 열기는 호스트가 사용자의 gh CLI로 결정적으로 처리합니다. 저장된 토큰도 없고 GitHub REST API를 직접 쓰지도 않습니다. PR 본문은 검증된 계획(plan)에서 만들고, gh를 쓸 수 없으면 compare URL로 대신합니다. 박스에서 workspace.create를 한 번 호출하자 git worktree list에 [smoke-test] 브랜치가 실제로 나타났습니다(6장).

프로젝트 → 워크스페이스(git worktree, 자체 브랜치·cwd) → 채팅·파일·터미널. 예외는 Default(프로젝트 폴더)와 External(기존 worktree) 두 가지. 박스에서 workspace.create 한 번으로 실제 worktree가 생겼다
프로젝트 → 워크스페이스(git worktree, 자체 브랜치·cwd) → 채팅·파일·터미널. 예외는 Default(프로젝트 폴더)와 External(기존 worktree) 두 가지. 박스에서 workspace.create 한 번으로 실제 worktree가 생겼다

5. 내부 동작 ②: 스펙 그래프, 위임, 상태 복원

스펙 그래프. pi-spec-graph는 프론트매터에 id와 type이 있는 마크다운 파일을 스펙으로 봅니다. parent, depends-on 같은 링크로 그래프를 만듭니다. 파일 시스템이 원본이고, 도구가 읽는 모델은 메모리에서 파생된 읽기 전용 인덱스입니다. 읽을 때마다 glob을 다시 돌립니다. 파일별 (mtimeMs, size)가 같으면 캐시된 파싱 결과를 쓰고, 스펙 집합이 바뀐 경우에만 그래프를 다시 만듭니다. 같은 mtime 틱 안에 바이트 길이까지 똑같은 수정이 들어오면 놓칠 수 있다는 한계도 문서에 그대로 적혀 있습니다. node_modules, .git은 물론 .claude, .superpowers, .gsd 같은 다른 어시스턴트의 작업 폴더도 무시합니다. 그 안의 계획 파일이 스펙처럼 생긴 프론트매터를 달고 있기 때문입니다.

도구 설계에서 중요한 점은 도구가 본문(prose)을 건드리지 않는다는 것입니다. spec_update는 프론트매터 블록만 다시 쓰고, 원래 필드 순서·주석·줄바꿈 형식을 유지합니다. 본문은 pi 기본 read/write/edit로 고칩니다. 상시 규칙은 before_agent_start에서 시스템 프롬프트 전체를 바꾸지 않습니다. systemPromptOptions.sections에 이름 붙은 섹션 하나만 끼워 넣습니다. 문서에 따르면 프롬프트 전체를 돌려주면 바뀔 때마다 캐시 미스가 나지만, 이름 붙은 섹션은 diff 패치 하나로 끝납니다. “프롬프트를 조립하지 않는다”는 원칙이 프롬프트 캐시 효율로 이어지는 지점입니다.

도구 종류 하는 일 주의점
spec_grep 읽기 내용 검색. 메타데이터(type·tags 등)로 범위를 좁힘 본문을 많이 읽지 않고 관련 스펙을 찾는 첫 단계
spec_get 읽기 노드의 프론트매터, 링크 해석 결과, 경로 (본문 제외) 본문이 필요하면 pi read로 따로 읽음
spec_graph 읽기 하위 트리·조상·이웃을 범위 제한해서 잘라 줌 그래프 전체 덤프가 아니라 bounded slice
spec_create 관리 정규 필드 순서로 새 스펙 생성 인덱스가 볼 수 없는 경로나 스펙이 아닌 파일이 될 파라미터는 거부
spec_update 관리 프론트매터만 제자리 수정 본문 바이트는 그대로 유지
spec_delete 관리 스펙 삭제 링크가 끊기는지는 spec_validate로 확인
spec_validate 관리 스키마·링크 검증 CI 게이트로 쓰기 좋음
pi-spec-graph: 프론트매터에 id·type이 있으면 스펙. parent·depends-on 링크로 그래프를 만들고 spec_* 도구 7개로 읽고 관리한다. 본문은 도구가 건드리지 않는다
pi-spec-graph: 프론트매터에 id·type이 있으면 스펙. parent·depends-on 링크로 그래프를 만들고 spec_* 도구 7개로 읽고 관리한다. 본문은 도구가 건드리지 않는다

서브에이전트 위임. pi-subagents는 도구 이름을 일부러 Claude Code와 맞췄습니다. 실행은 Agent, 결과 수거는 get_subagent_result입니다. 모델들이 이미 그 관례로 학습돼 있기 때문이라고 설명합니다. 병렬 팬아웃은 한 메시지 안에서 Agent를 여러 번 부르는 방식입니다. pi가 한 배치의 도구 호출을 동시에 실행하고, 코어의 세마포어가 속도를 조절합니다(부모당 기본 4개). 체인용 DSL은 없고 순서는 모델이 정합니다. 자식은 디스크에 저장되는 숨은 pi 세션이라서 실행 중이든, 끝난 뒤든, 호스트를 재시작한 뒤든 트랜스크립트를 읽을 수 있습니다. 다만 백그라운드 완료 알림은 호스트를 재시작하면 사라집니다. 문서도 이것을 감수한 한계로 적어 두었습니다.

Hydrate-then-stream. 클라이언트는 이벤트를 “목격했다”는 사실에 기대지 않습니다. 접속하면 먼저 project.list, workspace.list, session.list, session.getMessages로 현재 상태를 읽고, 그다음 실시간 델타를 구독합니다. 그래서 새로고침, 두 번째 탭, 휴대폰, 호스트 재시작 뒤에도 같은 화면을 다시 만들 수 있습니다. 에이전트 실행 상태도 pi의 agent_end를 끝으로 보지 않습니다. 재시도·컴팩션·대기 중인 후속 작업이 이어질 수 있어서 agent_settled만 유휴 전환으로 칩니다. 레이아웃 같은 화면 상태는 창마다 로컬에 두고 wire로 보내지 않습니다. 한 창이 다른 창의 배치를 바꾸는 일이 없도록 하기 위해서입니다.

설계 결정 택한 쪽 버린 쪽 대가
엔진 pi 하나, in-process 여러 에이전트 SDK 병행, 별도 프로세스 pi의 잦은 breaking 릴리스를 그대로 받음 → pi-compatibility.md로 관리
의존성 모든 매니페스트 정확 버전 고정, check:deps로 강제 ^·~ 범위 업그레이드가 전부 수동 diff (대신 재현성 확보)
터미널 xterm.js DOM 렌더러 + 실제 PTY WebGL 애드온, Ghostty WASM 계열, tmux 리거처 등 일부 렌더링 포기. 호스트 재시작 시 셸은 새로 뜸
셸 수명 탭 참조 + 호스트 프로세스 유휴 타이머 정리 탭을 안 닫으면 PTY가 계속 남음
채팅 제목 메인 에이전트가 set_title로 한 번만 헬퍼 모델·첫 단어 휴리스틱 에이전트가 안 부르면 이름 없는 채로 남음(첫 프롬프트로 표시)
인증 Tailscale ACL·기기 신원 앱 자체 로그인 로컬 바인딩·네트워크 경계 설정이 곧 보안 경계
PR 사용자 gh CLI 토큰 저장 + REST API gh 미설치 시 compare URL로 대체

6. 설치·실행·검증 명령과 박스 스모크 테스트

설치는 README에 나온 그대로입니다. CLI 설치 스크립트는 바이너리를 받아 SHA-256을 검증하고 PATH에 넣습니다.

# macOS / Linux CLI (안정 채널)
curl -fsSL https://raw.githubusercontent.com/JetBrains/thinkrail/main/install.sh | bash
# 나이틀리 또는 버전 고정
curl -fsSL https://raw.githubusercontent.com/JetBrains/thinkrail/main/install.sh | bash -s -- --channel nightly
curl -fsSL https://raw.githubusercontent.com/JetBrains/thinkrail/main/install.sh | bash -s -- --channel stable --version 0.1.2

thinkrail ~/code/my-repo          # 프로젝트를 열면서 실행
thinkrail --no-open --host localhost --port 24242   # 헤드리스 호스트
thinkrail update / thinkrail uninstall [--remove-data]

# 소스에서 개발
git clone https://github.com/JetBrains/thinkrail.git && cd thinkrail
bun install
bun run dev                 # 호스트 + 웹 클라이언트
bun run build:binary        # 단일 CLI 바이너리
bun run typecheck && bun run test && bun run check:deps

박스에서는 설치 스크립트를 파이프로 실행하지 않았습니다. 대신 v0.2.0 릴리스 자산 thinkrail-linux-x64와 SHA256SUMS를 직접 받아 해시를 비교했습니다(540f7d46…088010c, 일치). HOME을 작업 폴더 안 임시 디렉터리로 바꾸고, --no-open --no-analytics로 띄웠습니다. 모델 공급자 키는 하나도 넣지 않았기 때문에 실제 에이전트 대화는 돌리지 않았습니다. 그 대신 웹 UI가 쓰는 WebSocket 프로토콜을 Bun 스크립트로 직접 호출해 호스트 쪽 기능을 확인했습니다.

점검 명령/호출 실제 결과 해석
버전 thinkrail --version 0.2.0, 종료 코드 0 140MB(139,994,312바이트) 단일 바이너리. 별도 Node 설치 불필요
도움말 thinkrail --help --port(기본 24242), --host(기본 localhost), --no-open, --no-analytics, --verbose, update/uninstall 환경 변수 THINKRAIL_PORT/HOST/STATIC_DIR/NO_ANALYTICS/LOG_LEVEL
기동 --no-open --port 24299 ./demo 로그 “listening on port 24299”, GET / 200(1,454B), /health → ok 시작부터 응답까지 1초 안쪽. [::1] 루프백에만 바인딩됨
환영 메시지 WS /ws 접속 server.welcome: protocolVersion 85, hostPlatform linux main 브랜치 contracts는 91. UI를 따로 배포할 때 버전 차이를 감지하는 용도
프로젝트 project.list demo 1개, piResourceTrust: "untrusted" 새 프로젝트는 기본이 미신뢰. 저장소에 들어 있는 MCP 서버는 승인 전까지 꺼져 있음
워크스페이스 workspace.list → workspace.create 처음엔 Default(kind default, master)만 있다가 smoke-test 추가 git worktree list에 ~/.thinkrail/worktrees/demo/smoke-test [smoke-test] 생성 확인
스펙 그래프 워크트리에 SPEC.md 2개 작성 후 spec.graph 빈 {"nodes":[]} → goal, module-api(parent: goal) 2개 노드 호스트 재시작 없이 파일 변경이 바로 반영됨(재검증 인덱스)
공급자 provider.status 공급자 41종, 설정 0. OAuth 가능 9종(anthropic, github-copilot, openai-codex, openrouter, xai 등) pi 자체 인증을 그대로 노출. ThinkRail 계정은 없음
Origin 검사 Origin: http://evil.example로 /ws 업그레이드 HTTP/1.1 101 Switching Protocols v0.2.0 호스트는 업그레이드 시 Origin을 거르지 않았음. 아래 주의 사항 참고
박스 스모크 테스트(v0.2.0 linux-x64, SHA256 일치, 모델 키 없음): --version 0.2.0, GET / 200, server.welcome protocolVersion 85, provider.status 41종. /ws 업그레이드는 임의 Origin에도 101로 응답했다
박스 스모크 테스트(v0.2.0 linux-x64, SHA256 일치, 모델 키 없음): –version 0.2.0, GET / 200, server.welcome protocolVersion 85, provider.status 41종. /ws 업그레이드는 임의 Origin에도 101로 응답했다

마지막 항목은 짚고 넘어가야 합니다. server.ts의 /ws 분기를 보면 client, protocol 쿼리만 읽고 바로 srv.upgrade()를 부릅니다. 박스에서도 아무 Origin 헤더로 101 응답을 받았습니다. 이 WebSocket으로는 워크스페이스 생성, 터미널, MCP 설정 같은 강한 동작을 할 수 있습니다. 그래서 브라우저에서 다른 사이트가 ws://localhost:24242에 붙는 교차 사이트 WebSocket 시나리오를 따져 볼 필요가 있습니다. 실제 공격이 되는지는 이번에 검증하지 않았습니다(브라우저 정책, 클라이언트 키 처리 등 변수가 있음). 다만 아키텍처 문서가 인증을 Tailscale 같은 네트워크 경계에 맡긴다고 밝힌 만큼, 지금은 --host를 localhost로 유지하고 0.0.0.0 바인딩을 피하며, 신뢰하지 않는 사이트를 연 브라우저와 같은 기기에서 오래 띄워 두지 않는 편이 안전합니다. 운영에 쓰기 전에 이슈 트래커에서 Origin 검증 계획을 확인해 보길 권합니다.

7. 비슷한 도구와 비교

MoricWorld에서 이미 다룬 에이전트 작업 공간 도구들과 나란히 놓으면 ThinkRail의 위치가 분명해집니다. 공통 축은 “여러 에이전트 세션을 격리해서 굴리고 리뷰한다”이고, 갈리는 지점은 엔진을 몇 개 품느냐와 의도를 어디에 저장하느냐입니다.

구분 JetBrains/thinkrail stablyai/orca makecindy/cindy anomalyco/opencode 순수 pi CLI
정체성 pi 전용 에이전트 IDE worktree 기반 멀티 에이전트 오케스트레이터 여러 에이전트 CLI를 잇는 클라이언트 자체 코딩 에이전트 + 서버/클라이언트 최소 하네스
엔진 pi 하나, in-process Claude Code·Codex 등 외부 CLI Claude Code·Codex·pi 등 연결 자체 엔진 pi
격리 git worktree + Default/External 예외 git worktree 제품별 방식 세션 단위 (권한 시스템 중심) 사용자가 직접
에디터·리뷰 Monaco 탭, diff 줄 코멘트 → 채팅 전달, 터미널 worktree별 에이전트 실행·관리 중심 대화 중심 UI TUI/웹/데스크톱 클라이언트 터미널
장기 기억·의도 SPEC.md 스펙 그래프 + spec_* 도구 제한적 제한적 AGENTS.md 등 규칙 파일 스킬·프롬프트 파일
원격 접속 UI/호스트 분리, Tailscale 전제 로컬 데몬 로컬 API 서버 모드 SSH
강점 pi 설정·확장 그대로 + IDE 수준 리뷰 여러 벤더 에이전트를 동시에 이미 쓰는 에이전트를 한 화면에 성숙도·생태계 가볍고 투명함
약점 pi에 종속, 0.x 초기 단계 스펙·기억 계층 약함 엔진별 기능 편차 pi 확장 생태계와 별개 병렬·리뷰가 불편

정리하면 Orca와 cindy는 “엔진은 바깥에 있고 우리는 지휘한다” 쪽입니다. ThinkRail은 “엔진은 하나로 정하고 그 안쪽까지 맞춰 붙인다” 쪽입니다. 그래서 서브에이전트 트랜스크립트, 컴팩션, 프롬프트 섹션 패치처럼 엔진 깊숙한 곳까지 UI로 끌어올 수 있습니다. 대신 pi를 쓰지 않는 팀에게는 고를 이유가 거의 없습니다.

8. 도입 전에 알아 둘 한계와 주의점

항목 내용 대응
성숙도 0.x, 나이틀리가 거의 매일. 정식판과 main의 wire 버전이 이미 6단계 차이(85 vs 91) 팀 도입은 stable 채널 고정, 나이틀리는 개인 실험용
pi 종속 pi의 breaking 릴리스를 직접 받음. pi-compatibility.md에 “제거 조건이 충족되지 않은” 임시 조치가 여러 개 남아 있음 pi 버전을 따로 올리지 말고 ThinkRail 릴리스에 맞춰 올리기
텔레메트리 기본 사용 이벤트(실행, 채팅 생성, 메시지 전송, 공급자 연결)와 오류 보고는 항상 전송. 프롬프트·코드·경로는 제외한다고 명시 추가 데이터는 --no-analytics/THINKRAIL_NO_ANALYTICS=1로 끔. 기본 이벤트까지 막아야 하는 환경이면 네트워크 정책 검토
서명 Linux 산출물은 서명 없음. macOS CLI는 서명했지만 공증(notarize) 전 SHA256SUMS 검증을 배포 파이프라인에 넣기
데스크톱 요구 사항 Linux 데스크톱은 glibc 2.38+, GTK3, WebKitGTK 4.1 (Ubuntu 24.04 이상) 오래된 배포판은 CLI + 브라우저 방식으로
네트워크 경계 앱 자체 로그인 없음. v0.2.0 /ws는 Origin 미검사(박스 관찰) localhost 바인딩 유지, 원격은 Tailscale ACL로만
디스크 워크스페이스마다 worktree가 하나씩 생김. 셸은 탭이 남아 있는 한 유지 선반 정리 기능을 믿되, 큰 모노레포는 디스크 사용량을 주기적으로 점검
언어 UI 내장 언어는 영어·중국어 간체. 한국어는 ~/.thinkrail/locales에 번역한 en.json을 넣어 추가 팀 공용 번역 파일을 저장소에 두고 배포

9. 누가 써야 하나

  • 이미 pi를 주력으로 쓰는 개발자·팀: 가장 잘 맞습니다. ~/.pi/agent 설정, 스킬, MCP를 그대로 읽으므로 옮겨 갈 비용이 거의 없습니다. 병렬 worktree와 diff 줄 코멘트가 바로 이득으로 돌아옵니다.
  • 스펙 주도 개발(SDD)을 하려는 팀: pi-spec-graph는 ThinkRail 없이 순수 pi에서도 동작하는 포터블 패키지입니다. IDE를 도입하지 않더라도 스펙 그래프만 따로 가져다 쓸 수 있습니다. ThinkRail 저장소 자체가 SPEC.md 101개로 운영되는 실제 사례라서 참고하기도 좋습니다.
  • 휴대폰이나 다른 기기에서 에이전트를 지켜보고 싶은 사람: UI와 호스트가 분리돼 있고 hydrate-then-stream으로 상태를 복원하므로, Tailscale 안에서 원격 클라이언트로 붙는 구성이 설계 단계부터 고려돼 있습니다.
  • 맞지 않는 경우: Claude Code·Codex 등 여러 벤더 에이전트를 한 화면에서 섞어 쓰려는 팀(Orca나 cindy 계열이 맞음), 서명된 산출물과 엄격한 텔레메트리 차단이 필수인 보안 환경, 0.x 소프트웨어를 표준 개발 도구로 지정하기 어려운 조직.

개인적으로 가장 흥미로운 부분은 IDE 기능보다 설계 문서가 곧 제품의 일부라는 점입니다. 모든 모듈 옆에 SPEC.md가 있습니다. 경계나 계약을 바꾸는 변경은 같은 커밋에서 스펙도 고치게 돼 있고, 에이전트는 spec_* 도구로 그 스펙을 읽고 관리합니다. “에이전트가 다음 세션에서도 같은 결정을 기억하게 하려면 어디에 적어 둬야 하나”라는 질문에, JetBrains 팀은 “코드 옆의 스펙 그래프”라고 답하고 있습니다. 같은 고민을 하는 팀이라면 IDE를 쓸지와 상관없이 architecture.md와 packages/spec-graph/SPEC.md는 한 번 읽어 볼 만합니다.