3-2. 터미널다워지기 (6/13 ~ 6/30)

6월 후반은 "터미널이 갖춰야 할 것"을 채운 시기다. 그래픽 프로토콜, 글리프 합성, 유니코드, 설정, 배포까지 한 번에 밀었다.

Quick Terminal과 kitty 그래픽

6월 13일에 Quick Terminal이 폭발적으로 붙었다 — 위치 옵션, 미니멀 모드, 중앙 정렬, 분할 pane 테두리. 같은 날 iris 저장소도 새로 열렸다.

이미지 프로토콜은 여러 후보 중 하나만 골랐다 — "일단 키티부터 지원하시죠? 그리고 여태까지 한 작업 문서 동기화 먼저 해주세요"(6/15). 6월 16일에 kitty 그래픽 프로토콜을 구현했다.

  • Metal 텍스처 렌더와 텍스처 캐시, LRU eviction
  • PNG 디코딩, zlib 압축, chunked 전송
  • 함께 채운 VT 갭: SGR 장식선(overline/strikethrough/dim), OSC 색·클립보드·데스크톱 알림, DECOM

폰트가 없는 글자를 직접 그린다

6월 17일에는 합성 글리프를 완성했다. box-drawing, block elements, Braille, powerline, Legacy Computing 기호를 폰트에 의존하지 않고 직접 그린다. 합성 코드는 공유 픽셀 프리미티브로 정리했다. 같은 날 스크롤바와 Find를 pane별로 독립시키고, Option+드래그 블록 선택과 유니코드 케이스폴딩을 넣었다.

에이전트가 화면에 들어온다 (6/17~6/22)

Maru가 단순한 터미널에서 갈라져 나오는 첫 지점이다. 발단은 6월 17일의 요청 하나였다.

"그리고 해당 터미널에서 클로드 코드나 코덱스 키면 cmux나 warp처럼 해당 클로드 세션으로 바뀌고 진행중일땐 진행중인 UI 끝일떈 끝..." — 2026-06-17

다음 날 doc-first로 설계(에이전트 세션 감지, JSONL 기반)를 쓰고 PR0~PR4로 구현했다.

PR내용
PR0에이전트 세션 감지 설계
PR1Claude 트랜스크립트 상태 파싱 순수 코어
PR2Codex 트랜스크립트 어댑터
PR3에이전트 세션 상태를 사이드바에 표시
PR4에이전트 세션 완료 알림

터미널 출력을 훔쳐보는 방식이 아니라 각 도구가 남기는 트랜스크립트(JSONL)를 읽어 상태를 판정하는 구조다. 이어서 사이드바에 claude/codex 심볼과 세션 카드를 넣고, 카드 색을 상태 기반 관례로 정리했다(6/20).

알림은 6월 19~22일에 붙었다. 권한을 선요청으로 바꿔 OSC 9/777이 오지 않아도 권한 팝업이 먼저 뜨게 하고, TERM_PROGRAM=ghostty를 주입해 Claude·Codex가 설정 없이도 데스크톱 알림을 보내게 했다. 그다음이 인앱 알림 센터다.

"그리고 오른쪽 위에 알림 아이콘 하나 추가해서 누르면 알림 목록도 나올 수 있게 앱 안에서도" — 2026-06-22

"알림 클릭하면 알림 준 터미널로 자동활성화하고 싶으넫 가능할까요?" — 2026-06-22

둘 다 그날 구현됐다 — 사이드바 종 아이콘과 알림 목록 패널, 읽음/지우기, notifications.* config, 배지 9+, 그리고 알림을 누르면 발신 터미널로 창·탭·pane·term까지 따라 들어가는 동작.

유니코드를 정면으로

6월 23일, 69커밋이 들어간 날이다. 첫 주에 "미룬다"고 적어 뒀던 항목들을 여는 계기는 평범한 버그 보고였다.

"ls로 나오는 한글 폴더 자음 모음 분리 되는데 원인이 무엇인지 알 수 있을까요?" — 2026-06-23

macOS 파일 시스템이 한글을 NFD로 저장하기 때문에 ls 출력의 한글이 자모로 흩어져 보이는 문제였다. 셀 하나에 코드포인트 하나라는 가정이 깨지는 자리라, 임시 방편 대신 클러스터 모델을 넣기로 했다. 앞서 6월 14일에도 IME 조합 중 같은 증상이 보고돼 있었다 — "여전히 동일합니다 커서가 있긴 한데 깜빡이지 않고 가나다라를 입력하면 ㄱㄴㄷㄹ로 잘려보여요".

  1. HG1 — UAX#29 기반 한글 grapheme 분절 순수 함수
  2. HG2 — 셀이 여러 코드포인트를 갖게 하고, NFD 한글 cluster producer와 무손실 직렬화
  3. HG3a — CoreText 셰이퍼에 cluster 전체를 전달
  4. HG3b — Cell.combining 제거
  5. 이모지 ZWJ 시퀀스(GB11)와 키캡을 클러스터 경로로 통합

셀 하나가 코드포인트 하나라는 가정을 걷어내는 작업이라 저장·직렬화·셰이핑·렌더가 모두 움직였다.

설정: 스키마가 단일 출처

6월 21~22일 이틀에 config 체계를 세웠다.

  • 메타를 1급 필드로 두는 스키마 설계(config-schema.md) 확정
  • 대표 4종 이주(CS-1) → sub-struct 스칼라(CS-2) → 최상위 스칼라(CS-2b) 일괄 이주
  • 스키마↔문서 doc-drift 가드(CS-3)
  • 설정 화면(GUI) 설계(config-gui.md, CS-4)

다음 날 GUI를 실사용 수준으로 채웠다. HSV 색 picker(SV 그리드 + hue 스트립), 폼 검색(/), 좌측 섹션 키보드 네비, Backspace로 keybind·env 삭제, 비활성 행 표시, 테마 프리셋 순환과 활성 시 색 잠금. window.opacity, cursor.blink-interval-ms 같은 키도 이때 함께 들어갔다.

스키마가 단일 출처라는 결정 덕분에, 8월에 설정 화면을 모바일에서 스키마에서 자동 생성할 수 있었다.

단축키 힌트와 링크

  • 6/25 — 모디파이어를 누르고 있으면 뜨는 단축키 힌트 HUD(KH-0~6). 설계 → 멀티행 HUD → 카탈로그 → keyhint.* 스키마 설정 → 홀드 트리거 → 키캡 배경 → 배지 재설계 순으로 쌓았고, 간헐적으로 안 뜨던 근본 원인은 순수 Zig 상태머신으로 옮겨 잡았다.
  • 6/26 — Cmd+클릭으로 파일 경로와 추가 스킴 링크 열기. code-review와 적대적 검증이 hover 락 대칭, 경로 resolve, urlAt cwd use-after-free, IPv6 대괄호 보존을 잡아냈다.

배포 파이프라인

6월 28일에 인앱 업데이트와 배포를 갖췄다.

  • 버전 주입·체크 로직과 config 키
  • app_session에 백그라운드 버전 체크와 알림 발화 통합
  • universal(arm64 + x86_64) dmg 빌드, 릴리스 워크플로, 업데이트 전략 문서

UI도 함께 다듬었다. Warp를 벤치마킹해 상단 탭바의 grip hover-only와 바 높이, 마지막 탭 옆 인라인 +를 단계적으로 넣었다.

마무리: 폰트와 프레임

  • 6/29 — 개발자용 폰트 3종(Fira Code·Cascadia Code·Hack)을 라이선스 문서와 함께 번들하고 폰트 피커 GUI를 붙였다. IME 조합 중 preedit을 오버레이로 띄워 자동완성 고스트를 가리게 했다.
  • 6/30 — render.frame-rate 설정(기본 60Hz)과 frame-loop cadence 고정. 드래그 자동 스크롤을 경과 ms 기준으로 바꿔 프레임 레이트와 무관하게 약 30줄/s로 맞췄다. 자간은 셀당 2 quad로 그려 음수 자간의 세로 흔들림을 없앴다.

프레임 레이트 작업의 발단은 세션에 그대로 남아 있다.

"주사율 지금 30hz인데, 60hz로 수정하고 문서 업데이드 및 cmd + , 로 눌렀을때 설정하는 부분에서 설정 할 수 있게 할 수 있나요? 기본값이 60hz" — 2026-06-30

같은 날 링크 클릭의 경계 결함도 사용자 보고에서 시작됐다.

"지금 터미널 크기로 인해 말줄임표 처리되는 링크는 제대로 실행안되고, 터미널 창 크기를 늘려서 처리한 경우 괜찮은데요. 이거 어떻게 처리 할 수 있..." — 2026-06-30

이 달에 던져 둔 질문 두 개

6월에 답을 내지 않고 남긴 질문이 둘 있는데, 각각 7월과 8월의 큰 축이 된다.

하나. UI를 그리는 코드는 무엇인가. 터미널 위에 얹는 UI(탭바·사이드바·모달)를 chrome이라 부르기 시작하면서 나온 질문이다.

"그리고 사실 크롬은 일종의 디자인시스템과 같은건데, 이건 별도 플러그인? 라이브러리 형태의 구조로 가져가는게 좋을까요? 아니..." — 2026-06-14

"아이콘이 너무 허접해서 그런데 우리 디자인 시스템에 svg 넣는게 가능할까요? 트레이드 오프가 있을까요?" — 2026-06-25

이 질문의 답이 8월의 CIM·ScrollArea 이관과 컴포넌트 선언 구조다.

둘. 웹을 어디까지 들일 것인가. 마크다운 뷰어와 git diff를 만들려면 결국 웹 스택이 필요했다.

"그래서 가볍게 poc 느낌으로 웹 생태계를 활용하려고 했구요. cmux처럼 인앱브라우저도 가능하게 할 생각이였구요" — 2026-06-28

"인앱 마크다운 뷰어 그리고 코덱스나 클로드 데스크탑 앱처럼 git diff나 이런것 cmux에서 지원하는거 다 할 생각이긴 하거든요" — 2026-06-28

"네이티브 뷰 비사용이란게 호환성때문에 그랬던건데 각 운영체제의 네이티브 인앱웹뷰 쓰면 상관없긴 한거라" — 2026-06-28

7월의 웹 패널·인앱 브라우저가 여기서 출발한다.