devch

만든 것 / Chostty

Chostty 앱 아이콘

Chostty

프로젝트마다 작업공간을 두는 macOS 터미널

Ghostty를 포크해 창 모델만 바꿨습니다. 한 창 안에 작업공간을 두고, 작업공간 안에 탭을, 탭 안에 분할 패널을 둡니다. 왼쪽 사이드바에서 이 구조 전체가 보입니다. 렌더러와 설정 파일은 Ghostty 것을 써서 기존 설정이 그대로 동작합니다.

2026.07~10개인 프로젝트MIT ZigSwift/AppKitSparkleGitHub Actions
devch.co.kr/chostty열기 ↗
Chostty 랜딩 페이지 전체 화면
릴리스18

v1.0.0은 2026-10-08, 이후 1.0.2까지

복구 기능 제거 PR의 테스트508

macOS 테스트 전체 통과

탭 재결합 집중 테스트106

기기 직접 시험 A, B, C도 통과

설치DMG

Developer ID 서명과 공증, 자동 업데이트

왜 만들었나

Ghostty의 macOS 탭은 탭마다 창을 하나씩 만들고 운영체제의 창 묶음에 맡깁니다. 그래서 "이 프로젝트의 탭들"을 한데 묶을 자리가 없고 창이 뒤로 가면 묶음도 보이지 않습니다.

처음에는 Ghostty와 tmux 조합을 검토했습니다. 원한 모습은 cmux처럼 왼쪽 사이드바에 작업공간이 보이는 형태였습니다. cmux도 써 봤는데 당시 쓰던 에이전트 도구가 tmux와 함께 도는 방식이라 cmux 안에서는 호환이 잘 맞지 않았습니다. cmux는 출시된 지 몇 달 안 된 앱이라 업데이트가 아주 잦고 공개 이슈에도 메모리가 계속 늘어난다는 보고가 있어 매일 쓰는 터미널로 두기에는 마음이 놓이지 않았습니다. Orca는 기능과 개념은 좋았지만 제가 쓸 때는 베타 무렵이라 버그가 많고 무겁게 느껴졌습니다. 그래서 Ghostty처럼 가벼운 터미널 위에 제가 원하는 작업공간 사이드바만 얹기로 했습니다. 렌더러는 그대로 두고 창 모델만 바꿨습니다.

숨기지 않고 지운 네이티브 탭

작업공간 사이드바를 얹어도 AppKit 탭이 남아 있으면 탭 모델이 두 벌이 됩니다. 원본을 따라 코드를 받을 때마다 창 단위 가정이 다시 들어올 수도 있었습니다. 그래서 창 하나 안에 작업공간, 탭, 분할 패널을 트리로 두고 네이티브 탭은 제거했습니다. 네이티브 탭 API가 쓰이면 빌드가 실패하는 감사 스크립트도 CI에 넣었습니다.

이제 한 사이드바에서 모든 작업공간, 탭, 패널이 보이고 사이드바 제어 위치마다 UI 테스트를 둡니다. 대신 원본 변경을 받아올 때마다 동기화 목록을 읽고 창 관련 변경을 직접 걸러야 해서 포크를 유지하는 비용이 늘었습니다.

만들어 두고 걷어 낸 세션 복구

v0.2.5에서 앱을 다시 열면 이전 창을 되살리는 복구를 넣었습니다. 이름만 보면 작업을 되살려 줄 것 같았지만 실제로 돌아오는 것은 새 셸과 작업 디렉터리뿐이었고 프로세스와 스크롤백은 돌아오지 않았습니다. 그러면서도 셸 제목이나 디렉터리가 바뀔 때마다 전체 구조를 메인 스레드에서 다시 계산하고 있어서 이전 버전보다 무겁고 잔버그가 많았습니다.

복구 파이프라인을 더 고치는 길과 복구를 걷어 내고 v0.2.4 기준으로 안정화하는 길 중 뒤쪽을 골랐습니다. 복구 기능을 지운 PR은 macOS 테스트 508건을 통과했습니다. 그 뒤 작업공간, 탭, 패널 배치, 작업 디렉터리만 파일에 남기는 구조 저장을 다시 넣었습니다. 저장본이 지금 돌고 있는 셸을 덮어쓰지 않도록 디스크로 쓰는 방향만 허용했고 "종료 전 화면 그대로"라는 약속은 하지 않습니다. 앱을 꺼도 프로세스를 살려 두는 백그라운드 서버는 구조 저장이 안정된 뒤로 미뤘습니다.

구조 저장은 실제 앱에서 이전 저장본 승격과 쉬는 동안 쓰기 없음을 확인했습니다. 강제 종료 뒤 저장이 멈추던 문제는 재사용된 PID를 실행 중인 앱으로 오인한 원인을 고쳐 막았습니다.

그 밖에