← 목록
AI 2026-07-17 8KB 읽기 8분

크라우니AI — 탭 창간이동(N7)·CLI 프로필 설정(N8)·탭폭 축소+창 최소크기(N9) (2026-07-17)

개요

오전 3건(탭분리·타이핑→옴니·집사CLI)에 이어 사용자 추가 지시 3건. sonnet 3기 병렬 위임, 페블=판정·통합.

무엇을 했는지

N7 — 탭 드래그를 다른 창 탭바에 드롭 → 그 창으로 이동

  • 계약 교체: chromeDetachTab:atScreenPoint: (드롭 스크린좌표 전달).
  • 히트테스트: CGWindowListCopyWindowInfo(z순서) — 타 pid + 소유자명 CrownyAI/CrownyBrowser + layer0 + 창 상단 88px 밴드. Cocoa→CG y플립(주화면 기준).
  • IPC: NSDistributedNotificationCenter crowny.ai.adoptTab {pid, url} → 수신 인스턴스(pid 일치)가 탭 생성+창 전면화. 밴드 밖 드롭=기존 새 인스턴스 분리. 창간 이동은 마지막 1탭도 허용(빈 창은 AI홈 재생성).
  • 번들 CFBundleName=CrownyAI 확인 — 소유자명 매치 집합 유효.

N8 — 집사 CLI 계정/특성 프로필 + 검증 (지금은 claude 대상)

  • defaults 4키: crowny.ai.cliCommand / cliModel / cliConfigDir(CLAUDE_CONFIG_DIR=계정 프로필) / cliPersona(특성=추가 시스템프롬프트).
  • 설정>크라우니AI: 입력 4행(CASettingsTextRow 신설) + "CLI 연결 검증" 행([검증]→브릿지 실호출 60s, ✓응답(N초)/✗실패 라벨).
  • 브릿지/butler NSTask env 구동 일반화: CROWNY_CLI_CMD/MODEL/PERSONA, claude 계열만 --model/--append-system-prompt, 로그 라벨 claude_CLI_${MODEL}. 한선 동반 갱신(명령베이스이름 basename 판정)+학습(집사CLI브릿지_프로필env).
  • 실측: 기본 env 실응답("준비", 13s급)·모델/페르소나 지정·없는 CMD exit3 — 3경로 PASS. (에이전트의 env -i "미로그인" 소견은 격리 env 탓 — 정상 env 재실측으로 반증)

N9 — 탭폭 2단 축소 + 창 최소크기 완화

  • 탭폭 clamp 하한 72→30(FLOORW), 극단(n>avail/30)은 avail/n(15px 최후바닥) — avail=1200 기준 n=45도 총폭≤탭바.
  • 탭 3단 적응(경계 SSOT=caiIsNarrowTab 56px): ≥110 정상 / 56~110 말줄임+닫기 활성탭만 / <56 아이콘 전용(라벨·닫기 숨김, 호버 노출도 차단).
  • 창 minSize 1180×760→640×480. 좁은 폭 내성: 옴니<120 → 집사알약 아이콘화(36px)+재계산, 옴니 최소 80 보장, 옴니<200 ⌥Space칩 숨김, 북마크바 넘침 항목 숨김, relayoutMiddleRow 음수 가드.

검증

  • 파일별 syntax 게이트 0에러 → make ai 통합 빌드 경고 0(12:23, 507K) → 번들 배치 → 재기동(pid 88129).
  • GUI 육안 항목(사용자 확인): ①창 2개 사이 탭 드래그 이동 ②설정>크라우니AI CLI 4행+검증 버튼 ③탭 다수 생성 시 폭 축소 ④창을 640×480까지 줄여 레이아웃 확인.

관련 파일

native/{crowny-ai.h, crowny-ai-chrome.m, crowny-ai-main.m, crowny-ai-butler.m, crowny-ai-settings.m}, tools/집사CLI브릿지.{sh,한선} 에이전트B 상세문서: 2026-07-17-crownyai-집사cli-계정특성설정.md

잔여 이슈

  • GUI 4건 육안 확인 대기(위).
  • 타 CLI(비-claude)는 최소 규약(CMD "질의")만 — 실제 지원 시 인자 규약 확장 필요.
  • 오전 트랙 잔여(IME 첫 글자 자모, 드래그 중 원 탭 흐림 무효)는 유지.

사용자 테스트 피드백 수리 (12:46)

  • 육안 결과: 창축소 OK · 집사검증 OK(로그 12:28/12:29 claude_CLI_haiku 18~19s) · 탭이동 실패.
  • 원인: 분리모드 발동 조건이 "세로 40px 이탈"뿐 — 나란히 놓인 창으로 가로 드래그 시 미발동(드롭 자체가 무동작).
  • 수정: ①mouseDragged — 자기 창 프레임 밖 이탈 시 방향 무관 분리모드(N7 수정 주석) ②수신 관찰자 suspensionBehavior=DeliverImmediately ③onAdoptTab NSLog 진단줄.
  • 실측: raw 인스턴스 stderr 캡처로 adoptTab 수신 로그 확증(pid 매칭·url 전달). 12:46 빌드 배치·재기동(pid 33685).

2차 수리 (12:50) — "탭 누르고 움직이면 창 전체가 움직임"

  • 진짜 근본원인: 창=titlebarAppearsTransparent+FullSizeContentView 라 탭바가 타이틀바 영역 — 탭 드래그가 AppKit "창 이동"으로 흡수돼 mouseDragged 자체가 미도달(분리·이동 전부 이 때문에 무동작으로 보였음).
  • 수정: CAITabItemView mouseDownCanMoveWindow=NO(탭 위 창이동 금지, 빈 탭바=창이동 유지). 12:50 빌드·배치·재기동(pid 96574).

3차 수리 (13:30) — 드래그 무동작 진짜 근본원인 (프로브 실측)

  • NSLog 프로브 실측: mouseDown은 오는데 mouseUp/mouseDragged 미도달(일반 클릭조차).
  • 근본원인: mouseDown→chromeSelectTab→updateTabs가 탭 뷰 전체 제거·재생성 → 눌린 뷰가 계층 이탈 → AppKit이 그 뷰로의 후속 이벤트 전달 중단 → 이벤트가 테마 프레임으로 흘러 "창 전체 이동"(사용자 증상).
  • 수정: ①updateTabs 탭 수 동일 시 뷰 재사용(index 재대입+restyle만, 성능도 이득) ②드래그 좌표를 NSEvent mouseLocation→이벤트 파생 스크린 좌표로 정정(합성이벤트/일관성) ③고스트 이동도 동일.
  • 실측: 수정 후 mouseDown→mouseUp 페어 정상 도달(A3.log 3쌍). CGEventPostToPid 주입 하니스(evdrive.m) 제작 — 단 타 세션 pkill 레이스로 창간 실드롭까지는 미완, 수신 IPC는 12:46 기확증.
  • AppKit 교훈: 마우스 트래킹 중인 뷰를 removeFromSuperview 하면 안 됨 — 이벤트 스트림 단절+타이틀바 창이동 폴백. 목록 UI는 뷰 재사용이 정답.

4차 수리 (13:46) — "떨리며 가끔만 분리"

  • 원인: 히트테스트가 탭의 자식(라벨 NSTextField/아이콘 NSImageView)에 떨어지면 자식의 mouseDownCanMoveWindow=YES(기본) → 테마프레임 창이동 + 응답체인 경유 탭 드래그 추적이 동시에 걸림(=떨림). 라벨을 비껴 잡은 경우만 분리 성공("대개 안 됨"의 정체).
  • 수정: CAITabItemView hitTest를 자기 자신으로 수렴(닫기버튼만 예외). 13:46 빌드·배치·재기동.
  • 도구 적립: tools/e2e/{wins,adopt,evdrive}.m + README — evdrive(pid 주입 드래그)는 백그라운드 앱이 주입 마우스이벤트 무시(windowNumber 필드로도 불가) 한계 실측 기록.

✅ 최종 해결 (17:51 빌드, 사용자 실증 "된다!")

  • 5차(최종) 수리: CAWindow 서브클래스 — isMovable 게터 동적판정. 호버/클릭 movable 토글은 ①창이동 세션보다 늦고 ②mouseEntered=키창 전용(tear-off로 키 뺏기면 미발화)이라 근본 불가 — 창이동 시작 시점마다 커서가 탭 위인지 좌표 판정(caiHitTabAtWindowPoint, 이벤트 순서 무관).
  • 로그 확증: tear-off(targetPID=0→새창) + 창간이동(targetPID 지정→adoptTab 수신·타 인스턴스 pid 무시) 종단 성공.
  • 스티키 분리 + 자기밴드 드롭=취소 규칙 확정. acceptsFirstMouse=YES(비활성 창 첫클릭 드래그).
  • 안정화(17:55 빌드): N7 프로브(파일 기록)를 CROWNY_N7_DEBUG env 게이트 뒤로 — 평시 무기록, 진단 시 플래그로 재활성.
  • AppKit→한선씨 이관 리스트업 완성: 2026-07-17-AppKit-한선씨-이관후보-리스트업.md (티5·옴3·타 다수, 다음스텝=드래그판정 자산화→아이콘 글리프→크롬 레이아웃)

말풍선 클리핑 + TCC 권한 반복 수리 (22:41)

  • 말풍선 잘림("터미널 창 열어줘"→"터미널"): boundingRect 과소측정(86px vs 실렌더 ~104px)→라벨 감김+1줄 클리핑. sizeThatFits(셀 정확) 측정으로 교체(N19).
  • 권한 팝업 반복: adhoc 서명이 재빌드마다 해시 변경→TCC 매번 리셋. tools/서명설치.sh(자체 서명 인증서 "Crowny Dev Signing" 무대화 설치, crowny-sign.keychain)+배포 시 codesign — 이후 재빌드에도 동의 유지(처음 1회만). ※OS TCC는 앱 설정으로 주기 제어 불가 — 안정 서명이 정공법. p12는 OpenSSL3 레거시 암호화 필수(macOS import 함정).
  • 별도 집사창 무응답(N18): 창 열 때 활성 웹뷰 즉시 동기화. 별도창 ✕=창닫기(N17).