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로 접속하면 host는 cowork.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은 대체로 허용하나 일부 보안 정책 하에서 제한된다.
[낮음] copyEl — textContent에 "복사" 버튼 텍스트 혼입 위험
파일: 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·오너 피드 등 신조어 미설명 | 낮음 |
수정 우선순위 (빠른 순)
- portal.html:263-266 —
http://→location.protocol+'//'+host로 변경 - server.js:692 cowork-cli.sh 생성 — 포트 없이
https://$HOST로 생성 (host에:없을 때) - index.html:199,202 —
:9720→https://cowork.crowny.org - portal.html:370 copyEl — clipboard 폴백(
execCommand) 추가 - 두 HTML 공통 — Pretendard CDN
<link>추가 - 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