Giting.
낮의 Giting

홈 · TypeScript · Swift · iOS 시뮬레이터 · 모바일 QA · 셀프호스트

tapflow 대표 이미지 2b4eac20 (2026-10-16) · 전체 이력 2,741커밋
분석 리포트실측 정보적용점

구조와 기능

tapflow 는 세 부분으로 돈다.

  • 릴레이: 리눅스나 맥 어디서나 도는 서버. 대시보드도 같은 포트에서 내준다.
  • 맥 에이전트: iOS 시뮬레이터와 안드로이드 에뮬레이터를 움직인다. 릴레이 쪽으로 먼저 접속하므로 맥에 들어오는 포트를 열 필요가 없다.
  • 브라우저 대시보드: 팀원이 기기를 골라 실시간으로 누른다. 화면은 H.264 로 보낸다.

실측 규모는 1,186파일 217,710줄이다. 대부분 TypeScript(ts 107,907줄, tsx 26,907줄)이고, 시뮬레이터에 직접 닿는 부분은 Swift 5,611줄과 Objective-C 1,274줄이다. 패키지는 11개로 나뉜다. relay · ios-agent · android-agent · dashboard · cli 외에 MCP 서버(mcp-server)와 정해진 순서대로 누르는 실행기(flow-runner)가 있다. 설치는 npm install -g tapflow 뒤 tapflow setup, tapflow start 다.

하이라이트

매일 손이 가는 저장소

2026-05-07 에 만들어졌고 전체 커밋이 2,741개, 최근 90일만 1,525개다. 저자는 29명이지만 2,588커밋이 만든 사람 한 명(Duchan)의 것이다. 커밋 2,741개 중 1,730개에 Claude 공동 작성 표시가 있다. 태그가 54개, 최신 릴리스는 v0.27.1(2026-10-08)이다.

열린 이슈는 45개이고, 최근 25건 중 24건에 답이 달렸으며 응답 중앙값은 24시간이다.

증명한 것과 못 한 것을 나눠 적는다

코드 주석과 설계 문서가 유난히 꼼꼼하다. 네트워크 끊기 기능의 문서는 처음 만든 방식이 시뮬레이터 트래픽을 하나도 못 봤다는 실측(잡힌 217건이 전부 맥 프로세스)부터 적고, 왜 방식을 바꿨는지 이어 간다. 미리 빌드해 둔 라이브러리를 지키는 검사 스크립트에는 「이 검사는 커밋된 바이너리가 커밋된 소스로 만들어졌다고 말하지 못한다」고 적혀 있다. 거짓 통과를 피하려는 태도가 코드 전체에 보인다.

첫 관리자는 같은 맥에서만

로그인 없이 첫 관리자를 만드는 auth/init 은 localhost 에서 온 요청만 받는다(packages/relay/src/api/auth.ts). 서버를 밖에 열어 둔 채 주인보다 먼저 남이 관리자를 차지하는 일을 막는 장치다. 바깥으로 데이터를 보내는 분석 · 추적 코드는 찾지 못했다.

주의점

0.27.1 아래는 쓰지 않는다

2026-10-07~08 에 저장소 보안 공지가 세 건 나왔다.

  • 치명(GHSA-pq37-jfvf-hhhc): 정적 파일 처리의 경로 조작으로 로그인 없이 JWT 비밀키와 DB 를 읽을 수 있었다. 0.26.1 이하, 0.27.0 에서 고침.
  • 높음(GHSA-m7wx-fpvw-c4pp): 깨진 WebSocket 프레임이나 잘린 업로드로 로그인 없이 릴레이를 죽일 수 있었다. 0.27.1 에서 고침.
  • 중간(GHSA-32j8-75h9-978f): 웹훅 주소가 릴레이 자기 맥으로 풀리면 loopback 검사를 우회했다. 0.27.0 에서 고침.

공지가 나온 날 바로 고친 판이 나왔다. 대응은 빠르지만, 밖에서 접속되는 서버라면 버전을 먼저 본다. 예전 버전을 열어 둔 적이 있다면 올린 뒤 비밀키와 비밀번호를 새로 정한다.

같은 맥의 프록시 뒤에서는 localhost 판정이 흐려진다

첫 관리자 잠금은 요청이 localhost 에서 왔는지로 판단한다. 같은 맥에 Cloudflare Tunnel 이나 nginx 를 붙여 localhost 로 넘기면, 신뢰할 프록시 목록(trustedProxies, 기본값 비어 있음)을 설정하지 않은 경우 바깥 요청도 소켓 주소로는 localhost 다. 코드 주석(lib/clientAddress.ts)도 이 경우를 「주소로는 구분할 수 없어 막지 못하고 알아챌 수만 있다」고 적는다. 이 부분은 코드를 읽고 확인했고 재현하지는 않았다. 관리자 계정을 먼저 만들고 프록시를 붙이면 피할 수 있다.

비공개 API 와 앱 안 주입

iOS 터치는 WebDriverAgent 없이 SimulatorKit 의 비공개 함수(SimDeviceLegacyHIDClient, IndigoHIDMessageForMouseNSEvent)를 dlopen 으로 불러 넣는다(touch-helper.swift, 594줄). 설치가 가벼운 대신 Xcode 가 바뀌면 깨질 수 있는 자리다. 요구 환경이 macOS 26 · 27, Xcode 26 · 27 로 좁은 이유다.

네트워크 끊기는 더 깊이 들어간다. 맥에 콘텐츠 필터 시스템 확장(TapflowNetFilter.app)을 깔아 시뮬레이터 하나의 연결을 끊고, 테스트하는 앱 안에 라이브러리를 주입해 앱이 「오프라인」이라고 믿게 만든다. 시스템 확장은 개발자 ID 로 서명 · 공증돼 있다. 맥에 네트워크 필터를 까는 일이니 회사 맥이라면 관리자와 먼저 이야기할 자리다.

미리 빌드된 도우미 실행 파일

packages/ios-agent/bin/ 에 터치 · 화면 캡처 · 키보드 · 회전 도우미와 주입 라이브러리가 빌드된 채로 들어 있고, npm 패키지도 이 폴더를 그대로 싣는다. 이 파일들은 자체 서명(ad-hoc)이다. 소스와 함께 기록한 해시로 「둘이 같이 바뀌었는지」는 검사하지만, 저장소 스스로 밝히듯 소스로 만들어졌다는 증명은 아니다. 주입 라이브러리는 build-nethook.sh 로 직접 다시 만들 수 있다.

직접 돌려 보지는 않았다

이 리포트는 코드와 문서, 저장소 지표를 읽은 기록이다. 시뮬레이터 스트리밍과 지연은 실행해서 재지 않았다.

표지 그림은 저장소의 README 대표 이미지(docs/public/readme-hero.jpg, MIT)다.

실측 정보

HEAD 커밋
2b4eac20 (2026-10-16) · 전체 이력 2,741커밋
스타 / 포크
940 / 115
규모
217,710줄 · 1,186파일 · ts 107,907줄 · tsx 26,907줄 · swift 5,611줄 · m 1,274줄
구성
패키지 11개: relay · ios-agent · android-agent · dashboard · cli · mcp-server · flow-runner 등
활동
최근 90일 1,525커밋 · 저자 29명 · 태그 54 · 최신 v0.27.1 (2026-10-08)
테스트 / CI
테스트 파일 396 · CI 워크플로 4
이슈
열린 이슈 45 · 최근 25건 중 24건 응답 · 응답 중앙값 24시간
보안 공지
2026-10-07~08 세 건: 치명 1 · 높음 1 · 중간 1, 전부 0.27.1 에서 고쳐짐
요구 환경
에이전트는 macOS 26·27 + Xcode 26·27, 릴레이는 Node 22 이상 아무 OS

적용점

  • 쓴다면버전부터 확인한다. 0.27.1 이상. 그 아래 버전을 밖에서 접속되게 열어 둔 적이 있다면 JWT 비밀키와 DB 가 읽혔을 수 있으니 올린 뒤 비밀키를 바꾸고 계정 비밀번호를 다시 정한다.
  • 열기 전에관리자 계정을 먼저 만든다(tapflow admin init). 첫 관리자는 같은 맥(localhost)에서만 만들 수 있는데, 같은 맥에 Cloudflare Tunnel · nginx 같은 프록시를 붙이고 trustedProxies 를 비워 두면 바깥 요청도 localhost 로 보인다(코드 기준, 재현 안 함). 프록시를 쓰면 TAPFLOW_TRUSTED_PROXIES 를 설정한다.
  • 이럴 때 유용맥으로 앱을 만드는 팀에서, 맥이 없는 사람이 최신 빌드를 눌러 봐야 할 때. 혼자 만드는 사람에게도 의뢰자 · 지인에게 TestFlight 없이 화면을 보여 주는 길이 된다. LLM 에이전트용 MCP 서버도 들어 있다.
  • 알고 쓸 것iOS 터치는 WebDriverAgent 없이 SimulatorKit 의 비공개 함수로 넣고, 네트워크 끊기는 맥에 시스템 확장을 깔고 앱 안에 라이브러리를 주입해 흉내 낸다. 둘 다 Xcode 업데이트에 약한 자리라 요구 환경이 Xcode 26 · 27 로 좁다.
◆ 도입 후보

도입 후보. 단 0.27.1 이상일 때만. 맥 한 대에 시뮬레이터를 띄워 두면 기획자 · 디자이너 · 백엔드 개발자가 Xcode 없이 브라우저로 앱을 눌러 볼 수 있고, 빌드도 바깥 클라우드에 올리지 않는다. 만듦새가 좋다. 패키지가 역할별로 나뉘어 있고, 테스트 파일이 396개이며, 설계 문서와 코드 주석이 「무엇을 재 봤고 무엇은 증명 못 하는지」까지 적는다. 이슈 25건 중 24건에 하루 안팎으로 답한다. 걸리는 건 셋이다. 10월 7~8일에 보안 공지가 세 건 나왔고, 그중 하나는 로그인 없이 JWT 비밀키와 DB 를 읽을 수 있는 치명 등급이었다(0.27.0 에서 고침). 터치 입력과 오프라인 전환이 애플 비공개 API 와 앱 안 주입에 기대 있어 Xcode 가 바뀌면 깨질 수 있다. 그리고 npm 으로 받는 도우미 실행 파일이 저장소에 미리 빌드돼 들어 있다.

의견

판정에 대한 반론, 도입 경험, 정정 제보를 환영합니다. GitHub 계정으로 참여합니다.

이것도 재봤습니다

전체 리포트 →