← 목록
AI 2026-07-26 11KB 읽기 12분

CrownyAI 글로벌화 보완요소 + 윈도우버전 근본원인 진단 (2026-07-26)

1. 윈도우버전이 잘 안 되는 근본 원인 (실측)

  1. 제품 정본이 Apple 전용 레이어에 있음: 신셸 = crowny-ai-*.m 16,170줄 ObjC, AppKit 심볼 301개 결합. 윈도우에선 컴파일 자체 불가 → 윈도우판은 "포팅"이 아니라 "재작성".
  2. 재작성본의 드리프트: native/win/crowny_browser_win.c(44KB)는 7/1 스냅샷 — 이후 25일간 맥에만 쌓인 기능(멀티윈도우·오피스·사이드바·팝업수리…)이 전부 미반영. 두 코드베이스 이중 유지가 구조적으로 실패.
  3. 맥에서 최종 빌드 불가: WebView2는 COM+VS2022 전용(BUILD-WINDOWS.md 실측 "CrownyBrowser.exe 최종 빌드 = Windows에서만"). 개발 루프(맥 세션)와 단절 → 만들어도 검증 루프가 없어 실패 반복.
  4. 윈도우 검증 하네스 부재: 맥의 CROWNY_VERIFY_OUT 헤드리스·install-ai-app.sh 같은 원커맨드 루프가 윈도우엔 없음(ci-windows.bat는 빌드만).

2. "AppleKit 버리고 자체 지참?" 판정

  • 웹 엔진: 자체 번들(CEF/Chromium ~200MB+월간 보안패치 추종) 또는 자체 한선씨 엔진(일반 웹 호환은 수년 과제)은 타 — OS 공유 엔진 유지(맥 WKWebView/윈 WebView2/리눅스 WebKitGTK)가 티. 플랫폼 헌장("OS 공유 엔진, 1MB급") 방향이 맞음.
  • UI 셸: AppKit "폐기"가 아니라 어댑터로 강등 — 판정·레이아웃·상태 로직은 한선씨 SSOT(창관리.한선·런처레이아웃.한선 패턴 확대), 플랫폼별론 얇은 어댑터만.
  • 진짜 "가지고 다니는" 부분 = crownyc VM: crowny://app 벡터앱들은 이미 VM 직결이라 crownyc.exe(cl /O2 crownyc.c)만 있으면 윈도우에서 그대로 — 자체 소유 층은 이미 이식성 있음.

3. 전 세계 사용 보완요소 (실측 근거)

P0 — 맥에서 즉시(파급 최대)

  • 파일 업로드 불가: runOpenPanelWithParameters 부재(신셸·구셸 모두, grep 0) → 전 세계 모든 사이트의 파일 첨부 무동작. 팝업(7/26 수리)과 같은 부류.
  • 카메라/마이크 권한: requestMediaCapturePermission 부재 → 화상회의·음성인증 불가.
  • 세션 복원 없음: 재시작=탭 전체 소실(grep 0). 크롬 대비 최대 체감 격차.
  • 배포 서명: Signature=adhoc·TeamIdentifier not set → 타 맥에서 Gatekeeper "손상된 앱" 차단. Developer ID+공증+자동업데이트(Sparkle류) 필수.
  • i18n: UI 문자열 전부 한국어 하드코딩 → 최소 en 이중언어 테이블.

P1 — 품질

웹알림·비밀번호 자동완성·광고차단(콘텐츠룰)·웹페이지 인쇄·PDF뷰어·크래시리포터·접근성(VoiceOver)·하드닝 런타임.

P2 — 플랫폼

윈도우 v1(WebView2 셸 최소기능: 탭+옴니+북마크+다운로드, 신셸 동형 욕심 금지)·리눅스(WebKitGTK).

4. 윈도우 실무 처방

  • 로직을 한선씨 SSOT로 올리고 win 셸은 소비만(윈도우빌드가이드.md 매핑표 그대로).
  • 윈도우 PC 1대에 VS Build Tools+ci-windows.bat 상주 → 크라우니메신저/remote로 "빌드+스모크 1커맨드" 원격 루프 구축(관제 win/설치.ps1 전례).
  • v1 범위 동결: 탭·옴니·북마크·다운로드·crowny:// 인터셉트만. 오피스/집사/벡터앱은 crownyc.exe 확보 후 2차.

P0 착수 결과 (2026-07-26, 코드 항목 완료)

  • 파일 업로드: runOpenPanelWithParameters 구현(NSOpenPanel 시트, 다중선택 parameters 분기) — 전 세계 사이트 파일첨부 복구.
  • 카메라/마이크: requestMediaCapturePermissionForOrigin:type: 허용/거부 시트(macOS 12+) + Info.plist NSCamera/Microphone UsageDescription(라이브 번들·make-app.sh 템플릿 동시).
  • 세션 복원: 앱 종료 시(applicationWillTerminate) 전 창 탭 URL→세션.txt, 다음 실행 시 argv/검증모드 아닐 때 첫 창 복원(AI홈·설정 제외). data/세션.txt.
  • 빌드 에러0, install-ai-app.sh 설치+재서명, 실행번들 심볼 4종+plist Camera키 확증. 한선씨 창관리.한선 44/44(세션복원가능·미디어권한판정 추가).
  • 서명/공증(Developer ID)·i18n(영어 이중언어)은 미착수 — 서명은 Apple 계정(사장님 결정), i18n은 별도 트랙.
  • 앱 재시작 후 육안(업로드 다이얼로그·재시작 탭복원) 잔여.

추가 수리 (2026-07-26, 다운로드 + 사이드바)

다운로드 (사용자: 업로드·다운로드 안 됨)

  • 근본원인: decidePolicyForNavigationActionnavigationAction.shouldPerformDownload를 무시하고 Allow만 반환 → <a download> 링크·다운로드 지시 클릭 시 아무 일도 안 일어남.
  • 수리: shouldPerformDownload=YES → WKNavigationActionPolicyDownload 반환(macOS 11.3+). 추가로 표시가능 MIME라도 Content-Disposition: attachment면 다운로드로 전환.
  • 헤드리스 실측 PASS: data-URL <a download> 클릭 → ~/Downloads/크라우니테스트.txt 생성·내용 일치. (기존 decideDestination/진행률/완료 훅은 정상이었음 — 트리거만 누락.)

사이드바 (버튼만 보임 + 크기조정)

  • 버튼만 보임 버그: CABookmarkSidebarView가 setFrameSize: 미구현 → 창 축소 후 재확장 시 행이 옛 좌표로 남아 사라져 보임. 마지막 reload 인자 캐시 + setFrameSize:에서 재배치로 수리.
  • W7 폭 조정: 우측 6px 드래그 핸들(resize 커서) → CASidebarWidth 영속(160~420 클램프, 기본 220), 레일 모드 숨김. relayoutMiddleRow가 사용자 폭 사용.
  • 한선씨 창관리.한선 47/47(사이드바폭클램프 추가).

미착수(다음 턴): 자동 로그인(비밀번호 자동완성/자동입력) — P1, 별도 기능.

자동 로그인 (2026-07-26, P1 완료)

  • 저장: <input type=password> 폼 제출을 즉시층 JS(caPasswordScriptSource)가 가로채 caPasswd 핸들러로 {user,pass} 전송 → 확인 다이얼로그 후 Keychain(kSecClassInternetPassword, host별) 저장. 치수가드(pass≤512·user≤256)+동일값 중복 스킵.
  • 자동완성: didFinishNavigation(http/https)에서 host로 Keychain 조회 → native가 evaluateJavaScript로 아이디/비번 필드 채움(단방향, 빈 필드만, 자동제출 없음). 비번은 JS→native로 저장 제안 시에만 이동.
  • 검증: Keychain store/load 라운드트립 하네스 ROUNDTRIP_OK + 설치번들 심볼 4종(CrownyPasswdVault/caHandlePasswdMessage/caAutofillWebView/caPasswd). 한선씨 창관리.한선 53/53(자동로그인저장판정·자동완성적용).
  • 보안: NSUserDefaults 아닌 Keychain, host 스코프, 자동제출 없음(채우기만). 잔여=저장된 비번 관리 UI(설정>비밀번호 목록/삭제)·실 로그인 사이트 육안(앱 재시작 후).

계정 UI 통일 + 크라우니통합아이디 (2026-07-26)

  • 문제: 아바타('한') 클릭 시 별도 NSWindow(440×300 titled "크라우니 계정") 모달이 떠 앱 디자인과 이질적("이상한 모달창").
  • 수리: CAAccountPanel을 별도 창→NSPopover(아바타 앵커드, behavior=Transient 바깥클릭 자동닫힘, appearance=앱 테마 라이트/다크 자동채택)로 전환. 빌드 로직(레이아웃 누적기·필드 헬퍼·탭)은 그대로, 컨테이너만 window.contentView→_popVC.view. presentFromAnchor=showRelativeToRect:ofView:anchor. 성공/로그아웃 시 orderOut→[_popover close].
  • 크라우니통합아이디: 백엔드는 이미 CACrownyIDSession이 crowny-auth(/api/auth/signup·login·me, JWT)로 통신 중 = 통합ID 그 자체. 이번엔 UI만 통일(엔드포인트 무변경). 심볼 확증(NSPopover showRelativeToRect + /api/auth/login·signup 잔존).
  • 한선씨 창관리.한선 55/55(계정패널모드). 잔여=실 로그인 GUI 육안(앱 재시작 후)·JWT 토큰 Keychain 승격(현재 NSUserDefaults, 기존 한계 유지).

계정 팝오버 디자인 격상 (2026-07-26 — 앱등록가이드 톤 적용)

  • 사용자 피드백: "크라우니앱등록가이드가 훨씬 예쁨" → 그 팔레트(bundle/guide 라이트 #FFFFFF/보더 #E5E2DD/골드 #C9A961/골드텍스트 #A08840, 다크 #17130E)를 계정 팝오버 버튼에 적용.
  • _styleButton:primary: 헬퍼 추가 — 주버튼(로그인/회원가입)=골드 채움+흰 글씨 라운드8, 보조(로그아웃)=골드 외곽선. 구 회색 NSBezelStyleRounded 대체.
  • 확증: 바이너리 심볼 _styleButton + 골드상수 2건. GUI 실캡처는 사용자 활동중(포커스 스틸 위험, 메모리 함정)이라 앱 재시작/유휴 시점으로 보류.

다운로드 가짜 실패 토스트 수리 (2026-07-26, F8b)

  • 증상: 다운로드는 성공하는데 "실패했다고 나옴"(사용자 실측).
  • 원인: 다운로드로 전환된 provisional 네비게이션이 WebKitErrorDomain 102(Frame load interrupted)로 didFailProvisionalNavigation에 진입 — didFailNavigation엔 102/204 가드가 있었으나 provisional 경로엔 없어 handleLoadFailure→오류 토스트/카드.
  • 수리: didFailProvisionalNavigation에도 WebKitErrorDomain 102/204 return 가드 추가(F8 대칭).
  • 검증: 헤드리스 재실측 — 다운로드 정상 저장 + 실패 문구 부재. 설치+재서명 완료.

스크린샷 비교 → 계정 팝오버 디자인 정합 (2026-07-26)

  • 사용자 스크린샷(23:46) 대조: 왼쪽 앱등록가이드(예쁨) vs 오른쪽 계정 팝오버.
  • 식별된 갭 3: ①로그인 버튼 파란색(골드 적용 직전 구빌드 — 재시작 시 골드) ②이메일칸 파란 포커스링 ③입력칸 밋밋한 흰 사각.
  • 수리: 입력칸을 가이드 톤으로 — focusRingType=None, 크림배경(#FAF9F7/다크 #0A0908), 골드 얇은 테두리(#E5E2DD), 라운드6, 높이 24→30. 주버튼 골드채움(_styleButton, 기적용). 재시작 후 반영.

최종 확인 (2026-07-26 23:53 스크린샷) ✅

재시작 반영 후 계정 팝오버=앱등록가이드 톤 완전 통일: 골드 채움 로그인 버튼·골드 탭·크림 라운드 입력칸(파란 포커스링 제거)·아바타 앵커드 팝오버. 디자인 통일 트랙 완료.

3종 마감 (2026-07-27)

① 계정 팝오버 헤더 픽셀 정합

  • 볼드 타이틀 아래 회색 부제("한 번 로그인으로 크라우니 전 서비스 이용" / 계정모드 "크라우니 통합 계정 — 전 서비스 공통 로그인") + 우상단 접기(×) 버튼(라운드6 골드외곽, 클릭=팝오버 닫힘) — 앱등록가이드 collapse 미러. 심볼 확증.

② JWT 토큰 Keychain 승격

  • CACrownyIDSession 토큰 저장을 NSUserDefaults(평문 plist)→Keychain(kSecClassGenericPassword, org.crowny.ai.authtoken). user 공개필드 캐시는 NSUserDefaults 유지. 레거시 평문토큰 1회 자동 이관(_loadTokenMigrating)+삭제. 심볼가드 CrownyIDTokenVault. Keychain 라운드트립·삭제 하네스 JWT_ROUNDTRIP_OK. (자동로그인 비번 Keychain과 별개 vault.)

③ Developer ID 서명·공증 — 준비 완료, 실행은 사장님 계정 대기(s-admin 이관)

  • 현재 불가: Developer ID Application 인증서 없음(보유=Apple Development만, 팀 Y447DT68BP). notarytool 자격증명 미설정.
  • 준비물: native/notarize-ai-app.sh(인증서 자동탐지→하드닝런타임 서명→notarytool submit --wait→staple→spctl 검증) + entitlements 자동생성. 선행 3요건(Developer Program 가입·Developer ID Application 발급·notarytool store-credentials)만 채우면 원커맨드.
  • 크라우니메신저로 사장님 이관(계정 의사결정).