미리보기: 텍스트 선택형 댓글 HTML 페이지
어떤 계획, 제안, 초안 또는 완성文稿을 '텍스트 선택 → 댓글'이 가능한 HTML 페이지로 만들어 사용자 컴퓨터에서 열어줍니다(또는 고객이 검토). '전체 복사'를 누르면 댓글과 체크 결과가 마크다운으로 변환되어 대화에 붙여넣어집니다.
이 스킬의 파일 위치
이 파일이 있는 폴더가 스킬 폴더입니다(이하 $SKILL_DIR). 명령어 실행 전에 먼저 설정하세요:
SKILL_DIR="${CLAUDE_SKILL_DIR:-$HOME/.claude/skills/preview}"
[ -f "$SKILL_DIR/scripts/md-to-preview.py" ] || SKILL_DIR="$(cd "$(dirname "$(find "$HOME/.claude/skills" .claude/skills -path '*/preview/scripts/md-to-preview.py' 2>/dev/null | head -1)")/.." && pwd)"
echo "$SKILL_DIR"
- Python 3.9 이상만 필요하며, 표준 라이브러리만 사용합니다. pip 설치가 필요 없습니다.
- macOS는
python3를 사용하고, Windows에서python3명령어가 없으면python또는py를 사용하세요. - 스킬 폴더를 찾을 수 없으면 사용자에게 알리고
preview폴더가~/.claude/skills/아래에 있는지 확인하도록 안내하세요. 자체적으로 다른 댓글 기능을 구현하지 마세요.
| 파일 | 용도 |
|---|---|
scripts/md-to-preview.py | 주요 생성기: md → 미리보기 페이지 |
scripts/convert/inject.py | 이미排版된 HTML에 댓글 기능만 추가 |
scripts/convert/visuals.py, flow.py, tables.py | 시각 컴포넌트, 순서도, 테이블 변환 (생성기가 자동 호출) |
assets/preview-comment-overlay.html | 텍스트 선택형 댓글 인터페이스 |
assets/preview-tokens.css | 색상, 글꼴, 간격; 외형 변경은 여기서 |
assets/fonts/ | 내장 글꼴 Noto Sans TC, Geist, Geist Mono (SIL OFL 라이선스) |
assets/example.md | 전체 예시: 가상의 수주 제안서, 모든 컴포넌트 사용 |
규칙 1: 댓글은 항상 '텍스트 선택형'
사용자가 '댓글 추가', '댓글 버전'이라고 말하면, 이는 Google Docs처럼 '임의의 텍스트 선택 → 댓글 달기'를 의미합니다. 각 단락 옆에 입력 상자를 두는 방식이 아닙니다. 이 스킬의 댓글 인터페이스는 텍스트 선택형이며, 바로 사용하세요. 따로 만들지 마세요.
규칙 2: 먼저 다시 쓰고, 페이지 생성
먼저 페이지 유형 구분
| 유형 | 예시 | 처리 방법 |
|---|---|---|
| 설명형 | 계획, 제안, 보고서, 비교, 상대방이 결정해야 할 페이지 | 아래 작성법대로 읽기 좋게 다시 써서 페이지 생성. 작업 원고를 생성기에 직접 넣지 마세요 |
| 원문 검토형 | 계약서, 완성 카피, 속기록, 고객이 준 원고 | 내용 하나도 수정하지 않고 페이지 생성. --no-lint 옵션 사용. 맨 앞에 > [!결론]으로 이 페이지가 무엇을 검토할지 설명만 추가 가능 |
설명형 작성법
- 첫 화면에서 설명 완료: 맨 앞에
> [!결론]으로 결론을 한 문장으로 요약하고, 이어서> [!당신의 결정]으로 독자가 해야 할 일을 나열합니다. 배경 정보는 뒤에 두어 독자가 스크롤하지 않아도 결정할 수 있게 합니다. - 한 가지는 한 번만: 결론 상자에서 이미 말한 내용은 본문에서 다시 말하지 않습니다. 그림이나 표로 설명한 내용은 아래 단락에서 다시 서술하지 않습니다. '요약' 단락을 쓰지 마세요.
- 백화(평이한 언어): 독자가 일상적으로 쓰는 용어를 사용합니다. 전문 용어는 처음 등장할 때 비유를 사용하거나
> [!쉬운 말]로 한 줄 설명을 추가합니다. - 그릴 수 있으면 쓰지 않는다: 먼저 '이 단락은 어떤 관계를 설명하는가'를 판단하고, 아래 표에서 적절한 컴포넌트를 선택합니다. 순수 텍스트는 한 단락 최대 세 줄; 각
##단락에 최소 하나의 시각 컴포넌트 또는 표를 포함합니다. - 짧게: 한 문장에 하나의 핵심. '다시 말해', '즉', '주목할 점은' 등의 도입 문구를 삭제합니다.
- 삭제하는 것은 중복이지 정보가 아니다: 숫자, 날짜, 이름, 결과는 하나도 빼거나 바꾸면 안 됩니다.
시각 컴포넌트 빠른 참조
몇 줄의 짧은 구문으로 작성하며, 그림은 생성기가 그립니다. 구분은 전각 |를 사용하고 화살표는 →를 사용합니다. 전체 예시는 assets/example.md를 참조하세요.
| 이 단락이 설명하는 것 | 컴포넌트 | 구문 |
|---|---|---|
| 기존 vs 신규, 현재 vs 개선 후 | 대조 | ```대조: 첫 줄 현재 → 개선 후, 이후 각 줄 항목|기존 → 신규 |
| 시스템 구성, 데이터 흐름 | 아키텍처 | ```아키텍처: 각 줄 한 레이어 레이어명|상자, 상자; 레이어 내 순서는 甲 → 乙; 두 레이어 사이에 ↓ 설명 한 줄 삽입 가능 |
| 언제 무슨 일이 발생 | 타임라인 | ```타임라인: 각 줄 시간|제목|설명; 줄 앞 ✅ 완료, 👉 현재 |
| 순서, 작업 단계, 인과 사슬 | 단계 | ```단계: 각 줄 제목|설명, 자동 번호 매김; 4단계 이하 가로 배치, 5단계 이상 세로 배치 |
| 몇 가지 핵심 숫자 | 숫자 | ```숫자: 각 줄 숫자 단위|레이블|작은 주석; 단위와 숫자 사이에 공백 한 칸을 넣으면 작은 글씨로 표시 |
| 여러 옵션, 역할 분담, 나열 항목 | 카드 | ```카드 (또는 옵션, 분담): 각 줄 제목|한 줄|한 줄; 줄 앞 ★ 권장 옵션 표시 |
| 다열 비교 | 표 | 일반 md 표. 헤더에 '기존/이전'과 '개선 후/신규/권장'이 함께 있을 때, 기존 열은 자동 회색, 신규 열은 연두색 |
| 분기 있는 프로세스 | 프로세스 카드 | ASCII 또는 mermaid 플로우차트 (graph/flowchart의 TD, LR); 변환 실패 시 원본 유지 |
| 결론, 독자 결정, 주의, 위험 | 강조 상자 | > [!결론] 제목, 다음 줄부터 > 내용. 사용 가능: 결론, 당신의 결정, 주의, 위험, 완료, 쉬운 말, 설명 |
| 상태 | 색상 라벨 | 인라인 {초록:완료} {노랑:대기중} {빨강:막힘} {파랑:진행중} {회색:안 함} |
| 문장 내 키워드 | 강조선 | ==키워드==, 단락당 최대 한 곳 |
- 색상은 고정된 의미를 가집니다: 파랑은 결론과 정보, 초록은 완료와 개선 후, 노랑은 주의와 대기, 빨강은 위험과 막힘. '당신의 결정' 상자는 페이지 전체에 하나만 배치합니다.
- 구문이 잘못되어도 페이지가 깨지지 않고 회색 배경의 코드 블록으로 표시됩니다. 생성 후 그림이어야 할 부분이 여전히 회색 배경인지 확인하세요.
- 순서나 인과 관계가 있으면 단계, 타임라인을 사용하고, 서로 관련이 없으면 카드를 사용하세요.
- 그림 속 텍스트도 실제 텍스트이므로 선택하여 댓글을 달 수 있습니다.
레이아웃 검사
페이지 생성 시 자동으로 '레이아웃 검사'가 실행됩니다: 시작 부분에 결론 상자 없음, 특정 단락이 너무 긴 텍스트로만 구성, 시각 컴포넌트 부족, 반복 표현, 줄표, 동일 내용 반복 등. 경고가 있으면 md를 수정하고 다시 실행하여 '레이아웃 검사: 통과'가 나올 때까지 반복합니다. 원문 검토형은 --no-lint를 사용합니다.
리소스 절약
- 그림은 항상 짧은 구문을 사용하며, HTML이나 SVG를 직접 작성하거나 별도 이미지를 생성하지 않습니다.
- 내용을 변경하려면 md를 수정하고 다시 실행하며, 출력된 HTML을 직접 수정하지 마세요.
- 매우 긴 목록은
--fold "3"옵션으로 접을 수 있습니다.
규칙 3: 항상 생성기 실행
- 미리보기 페이지는 항상
scripts/md-to-preview.py(md 소스) 또는scripts/convert/inject.py(이미排版된 HTML) 으로 생성합니다. CSS를 직접 작성하거나 댓글 기능을 직접 구현하지 마세요. - 외형을 변경하려면
assets/preview-tokens.css를 수정하고 생성기를 다시 실행하세요.
실행 흐름
Step 1: 소스 및 신원 확인
대화에서 판단하고, 판단되지 않으면 질문:
- 무엇을 미리보기로 만들까요? (대화에서 방금 작성한 내용, 사용자가 제공한 파일)
- 누가 댓글을 달까요? 신원 기본값은
나,방문자. 고객에게 보여줄 경우고객,나등으로 변경 (첫 번째가 기본 신원).
소스가 대화 내용인 경우, 먼저 md 파일로 저장합니다. 사용자의 현재 작업 폴더(없으면 바탕화면의 미리보기 폴더)에 저장하며, 파일명은 내용을 한국어로 설명하는 이름, 예: 제안-예시-고객.md.
Step 2: 페이지 생성
소스가 md인 경우 (가장 흔함):
python3 "$SKILL_DIR/scripts/md-to-preview.py" "<소스>.md" "<출력>.html" \
--identities "나,방문자" --badges "초안,2026-10-19"
| 매개변수 | 역할 |
|---|---|
--identities | 신원 목록, 쉼표로 구분, 첫 번째가 기본값 |
--badges | 제목 아래 작은 회색 태그, 쉼표로 구분. 제공하지 않으면 표시 안 함 |
--key | 브라우저에 댓글을 저장할 때 사용할 이름. 페이지마다 고유해야 함. 제공하지 않으면 출력 파일명 사용 |
--title | 문서 제목. 제공하지 않으면 md의 첫 # 제목 사용 |
--fold "3,4" | 지정한 헤딩 레벨을 접을 수 있는 단락으로 변환. 긴 페이지에 사용 |
--no-lint | 레이아웃 검사 생략 (계약서, 완성 원고 등에 사용) |
--no-overlay | 댓글 기능이 없는 깔끔한 버전 |
--icon | 탭 아이콘의 문자나 이모지. 제공하지 않으면 제목의 첫 글자 사용 |
--fonts copy/link/none | 글꼴 처리, 기본값 copy |
글꼴: 기본적으로 출력 HTML 옆에 preview-fonts/ 폴더가 생성됩니다. 🚨 다른 사람에게 전달할 때는 HTML과 preview-fonts/ 폴더를 함께 압축해야 합니다. HTML만 전달하면 시스템 글꼴로 표시됩니다 (사용 가능하지만 더 보기 어렵습니다).
이미지: md에서 독립적인 단락으로 존재하는 는 설명이 포함된 이미지로 변환되며, 경로는 출력 HTML을 기준으로 상대 경로입니다.
소스가 이미排版된 HTML인 경우 (예: 직접 만든 제안 페이지): 레이아웃을 변경하지 않고 댓글 기능만 추가합니다.
python3 "$SKILL_DIR/scripts/convert/inject.py" "<페이지>.html" -o "<페이지>-댓글-버전.html" --identities "나,고객"
-o는 새 파일이어야 하며, 도구가 소스를 덮어쓰지 않습니다.- 페이지에 이미 댓글 기능이 있고 새 버전으로 교체하려면
--replace를 추가하세요.
Step 3: 사용자에게 열어주기
시스템 기본 브라우저로 엽니다:
# macOS
open "<출력>.html"
# Windows (Claude 터미널이 Git Bash면 start 사용; PowerShell은 Start-Process "<출력>.html" 사용)
start "" "<출력>.html"
# Linux
xdg-open "<출력>.html"
사용자에게 세 가지를 알려주세요:
- 아무 텍스트나 선택하면 '댓글 추가'가 나타납니다.
- 체크박스는 직접 클릭하여 선택할 수 있습니다.
- 검토 후 오른쪽 상단의 '전체 복사'를 누르면 내용을 대화에 붙여넣을 수 있습니다.
Step 4 (선택): 고객에게 검토 요청
- HTML과 옆의
preview-fonts/폴더를 함께 zip으로 압축하여 고객에게 전송하고, 압축을 푼 후 HTML을 더블 클릭하여 열도록 안내합니다. - 신원은 고객의 역할로 설정합니다. 예:
--identities "고객,나". - 댓글은 고객의 브라우저에 저장되며 자동으로 동기화되지 않습니다. 고객이 검토 후 '전체 복사'를 눌러 텍스트를 이메일이나 메시지로 보내도록 요청하세요.
체크 확인
사용자가 일련의 항목을 하나씩 결정해야 하고, 옵션이 고정된 경우 체크박스를 만드세요. 사용자가 타이핑하여 답변하도록 요구하지 마세요. 예: 기능 도입 여부, 자료 선택, 출시 전 점검 목록. 옵션이 한두 개이거나 이유를 설명해야 하는 경우에는 직접 질문하거나 텍스트 선택형 댓글을 사용하세요.
작성 방법
md에서 작업 목록 형식으로 작성하면 생성기가 클릭 가능한 체크박스로 변환합니다:
### 반드시 할 것
- [x] 주문 폼 (고객이 작성하면 자동으로 데이터베이스에 저장)
- [ ] 일정 캘린더 (각 직원은 자신의 일정만 확인)
- [ ]미체크,- [x]기본 체크.- 각 그룹은 자신의 제목 아래에 배치합니다 (
##또는###): 내보낼 때 '가장 가까운 이전 제목'으로 그룹화합니다. - 각 항목은 이름과 한 줄 설명을 포함하여 독립적으로 이해할 수 있어야 하며, '예', '아니오'만 쓰지 마세요.
- 같은 제목 아래에 동일한 옵션 텍스트가 두 번 있으면 안 됩니다.
사용자 쪽에서 발생하는 동작
- 체크 상태는 브라우저에 저장되며 새로 고침해도 유지됩니다. '초기화' 버튼은 댓글만 지우고 체크는 지우지 않습니다.
- '전체 복사'를 누르면 맨 앞에 다음 내용이 추가됩니다:
## 체크 결과 (2/5 체크됨)
### 범위 확인 › 반드시 할 것
- [x] 주문 폼 (고객이 작성하면 자동으로 데이터베이스에 저장)
- [ ] 일정 캘린더 (각 직원은 자신의 일정만 확인)
체크 결과를 받았을 때
- 먼저 체크 결과를 그대로 파일로 저장합니다. 이 결과를 기준으로 작업하며, 기억에 의존하지 마세요.
- 체크되지 않은 항목은 수행하지 않거나 원래대로 유지합니다. 스스로 판단을 추가하지 마세요.
- 같은 그룹에서 상충되는 옵션이 체크된 경우, 사용자에게 확인합니다.
- 외부에 영향을 미치는 작업 (메일 발송, 파일 삭제, 출시)은 최종 목록을 먼저 제시하고 사용자가 '실행'을 말한 후에 진행합니다.
'댓글 통합' 수신 시 적용 방법
사용자가 '전체 복사'를 눌러 붙여넣은 내용은 다음과 같습니다: 각 댓글에는 선택된 원문 (인용문), 위치 (단락 제목), 앞뒤 문맥, 댓글 내용이 포함됩니다.
건별 해석
| 댓글 형태 | 해석 |
|---|---|
| 동사 없이 새로운 텍스트 한 문장만 | 대체: 인용문을 댓글 텍스트로 교체 |
| '삭제', '제거' | 인용문 단락 삭제 (인용문 범위만) |
| '추가', '보충', '아래에 하나 더' | 신규: 인용문 근처에 내용 추가 |
| 설명형 ('~할 수 있나요?', '~했으면 좋겠어요') | 요청에 따라 수정 |
| 모호함, 두 가지로 해석 가능 | 변경량이 가장 적은 방법 선택. 보고 시 어떤 선택을 했는지 명확히 설명 |
- '위치'와 '앞뒤 문맥'을 사용하여 올바른 위치를 찾은 후 수정합니다. 동일한 텍스트가 페이지에 여러 번 나타나는 경우, 문맥을 사용하여 한 곳만 수정되는지 확인합니다.
- 같은 라운드의 댓글이 이전 라운드와 중복될 수 있습니다. 먼저 이미 수정된 부분과 비교합니다.
적용, 재실행, 다시 열기
- md 원본을 수정한 후 **동일한 명령어와 동일한
--key**로 생성기를 다시 실행합니다. 출력 HTML을 직접 수정하지 마세요 (다시 실행 시 덮어쓰기됩니다). 동일한 key를 사용해야 이전 댓글이 유지됩니다. - 페이지를 다시 열어 사용자에게 보여줍니다.
- 보고: 건별로 '어느 댓글 → 무엇을 변경했는지'를 나열하고, 모호한 경우 선택한 내용을 표시합니다.
기술 메모 (Claude용, 사용자에게 설명할 필요 없음)
- 댓글 앵커는 '선택된 텍스트 + 앞뒤 문맥'을 사용합니다. 내용이 약간 변경되어도 위치를 다시 찾을 수 있으며, 찾을 수 없으면 '원문 변경됨'으로 표시합니다.
- 하이라이트는 브라우저의 CSS Custom Highlight API를 사용하여 페이지 구조를 변경하지 않습니다. Chrome, Edge, Safari 최신 버전 모두 지원합니다. 지원하지 않는 브라우저에서는 노란색 하이라이트가 표시되지 않지만 사이드바 댓글은 정상 작동합니다.
- 댓글과 체크 상태는 브라우저 localStorage에 저장됩니다. 페이지마다 다른
--key를 사용해야 하며, 그렇지 않으면 서로 다른 페이지의 댓글이 섞입니다. - 댓글 인터페이스 로드 후
window.PreviewComments제공:.refresh()하이라이트 다시 위치 지정,.data()모든 댓글 가져오기,.exportMd()내보낸 마크다운 반환. - 페이지 자체 팝업의 z-index는 10400 미만이어야 댓글 버튼이 가려지지 않습니다.
