← 목록
기타 2026-06-27 12KB 읽기 14분

cowork UX/프론트엔드 감사 — 윈도우PC 무한 제한 원인 규명

작성일: 2026-06-27 대상: /Users/ef/crowny-cowork/public/portal.html, public/index.html, public/js/crowny-admin-widget.js 목적: 윈도우PC 무한 제한 원인 + kps.crowny.org 대비 UX 격차 + 표현 접근성 감사


1. 윈도우PC 무한 제한 원인 — 코드 근거

[높음] portal.html — 부트스트랩 명령에 http:// 하드코딩

파일: public/portal.html:263-266

javascripth('bootMac').innerHTML='<button...>복사</button>'+
  `curl -s http://${host}/setup | bash -s -- ${ME.id}`;
h('bootWin').innerHTML='<button...>복사</button>'+
  `irm http://${host}/setup.ps1 | iex; cowork-setup ${ME.id}`;

HTTPS로 접속하면 hostcowork.crowny.org(포트 없음)가 된다. 그런데 무조건 http://를 앞에 붙여서 http://cowork.crowny.org/setup.ps1을 생성한다.

반면 서버(server.js:370)의 setup.ps1 내부 로직은:

powershellif ($H -match ":") { $BASE = "http://$H" } else { $BASE = "https://$H" }
이 조건으로 올바르게 처리한다.

문제: portal.html이 이 조건을 무시하고 무조건 http://를 생성한다. → 윈도우 엣지/크롬에서 HSTS(HTTP 강제 HTTPS 정책)가 걸린 경우, 또는 기업 보안 정책으로 HTTP가 차단된 경우, 명령 자체가 작동 안 한다.


[높음] cowork-cli.sh — 포트 직접 접속으로 배포

파일: server.js:692, 702, 714, 719, 727, 759, 770, 778 등

서버가 생성해 배포하는 cowork-cli.sh 스크립트:

bashHOST="${host || 'cowork.crowny.org'}"
PORT_NUM=9720
...
curl -s -X POST "http://$HOST:$PORT_NUM/api/register"
curl -s "http://$HOST:$PORT_NUM/api/libs"
curl -s "http://$HOST:$PORT_NUM/api/login" ...

CLAUDE.md에 명시된 함정: "외부에서 :9720 직접 접속 = 방화벽 차단(000/연결안됨)"

/cli로 배포된 스크립트는 모두 http://cowork.crowny.org:9720으로 요청을 보낸다. 외부(윈도우PC)에서 이 스크립트를 사용하면 모든 명령이 연결 실패.


[높음] index.html CLI 탭 — 포트 하드코딩 URL

파일: public/index.html:199, 202

html<code>curl -o cowork-cli.sh cowork.crowny.org:9720/cli && chmod +x cowork-cli.sh</code>
<code>curl -o run.sh cowork.crowny.org:9720/api/run/HTTP서버.한선 && bash run.sh</code>

이 화면의 URL을 윈도우에서 복사하면 방화벽에 막힌다. https://cowork.crowny.org/cli로 수정해야 한다.


[높음] navigator.clipboard.writeText — HTTP에서 작동 안 함

파일: public/portal.html:370

javascriptfunction copyEl(id){ const t=h(id).textContent.replace('복사','').trim(); navigator.clipboard.writeText(t); }

navigator.clipboard.writeText()HTTPS 보안 컨텍스트에서만 동작한다. 오류 처리(.catch())가 없어서 HTTP 접속 시 조용히 실패한다. 윈도우에서 "복사" 버튼을 눌러도 클립보드에 아무것도 복사 안 된다.

수정 방법:

javascriptfunction copyEl(id){
  const t = h(id).textContent.replace('복사','').trim();
  if(navigator.clipboard && location.protocol==='https:'){
    navigator.clipboard.writeText(t).catch(()=>fallbackCopy(t));
  } else {
    fallbackCopy(t);  // document.execCommand('copy') 폴백
  }
}


[중간] blob 다운로드 — Content-Disposition 파싱 불완전

파일: public/portal.html:254

javascripta.download=(r.headers.get('Content-Disposition')||'cowork-setting.tgz')
  .replace(/.*filename="?([^"]+)"?.*/,'$1');

서버(server.js:1877-1881)는 RFC5987 형식으로 보낸다:

attachment; filename="ascii_fallback.tgz"; filename*=UTF-8''%ED%95%9C%EA%B8%80.tgz

포털 정규식은 filename= 앞부분만 잡아 ASCII 폴백(한글→_로 치환된 이름)을 쓴다. 의도 자체는 문제없으나 윈도우에서 파일명이 ______-v1.0.zip처럼 표시된다.

또한 URL.revokeObjectURL()을 호출하지 않아 메모리 누수가 발생한다 (pull함수, dlPkg, dlCommit 동일).


[중간] dlPkg — 한글 파일명을 a.download에 직접 대입

파일: public/portal.html:277-278

javascripta.href=URL.createObjectURL(blob);
a.download=p.file;   // 예: '크라우니-올인원-v1.0.zip'
a.click();

Firefox에서 a.download에 한글이 포함되면 파일명이 깨지거나 다운로드가 거부될 수 있다. Edge/Chrome은 대체로 허용하나 일부 보안 정책 하에서 제한된다.


[낮음] copyEltextContent에 "복사" 버튼 텍스트 혼입 위험

파일: public/portal.html:263-266, 370

javascriptconst t=h(id).textContent.replace('복사','').trim();

bootMac / bootWin 요소의 textContent에서 "복사" 문자열만 제거한다. 버튼 텍스트가 "복사"가 아닌 다른 내용으로 바뀌거나, 여러 버튼이 있으면 오작동한다.


[낮음] index.html api() — 인증 헤더 없는 단순 fetch

파일: public/index.html:255

javascriptasync function api(p){const r=await fetch(A+p);return r.json()}

인증 토큰을 붙이지 않는다. 공개 대시보드용이라 의도적이지만, 인증 필수 엔드포인트(/api/packages, /api/download)를 이 함수로 호출하면 401이 난다. 코드 분리가 명확하지 않아 유지보수 중 실수 가능성이 있다.


2. kps.crowny.org 디자인 표준 대비 UX 격차

[높음] 크라우니 디자인 팔레트 미적용

파일: public/portal.html:9, public/index.html:9-12

표준 팔레트:

--choco:#3B2A1D  --gold:#B58A4A  --gold-soft:#D8C29A  --gold-wash:#EFE4CD

실제 cowork 팔레트:

css--bg:#0a0a0f; --ac:#7c5bf5; --ac2:#5b8bf5;

보라 계열 색상으로 kps.crowny.org(초콜릿+골드)와 완전히 다른 색 체계다. 같은 "크라우니" 브랜드인데 사이트마다 색이 달라 브랜드 일관성이 없다.


[높음] Pretendard 폰트 CDN 미로드 — 윈도우에서 기본 폰트 표시

파일: public/portal.html:10, public/index.html:13

cssfont-family:-apple-system,'Pretendard',sans-serif;
/* 또는 */
font-family:-apple-system,'SF Pro','Pretendard',sans-serif;

실제 @import 또는 <link> 태그가 없다. Pretendard가 설치된 맥에서는 보이지만, 윈도우PC에서는 맑은 고딕(시스템 폰트)으로 렌더링된다.

kps.crowny.org 표준:

html<link href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.css" rel="stylesheet">


[중간] 테마 토글 없음

kps.crowny.org에는 theme-toggle 버튼이 있어 라이트/다크 모드를 전환할 수 있다. cowork 두 페이지 모두 다크 모드만 지원한다. 밝은 환경에서 작업하는 사용자(특히 윈도우 기업 환경)에게 피로감을 준다.


[중간] 언어 토글 없음

kps.crowny.org의 lang-toggle 패턴이 없다. 영어 사용자나 외국 클라이언트를 위한 다국어 지원이 전혀 없다.


[중간] 히어로 섹션 없음

kps.crowny.org의 hero-motif 패턴(큰 타이틀 + 한 줄 설명 + CTA 버튼 + 배경 그라디언트)이 없다. 처음 방문한 사용자가 "이 사이트가 뭐 하는 곳인지" 바로 알 수 없다. index.html은 로그인 없이 대시보드로 바로 진입하는 구조라 더욱 그렇다.


[중간] reveal 스크롤 애니메이션 없음

kps.crowny.org는 스크롤 시 카드가 아래에서 올라오는 reveal 애니메이션으로 시각적 흥미를 준다. cowork는 정적 렌더링만 한다. 작은 개선이지만 완성도 체감 차이가 크다.


[낮음] 반경·그림자 비표준

표준: r-xs:8px / r-sm:12px / r-md:18px / r-lg:28px / r-xl:40px / r-pill:999px cowork: border-radius:12px, 10px, 8px, 6px 등 비규격 혼용. kps.crowny.org와 나란히 열면 카드 모서리 느낌이 다르다.


[낮음] crowny-admin-widget.js 색 비표준

파일: public/js/crowny-admin-widget.js:70-72

javascriptcss += 'background:#A8874A;color:#fff;...';

표준 골드 토큰(--gold:#B58A4A)에 근사하지만 정확히 일치하지 않는다(#A8874A vs #B58A4A).


3. 중학생 이해 표현 감사

[중간] "티어드 블록체인 세팅 이관" — 전문 용어 3개 연속

파일: public/portal.html:6, 163

"티어드(tiered)", "블록체인", "이관" 세 단어가 연속으로 붙어 있다. 중학생이 이해하려면 세 단어 모두 별도 설명이 필요하다.

대안: "등급별 설정 파일 동기화 포털" 정도가 더 쉽다.


[중간] "croworker 등록" — 신조어 무설명

파일: public/index.html:183

html<h3>Croworker 등록</h3>

'croworker'는 cowork+worker를 합친 신조어다. 설명이 없다. "팀원(croworker) 등록" 또는 "협업 참여자 등록" 정도로 바꾸면 이해가 쉽다.


[낮음] "오너 피드" — '오너', '피드' 동시 설명 없음

파일: public/portal.html:98

"오너 피드 — 오가는 모든 대화(지원·태스크·작업·오너) 한눈에 · 내가 쓰면 현재 세션에 반영" '오너'가 누구인지, '피드'가 무엇인지, '세션'이 왜 나오는지 설명이 없다. "관리자용 알림판 — 모든 대화를 보고, 메시지를 보내면 작업 중인 클로드가 바로 반영" 정도가 낫다.


[낮음] "부트스트랩" 미설명

파일: public/portal.html:89

"다른 컴퓨터에서 같이 작업하기 (부트스트랩)" 부트스트랩은 IT 용어다. "(시작 설치 자동화)" 정도로 바꾸면 처음 보는 사람도 이해한다.


[낮음] "needs-owner" 상태 — 영어 코드 노출

파일: public/portal.html:288

javascriptconst STMAP={open:'🆕 신규',screening:'🔎 검토중','needs-owner':'⏳ 오너확인대기',...}

'오너확인대기'라고 한글로 표시하지만 '오너'가 무엇인지 여전히 모호하다. "⏳ 관리자 검토 중"이 더 쉽다.


요약

분류문제심각도
윈도우 차단portal.html 부트스트랩 http:// 하드코딩높음
윈도우 차단cowork-cli.sh :9720 포트 직접 접속높음
윈도우 차단index.html CLI 탭 :9720 하드코딩높음
윈도우 차단clipboard API HTTPS 전용 오류처리 없음높음
다운로드blob 메모리 누수 + 한글 파일명 처리중간
UX 격차크라우니 디자인 팔레트 미적용높음
UX 격차Pretendard 폰트 CDN 미로드높음
UX 격차테마/언어 토글 없음중간
UX 격차히어로 섹션·reveal 애니메이션 없음중간
표현 접근성전문 용어 남발(티어드·블록체인·이관·부트스트랩)중간
표현 접근성croworker·오너 피드 등 신조어 미설명낮음

수정 우선순위 (빠른 순)

  1. portal.html:263-266http://location.protocol+'//'+host 로 변경
  2. server.js:692 cowork-cli.sh 생성 — 포트 없이 https://$HOST로 생성 (host에 : 없을 때)
  3. index.html:199,202:9720https://cowork.crowny.org
  4. portal.html:370 copyEl — clipboard 폴백(execCommand) 추가
  5. 두 HTML 공통 — Pretendard CDN <link> 추가
  6. portal.html blob 다운로드URL.revokeObjectURL() 추가
관련 파일:
  • /Users/ef/crowny-cowork/public/portal.html
  • /Users/ef/crowny-cowork/public/index.html
  • /Users/ef/crowny-cowork/server.js
  • /Users/ef/crowny-cowork/public/js/crowny-admin-widget.js