
Strace-ui, Bonsai_term, 그리고 TUI의 르네상스
요약
기존 strace의 복잡한 출력을 개선하기 위해 대화형 TUI를 제공하는 strace-ui를 소개합니다. 이 도구는 실시간 필터링, FD 추적, DNS 해상도 지원 등을 통해 시스템 호출 디버깅을 훨씬 직관적으로 만들어줍니다.
핵심 포인트
- strace-ui는 strace를 대화형 TUI로 변환하여 디버깅 편의성 제공
- 대화형 필터링 및 특정 파일 디스크립터(FD) 추적 기능 지원
- PID를 짧은 라벨로 표시하고 DNS 호스트네임을 해석하여 가독성 향상
- OCaml 기반의 Bonsai 프레임워크를 활용한 반응형 UI 구축
우리는 항상 strace가 유용하지만 다루기에는 다소 어렵다는 점을 발견해 왔습니다. 그 출력 결과는 종종 해독하기 어렵고, 하위 프로세스(subprocess)나 스레드(thread)를 추적하기 힘들며, 시스템 호출(syscall)을 필터링하려면 각 호출마다 플래그를 지정하여 트레이스를 다시 실행해야 합니다. 디버깅에서 진정으로 원하는 것은 탐색하고 정제할 수 있는 도구이지만, strace는 이를 어렵게 만들 수 있습니다.
이때 등장한 것이 strace를 대화형 터미널 UI(TUI)로 바꿔주는 strace-ui입니다:

strace-ui는 PID에 짧은 ID를 할당하여 훑어보기 쉽게 만들고, 구조체(struct)를 포맷팅하며, 버퍼를 문자열 대신 헥스덤프(hexdump)로 렌더링합니다. 스크린샷에서는 볼 수 없는 몇 가지 유용한 기능들도 있습니다:
- 대화형 필터링(Interactive filtering). 비동기 OCaml 프로세스를 트레이싱 중인가요?
-e '!futex,timerfd_settime,epoll_wait'를 전달하는 것을 잊으셨나요? 걱정하지 마세요. h를 눌러 관심 없는 시스템 호출을 숨길 수 있습니다. - 특정 파일 디스크립터(file-descriptor) 추적. > 또는 **<**를 눌러 동일한 파일 디스크립터를 참조한 다음/이전 시스템 호출로 이동하거나, F를 눌러 특정 FD를 사용하는 시스템 호출만 포함하도록 필터를 변경할 수 있습니다. (단순한 숫자 FD 필터링보다 약간 더 스마트합니다. strace-ui는 FD 재사용을 추적하고 fork를 통한 추적을 시도하지만, 이미 FD가 열려 있는 프로세스에 연결할 경우 그 성능이 아주 뛰어나지는 않습니다.)
rt_sigprocmask가 도대체 무엇인가요? m을 눌러 매뉴얼 페이지(man page)를 열어 확인해 보세요.- 하위 프로세스나 스레드에 원시 PID(raw pid) 대신 짧은 숫자 라벨이 할당되어, 복잡한
strace -f호출을 더 쉽게 따라갈 수 있습니다. (PID로 필터링하거나 PID를 제외할 수도 있습니다.) - DNS 해상도(DNS resolution): strace의
--decode-fds=all은 파일 디스크립터를14<TCP:[55.55.555.555:12345->11.11.11.11:56789]>와 같이 출력하며, 이는 매우 훌륭합니다. strace-ui는 여기서 한 걸음 더 나아가14<TCP:[실제-호스트네임:12345->다른-호스트네임:56789]>와 같이 출력하여, 프로세스가 정확히 무엇을 하고 있는지 한눈에 더 쉽게 파악할 수 있게 해줍니다.
이곳의 개발자인 Ian Henry는 자신의 필요를 충족시키기 위해 strace-ui를 만들었습니다. 2017년에 그는 이러한 도구를 찾아 헤맸지만 결국 찾지 못했습니다. 그는 대화형 터미널 UI (interactive terminal UIs, lambda_term을 사용한 OCaml 포함)를 구축해 본 경험이 있었기에, 그것이 얼마나 어렵고 불쾌할 수 있는지 알고 있었습니다. 이 아이디어는 수년간 머릿속을 맴돌았지만 딱히 가치가 있다고 느껴지지 않았습니다. 그러다 최근 몇 가지 요인들이 결합되면서 터미널 UI 개발이 실제로 꽤 즐거운 일이 되었습니다.
Bonsai, 반응형 UI (reactive UIs)를 위한 강력한 프레임워크
우리는 수년 동안 Elm에서 느슨하게 영감을 받은 Bonsai라는 라이브러리를 사용하여, 함수형 스타일 (functional style)로 OCaml을 이용해 웹 애플리케이션을 구축해 왔습니다. 약간의 상호작용이 포함된 간단한 Bonsai 컴포넌트 (component)는 다음과 같습니다:
module Dice = struct
let faces = ...
let component (graph @ local) =
...
컴포넌트들은 순수 함수형 상태 머신 (purely functional state machines)으로 구현되며, 쉽게 조합 (composable)할 수 있습니다. 프레임워크 내부의 증분 처리 (Incrementalization)는 값이 필요할 때까지 재계산되지 않음을 의미합니다. 이는 뷰 (view)뿐만 아니라 모든 값에 적용됩니다.
Bonsai의 멋진 점은 상태 (state)와 증분성 (incrementality) 프리미티브 (primitives)를 원하는 대로 조합할 수 있다는 것입니다. 사용자 상호작용 중에 페이지 전체가 다시 렌더링되는 것을 방지하는 것과 동일한 프리미티브를 실시간으로 업데이트되는 데이터셋에 대한 비용이 많이 드는 비즈니스 로직 계산을 증분 처리하는 데에도 사용할 수 있습니다. (만약 React에 익숙하시다면, 모든 것이 훅 (hooks)과 매우 유사한 것을 사용하고, 상태가 컴포넌트 계층 구조 외부에서 관리된다고 상상해 보세요.)
그리고 Bonsai는 OCaml로 작성되었기 때문에 백엔드와 프론트엔드 모두에서 동일한 언어와 타입을 사용하는 것이 가능해집니다. 특히 OCaml의 타입 시스템 (type system)을 광범위하게 사용할 때, 이것이 대규모 웹 앱의 코드베이스를 관리 가능한 수준으로 유지하는 데 미치는 영향은 아무리 강조해도 지나치지 않습니다.
Bonsai는 사실 웹 프레임워크가 아닙니다
지금까지 우리는 사실 Bonsai_web에 대해 이야기해 왔습니다. Bonsai 자체는 프론트엔드(frontend)에 대해 무관심(agnostic)합니다. 왜냐하면 생각해 보면, 모든 UI는 근본적으로 상태를 가진 점진적 계산(stateful incremental computations)으로 표현될 수 있으며, 여기서 서로 다른 컴포넌트들은 기반 데이터가 변경됨에 따라 스스로를 어떻게 렌더링할지 알고 있기 때문입니다.
만약 Bonsai가 상태의 생명주기(lifecycle)와 스코핑(scoping)을 관리하기 위한 라이브러리이고, 그 위에 특정 UI 표면의 세부 사항을 표현하기 위한 레이어가 있는 것이라면, 동일한 기반 코어가 어떻게 적응될 수 있는지 이해할 수 있을 것입니다. 그리고 그것이 바로 Bonsai_term이 탄생한 배경입니다.
Ty Overby가 2019년에 Bonsai를 만들었을 때, 이것이 결국 터미널 앱(terminal apps)에 사용될 것이라는 생각은 일종의 농담처럼 통했습니다. 어떤 면에서 Bonsai의 핵심 목적은 Jane Street에서 웹 개발 측면에서 다소 역량이 부족하다고 느꼈기 때문이었습니다. 우리의 가장 중요한 앱 중 일부는 이름값(curses)을 하는, 오래되고 다소 까다로운 curses 라이브러리를 기반으로 구축되었습니다.
터미널 앱은 빠르고 키보드 중심적이며, 이는 우리가 선호하는 방식입니다. 하지만 웹 또한 많은 장점을 가지고 있습니다. 하이퍼링크를 클릭하는 인체공학적 편의성은 따라잡기 어렵습니다. 또한 웹은 명령줄(command line)에서는 실용적이지 않은 차트와 그래픽, 그리고 통합 도움말(툴팁 등을 통해)을 포함하여 UI를 구축하기 위한 방대한 팔레트를 제공합니다. Bonsai_web 출시 이후 몇 년 동안, 터미널에서 직접 포팅된 많은 앱을 포함하여 웹 앱이 엄청나게 꽃피웠습니다.
하지만 2026년인 지금, 이번에는 반대 방향으로 또 다른 르네상스가 일어나고 있는 것처럼 느껴집니다.
터미널 UI의 귀환 — Claude Code 효과인가?
Bonsai_term은 2024년 여름, 우리의 개발자 중 한 명인 Jose Rodriguez가 kitty 그래픽 프로토콜을 사용하는 만화 리더를 만들기 위해 구축한 개인적인 취미 프로젝트로 시작되었습니다. 이는 충분한 가능성을 보여주었고, 이후 그는 Jane Street에서 더 폭넓게 사용할 수 있는 ncdu 스타일의 도구들을 만들었습니다. 2025년 4월, Bonsai_term은 본격적으로 제품화(productionizing)를 시작할 만큼 충분한 견인력(traction)을 확보했습니다.
마침 AI 에이전트(AI agents)들이 등장하기 시작했고, 2025년 2월 Claude Code의 등장이 모든 것에 가속도를 붙였습니다. 터미널 앱 자체가 가진 속도, 단순성, 그리고 휴대성(portability) 덕분에 잘 만들어진 터미널 앱이 모든 기능을 갖춘 IDE(Integrated Development Environment)를 이기고 있다는 사실이 상당히 빠르게 명확해졌습니다. 터미널 에뮬레이터(Terminal emulators)는 어디에나 존재하며 에디터에 깊숙이 통합되어 있습니다. 즉, TUI(Text User Interface)는 개발자들이 이미 머물고 있는 곳에서 그들을 만난 것입니다. 태초에 커맨드 라인(command line)이 있었고, 그것은 여전히 어디에나 존재하며 항상 손닿는 곳에 남아 있습니다.
우리는 Bonsai_term에 더욱 집중했고, 곧 피드백 루프(feedback loop)가 형성되었습니다. 우리는 AIDE라고 불리는 우리만의 Claude Code 스타일의 도구를 개발했습니다. (우리는 다양한 모델 벤더 사이에서 선택의 자유를 유지하고, 우리의 독특한 개발 환경에 맞추며, 실행 샌드박스(execution sandbox)를 더 잘 제어하기 위해 이를 구축했습니다.) 이 도구는 Bonsai_term의 데모인 동시에 이를 만드는 파트너가 되었습니다. AIDE를 완전한 기능을 갖춘 에이전트 하네스(agent-harness)로 구축하는 과정에서, 우리는 다른 앱들도 활용할 수 있는 풍부한 UI 컴포넌트 라이브러리를 함께 만들어냈습니다.
이 유난히 뛰어난 TUI를 접하게 된 개발자들은, 이 TUI가 구축된 새로운 프레임워크 덕분에 자신들도 그만큼 완성도 높은 터미널 앱을 만들 수 있다는 사실을 발견하고 기뻐했습니다. Bonsai_term은 여기서 웹 개발을 해본 사람이라면 누구에게나 친숙하게 느껴질 것이며, 특히 AI의 도움을 받기에 매우 용이하다는 거대한 장점을 가지고 있었습니다. 사실 Bonsai_term 코드가 상대적으로 생소하고, 예를 들어 OxCaml 전용 기능에 의존한다는 점을 고려할 때, 모델들이 Bonsai_term 코드를 작성하는 능력이 어떻게 그렇게 뛰어난지는 우리에게도 다소 미스터리였습니다. (우리는 이것이 아래에서 논의할 테스트 이야기와 관련이 있을지도 모른다고 생각합니다.)
그러다 최근 Bonsai_term과 AI 에이전트의 출현과 함께, Ian은 10분도 채 되지 않아 작동하는 프로토타입을 만들 수 있다는 것을 발견했습니다. 그 프로토타입은 이를 실제로 구현하기 위해 계속 시간을 투자할 가치가 있을 만큼 충분히 유용했습니다.

스크린샷 테스트(screenshot tests)로 루프 닫기
AI 개발을 훌륭하게 보완해 주는 Bonsai_term의 가장 강력한 기능 중 하나는 바로 테스트 프레임워크입니다. 터미널 앱에서 앱을 사용하는 과정을 말 그대로 따라가며, 어느 순간이든 스크린샷처럼 보이는 상태를 출력하는 통합 테스트 (integration tests)를 쉽게 작성할 수 있습니다. 모든 것이 텍스트이기 때문에, 이는 우리의 expect 테스트 프레임워크를 직관적으로 적용한 것이며, 일반적인 expect 테스트와 마찬가지로 회귀 (regressions) 또는 동작의 변화가 diff로 나타납니다.
중요한 점은, 이러한 테스트들이 코딩 에이전트 (coding agent)가 실행하기에 매우 사소한 작업이며, 출력 결과 또한 에이전트가 읽기 쉽다는 것입니다. 이러한 폐쇄 루프 (closed loop) 덕분에 AI는 자신의 작업 내용을 쉽게 확인할 수 있으며, 결과적으로 첫 시도에 더 정확한 기능을 구현하게 됩니다. 실제로 이 경험이 너무나 좋았기에, strace-ui 개발 시간의 상당 부분은 에이전트가 테스트를 통해 볼 수 없는 종류의 출력물, 예를 들어 스크롤, 필터링 및 렌더링의 성능 특성 등에 집중되었습니다. (또한 파일 디스크립터 (file-descriptor) 추적에서도 정말 큰 어려움을 겪었습니다.)
수많은 터미널 앱의 개화
Bonsai_term에 대한 언급을 찾기 위해 우리의 내부 검색 엔진을 살펴보면, 매일 소수의 새로운 앱들이 구축되고 있음을 알 수 있습니다. 몇 가지 예시는 다음과 같습니다:
- 트레이딩 시스템을 위한 타임 트래블 디버거 (time travelling debugger) TUI.
- Linux 관리 작업을 자동화하기 위한 TUI.
- 내부 CI 시스템을 위한 모니터링 TUI.
- 에이전트 기반 코딩 세션 (agentic coding sessions)을 오케스트레이션하고 모니터링하기 위한 TUI.
- 에이전트 기반 평가 (agentic evals)를 실행하고 관리하기 위한 TUI.
- 배포 및 롤 (deployments and rolls) 관리를 위한 TUI.
- 로그 탐색을 위한 TUI.
- 터미널 차트 라이브러리 (Terminal charting libraries).
공개 게시물에 이 모든 것의 스크린샷을 보여드릴 수는 없지만, 공유할 수 있는 두 가지가 있습니다: 멀티 프로세스 애플리케이션 관리를 위한 proctopus, 그리고 실행 파일의 비대함 (bloat)을 분해하기 위한 dissect입니다.


이러한 증가세는 아마도 strace-ui를 이끌었던 것과 동일한 동력에서 기인할 것입니다:
- 터미널 앱은 가볍고 빠르며, 개발자가 있는 곳이라면 어디에서나 사용할 수 있습니다.
- Bonsai_term을 사용하면 선언적(declarative)이고 타입 안전(type-safe)한 방식으로 터미널 앱을 구축할 수 있으며, 백엔드와 프론트엔드 간에 코드를 공유할 수 있습니다.
- 시작하기 위해 이전에 Bonsai를 사용해 본 경험이 없어도 됩니다.
- AI는 "Bonsai_term을 이해하며("speak Bonsai_term")", 스크린샷 스타일의 expect 테스트와의 폐쇄 루프(closed loop) 덕분에 사용자와 에이전트 모두 앱이 무엇을 하고 있는지 확인할 수 있습니다. 피드백은 빠르고 정확합니다.
- 건강한 컴포넌트 생태계가 구축되어 있으며, Bonsai 컴포넌트는 결합성(composable)이 뛰어나기 때문에 기존 컴포넌트들을 서로 엮어 상당히 정교한 앱을 구축할 수 있습니다.
Bonsai_web이 작동하는 방식의 특이점에서 기인하는 한 가지 추가적인 이점이 있습니다. Bonsai_web 애플리케이션은 OCaml로 작성되지만 js_of_ocaml이라는 트랜스파일러(transpiler)에 의해 JavaScript로 포팅됩니다. 브라우저 API의 변덕스러움 때문에 네이티브 플랫폼에서는 잘 작동하는 일부 라이브러리들이 js_of_ocaml 프로그램에 연결되지 못할 수 있습니다. 실제로 Bonsai_web 앱을 작성할 때 가장 큰 장애물 중 하나는 의존하는 모든 라이브러리에서 JavaScript 친화적인 부분을 신중하게 골라내는 작업입니다. 이러한 골라내는 작업의 상당 부분이 지난 몇 년간 우리의 웹 앱 작업을 지원하기 위해 이미 이루어졌지만, 아직 완전히 완료된 것은 아닙니다.
Bonsai_term은 이러한 문제가 없으며, 이는 여러분의 TUI가 일반적인 OCaml 프로그램에 더 가깝고, 다른 애플리케이션과 동일한 모든 라이브러리, 도구 및 서비스를 사용할 수 있음을 의미합니다.
인간공학(ergonomics)을 제대로 맞추는 것이 실제로 개발자의 관심에 엄청난 영향을 미친다는 것을 확인하는 것은 매우 뿌듯한 일이었습니다. 이제 Jane Street의 많은 개발자가 자신을 위한 작은 유틸리티를 만들거나, 이전에는 투자할 가치가 없었을 수도 있는 정교하고 완전한 애플리케이션을 구축할 때 Bonsai_term을 찾습니다. 그리고 터미널 환경에 있다는 덕분에 이 앱들은 키보드 중심적이고, 번개처럼 빠르며, 유용한 방식으로 제약되어 있습니다. 즉, 화려함보다는 유용성에 최적화되어 있습니다. 웹은 사라지지 않겠지만, 터미널 앱이 다시 번창하는 것을 보는 것은 마치 집에 돌아온 것과 같은 기분입니다.
부록: strace-ui, Bonsai_term, 그리고 Proctopus를 시도하는 방법
Bonsai_term을 시도해보고 싶으신가요? 여기에서 설치 지침을 읽어보실 수 있습니다. 여러분의 LLM (Large Language Model)이 우리의 예시 리포지토리 (examples repo)를 참조하도록 설정한 뒤, 여러분만의 TUI (Text User Interface)를 구축해 달라고 요청할 수 있습니다. 더 나은 결과를 얻기 위해, 여러분의 LLM에게 이와 같은 expect 테스트를 작성하도록 요청하는 것을 강력히 권장합니다!
proctopus와 strace-ui는 각각 여기와 여기의 README 파일에 있는 설치 지침을 따라 설치할 수 있습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 HN AI Posts의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기