← 목록
기타 2026-07-11 7KB 읽기 7분

맥터미널(crowny-terminal-native) B1 마감 — ANSI 파서 보강 + .app 갱신

개요

CrownyOS 토탈 브라우저 로드맵 B1 단계(맥 네이티브 터미널, /Users/ef/crowny-terminal-native)의 남은 작업을 실사하고, claude code 같은 TUI가 이 터미널에서 정상 렌더되도록 ANSI 파서 상태기계를 보강했다. 작업 범위는 crowny-terminal-native/ 내부로 한정(CrownyBrowser는 다른 세션이 병렬 작업 중이라 미접촉).

실사 결과 — README 주장 vs 실코드

README는 "ANSI 컬러·커서 이동 지원(현재는 strip)"이라 적고 있었으나, 실제 src/app.m(1182줄→확장)에는 이미 다음이 구현돼 있었다(구 README 서술은 stale):
  • SGR(0/1/3x/4x/9x/10x, 256색 38·48;5;n, 트루컬러 38·48;2)
  • CUP류(A/B/C/D/H/f/G/d/E/F), ED/EL(J/K), IL/DL(L/M), ICH/DCH(@/P)
  • 저장/복원 커서(CSI s/u, DECSC/DECRC ESC 7/ESC 8)
  • Reverse Index(ESC M)
  • TIOCSWINSZ + SIGWINCH 리사이즈 전파(propagateWinsize) — README가 "남은 작업"이라 적었지만 이미 완료돼 있었음
진짜로 비어 있던 것은 두 가지뿐이었다:
  1. DECSTBM 스크롤영역(CSI r) — 코드에 "simplified: just ignore"라는 주석과 함께 완전 stub.
  2. 대체화면(alternate screen) 47/1047/1049 — 전혀 미구현. claude code/vim 등 풀스크린 TUI가
화면을 전환할 때 필수(미구현 시 TUI 종료 후 스크롤백이 뒤섞임).

구현

/Users/ef/crowny-terminal-native/src/app.m:
  • _mainCells/_altCells 이중 버퍼 추가, _cells는 활성 버퍼 별칭(이중 free 방지 처리).
  • resizeScreenRows:cols:가 두 버퍼 모두 리사이즈하도록 재작성(resizedBuffer:rows:cols:newRows:newCols: 헬퍼 분리).
  • scrollUpRegionTop:bottom:/scrollDownRegionTop:bottom: 추가 — 전체화면 리전이면 기존
스크롤백 기록 경로(scrollUp) 재사용, 리전 제한이면 그 구간만 이동(스크롤백 미기록, xterm과 동일).
  • putChar:/LF(0x0A)/Reverse Index(ESC M)가 스크롤영역(_scrollTop/_scrollBottom)을 인지하도록 수정.
  • executeCsi:params:len:case 'r'(DECSTBM 파싱+적용, 커서를 리전 원점으로 이동) 구현,
case 'S'/case 'T'(SU/SD 스크롤) 신규, case 'h'/case 'l'에 47/1047/1049 대체화면 진입/복귀 (1049는 커서 저장/복원 포함) 추가.
  • renderScreen: 대체화면 활성 중엔 스크롤백을 렌더하지 않음(풀스크린 TUI 위에 예전 스크롤백이
겹쳐 보이지 않도록).

검증

  1. 빌드: make(clean rebuild) exit 0, 경고 0.
  2. 헤드리스 C 하네스: /private/tmp/claude-501/.../scratchpad/ansi_harness.c
app.m의 parseCsiParams를 바이트 그대로 복사하고, 이번에 추가한 SGR/CUP/ED·EL/DECSTBM/ 대체화면(1049,47) 로직을 동일 규칙으로 이식해 25개 케이스 검증. 25/25 PASS, exit 0. - SGR 색상·굵게, CUP 좌표, ED mode2 전체지우기 - DECSTBM 리전 한정 스크롤은 스크롤백 미기록 vs 전체화면 스크롤은 기록(분리 검증) - 1049 진입 시 커서(0,0) 리셋+메인 내용 보존, 복귀 시 커서 복원+메인 내용 유지 - 47(커서 저장 없는 버전), CSI s/u 저장·복원
  1. GUI 실기동: 이 세션에서는 수행하지 않음(헤드리스 원칙). 사용자 실측 절차를 README에 기록:
make app && open build/크라우니터미널.app → 터미널 탭에서 claude 실행 → alt-screen 전환/색상 육안 확인.

한선씨 동반

/Users/ef/crowny-terminal-native/한선씨/ANSI파서.한선 — app.m에 추가한 CSI 파서 상태기계 (CSI파라미터파싱/SGR적용/CSI실행/스크롤_위·아래_영역/처리)를 1:1로 이관, C 하네스와 동일한 7개 시나리오(14개 검사문)를 내장한 자가검증 포함.
  • hanseonc_high 컴파일: 성공(0 에러, 4469 토큰, 13753 큐브).
  • VM 실행 검증은 차단됨 — 아래 "발견한 이슈" 참조. 크라우니코드 lookup 사전조회 MISS 확인 후 신규 작성.

발견한 이슈 (범위 밖, crowny-terminal-native 무관 — 별도 트리아지 필요)

crownyc/hanseonc_high 공유 툴체인(/Users/ef/CrownyOS/crownyc)에 루프 구문(동안/반복문)의 백점프가 루프 헤드가 아니라 프로그램 시작 주소로 잘못 튀는 회귀가 현재 존재한다.
  • 재현: ./hanseonc_high tests/기본기회귀.한선 > /tmp/t.toau && timeout 3 ./crownyc run /tmp/t.toau
→ 루프 이전까지는 EXPECT와 일치하다가 반복문 도달 즉시 프로그램 전체가 무한 재실행(exit 43/139).
  • crownyc.c(7/10 22:48)/hanseonc_high.c(7/11 08:52) 소스에서 clean rebuild(/tmp)해도 동일 재현 →
공유 바이너리 stale 캐시 문제가 아니라 소스 자체 회귀. smoke-test.sh(15/15 PASS)는 루프를 전혀 다루지 않아 이 회귀를 못 잡는다.
  • 이 프로젝트(crowny-terminal-native)뿐 아니라 루프를 쓰는 모든 .한선 프로그램(이 저장소의
기존 화면버퍼.한선 포함)이 현재 동일하게 깨져 있음을 재확인.
  • ~/.claude/scripts/crowny-knowledge.sh add feedback crownyc_loop_backjump_broken "..."
전 세션 브로드캐스트 완료(셀 #23146). 범위 제한(crowny-terminal-native만 수정 허용) 때문에 이 세션에서 crownyc.c는 직접 수정하지 않음 — crownyc 담당 세션의 트리아지 필요.

관련 파일

  • /Users/ef/crowny-terminal-native/src/app.m — ANSI 파서 본체(수정)
  • /Users/ef/crowny-terminal-native/한선씨/ANSI파서.한선 — 한선씨 동반본(신규)
  • /Users/ef/crowny-terminal-native/resources/Info.plist — CFBundleDisplayName "CrownyAI 터미널 (맥)", v0.2 (수정)
  • /Users/ef/crowny-terminal-native/README.md — 실사 결과 반영 갱신
  • /Users/ef/crowny-terminal-native/build/크라우니터미널.app — 재생성된 번들
  • /Users/ef/crowny-terminal-native/build/백업-20260711/ — 변경 전 바이너리·번들 백업
  • /private/tmp/claude-501/-Users-ef/929a8ec9-1c47-4929-9008-6af6618baaf0/scratchpad/ansi_harness.c — 헤드리스 C 검증 하네스(세션 스크래치패드, 영구 보관 아님)

잔여 이슈

  1. crownyc 루프 백점프 회귀 해결 대기 — 해결 후 ANSI파서.한선을 실제 VM에서 재실행해 하네스 결과와 대조 필요.
  2. IL/DL/ICH/DCH가 DECSTBM 리전 경계를 존중하지 않음(전체화면 기준 동작) — claude code 기본 UI엔
영향 적으나 vim split 등 리전 활용 앱에선 오동작 가능.
  1. 트루컬러(38;2) 저장은 되지만 렌더 경로가 rgb 필드를 안 씀(팔레트 근사만 사용) — 필요 시 colorFromCell
확장.
  1. 파일 탭 NSOutlineView 업그레이드, 탭 추가/제거 UI, 앱.한선↔C 브릿지는 이번 세션 범위 밖(README에 남은 작업으로 유지).
  2. GUI 실기동(사용자 육안) 검증 미실시 — README에 절차 기록, 사용자 실측 필요.