문서 검토 스킬은(는) 무엇을 하나요?
문서/기사를 Cloudflare Pages에 배포하여 인라인 텍스트 주석을 지원합니다. 검토자는 텍스트를 선택하고 댓글을 추가합니다. 댓글은 Cloudflare D1에 저장됩니다. 에이전트는 피드백을 읽고 반복 작업할 수 있습니다. 이 스킬은 항상 비밀번호로 보호됩니다.
사전 요구 사항
- Cloudflare 자격 증명:
$HOME/.openclaw/credentials/cloudflare.json - Cloudflare API 토큰에 D1 편집 권한이 있어야 함
- D1 데이터베이스는 deploy.sh에 의해 자동 생성됨 — DB 매개변수를 수동으로 생성하거나 전달하는 것을 금지
주요 규칙
- 프로젝트 이름은
-review로 끝나야 함 — deploy.sh에서 적용 - 각 검토 페이지는 독립적인 D1 데이터베이스를 가짐 — 명명 규칙
review-<project-name>, 자동 생성, 재사용 금지 - 지속성 디렉토리:
$HOME/.openclaw/published-content/<project-name>/— meta.json, content.html, index.html 저장 - content.html은 빌드 산출물 — 재배포 시 원본 파일에서 다시 생성하며, content.html을 직접 수정하지 말 것
워크플로우
1. 검토를 위한 배포 (최초 게시)
- 원본 파일을 확인하고, 순수 시맨틱 HTML 콘텐츠를 생성합니다 (아래 HTML 콘텐츠 규칙 참조) →
content.html로 저장 - render.js를 실행하여 테마로 감쌉니다 →
index.html생성:node references/render.js \ --input /tmp/<project-name>/content.html \ --output /tmp/<project-name>/index.html \ --theme editorial - 배포 (주석 주입 + D1 생성은 완전 자동):
bash scripts/deploy.sh <project-name> /tmp/<project-name> - 배포 후 즉시 meta.json 업데이트 (deploy.sh가 초기 meta.json을 자동 생성하며, 에이전트는 원본 파일 정보를 보완해야 함):
python3 -c " import json meta_path = '$HOME/.openclaw/published-content/<project-name>/meta.json' with open(meta_path) as f: meta = json.load(f) meta['source'] = '<원본 파일 경로 (예: /path/to/your/source/file.md)>' meta['sourceType'] = '<markdown|pdf|text|generated>' meta['theme'] = '<실제로 사용된 테마>' with open(meta_path, 'w') as f: json.dump(meta, f, indent=2, ensure_ascii=False) "
비밀번호 보호 (사용자 지정 비밀번호)
bash scripts/deploy.sh <project-name> /tmp/<project-name> --password <password>
deploy.sh 스크립트는 자동으로:
review-<project-name>이라는 전용 D1 데이터베이스를 생성 (프로젝트당 1:1, 재사용 안 함)- 주석 + 댓글 테이블 생성
references/annotations-api.js에서functions/api/annotations.js로 복사references/middleware-template.js에서functions/_middleware.js로 복사wrangler pages secret put을 통해PAGE_PASSWORD설정 (비밀번호는 소스 코드에 절대 저장되지 않음)- D1 바인딩이 포함된
wrangler.toml생성 - content.html, index.html, meta.json을
$HOME/.openclaw/published-content/<project-name>/에 저장
⚠️ db-name 또는 db-id를 수동으로 전달하는 것을 금지합니다. 스크립트가 자동으로 관리하며, 각 검토 페이지가 독립적인 D1 데이터베이스를 가지도록 보장합니다.
비밀번호 관리:
- 최초 배포:
--password매개변수로 지정하거나 자동 생성 - 비밀번호는 Cloudflare Secret에 저장되며, meta.json이나 소스 코드에 저장되지 않음
- 비밀번호 변경:
deploy.sh <project-name> --change-password <new-password>(자동으로 secret 업데이트 + 재배포 + meta.json 업데이트) - 재배포 시 비밀번호를 다시 설정할 필요 없음 (secret은 배포 간에 유지됨)
2. 피드백 읽기
모든 주석과 댓글을 D1에 쿼리합니다 (DB 이름은 항상 review-<project-name>):
npx wrangler d1 execute review-<project-name> --remote --command "
SELECT a.text as highlighted, c.author, c.text as comment, c.created_at
FROM comments c JOIN annotations a ON c.annotation_id = a.id
ORDER BY c.created_at
"
피드백을 사용자에게 테이블 형식으로 제시합니다.
3. 반복 작업 (재배포)
사용자가 검토 피드백에 따라 변경을 요청하는 경우:
$HOME/.openclaw/published-content/<project-name>/meta.json을 읽습니다 — source 경로와 sourceType 확인- D1 피드백을 읽습니다 (섹션 2와 동일)
- sourceType에 따라 업데이트 방법 결정:
markdown/text:source경로에서 원본 파일을 다시 읽음 → content.html 재생성pdf: 원본 파일이 있으면 다시 추출, 없으면$HOME/.openclaw/published-content/<project-name>/content.html사용generated:$HOME/.openclaw/published-content/<project-name>/content.html을 기본으로 수정
- 동일한 테마로 렌더링 →
index.html - 완전히 동일한 프로젝트 이름으로 재배포:
bash scripts/deploy.sh <project-name> /tmp/<project-name>- 동일한 프로젝트 이름 → 동일한 DB → 주석 데이터 유지
- 재배포 시 원래 비밀번호를 유지하려면 반드시
--password를 전달해야 합니다. 그렇지 않으면 새 비밀번호가 생성되어 기존 secret을 덮어씁니다.
⚠️ 재배포는 동일한 프로젝트 이름을 사용해야 합니다. 이름을 바꾸면 새 페이지 + 새 DB가 생성되어 이전 데이터가 손실됩니다.
처리된 주석은 자동으로 사라집니다 (새 페이지에서 강조 표시된 텍스트가 더 이상 일치하지 않음).
4. 정리 (제거)
프로젝트 삭제 시 반드시 D1 데이터베이스와 로컬 지속성 디렉토리를 함께 정리하여 잔여물이 남지 않도록 해야 합니다.
# 1. Pages 프로젝트 삭제
npx wrangler pages project delete <project-name>
# 2. 해당 D1 데이터베이스 삭제 (명명 규칙: review-<project-name>)
npx wrangler d1 delete review-<project-name>
# 3. 로컬 지속성 디렉토리 삭제
rm -rf $HOME/.openclaw/published-content/<project-name>
세 단계를 모두 완료해야 정리가 완료됩니다.
meta.json 스키마
{
"type": "review",
"project": "my-report-review",
"source": "/path/to/your/source/file.md",
"sourceType": "markdown",
"theme": "editorial",
"dbName": "review-my-report-review",
"dbId": "uuid-here",
"created": "2026-04-12T13:20:00+08:00",
"lastDeployed": "2026-04-12T15:30:00+08:00"
}
sourceType 값:
markdown— knowledge-base 또는 다른 경로의 .md 파일 (가장 일반적)pdf— PDF 파일text— 일반 텍스트 파일generated— 대화에서 직접 생성, 소스 파일 없음
환경 설정
모든 wrangler 명령어에 필요:
source <(python3 -c "
import json
with open('$HOME/.openclaw/credentials/cloudflare.json') as f:
c = json.load(f)
print(f'export CLOUDFLARE_ACCOUNT_ID={c[\"account_id\"]}')
print(f'export CLOUDFLARE_API_TOKEN={c[\"api_token\"]}')
")
참고 사항
- 비밀번호는 Cloudflare Secret (PAGE_PASSWORD)으로 저장되며, 소스 코드나 meta.json에 절대 저장되지 않음
- 댓글은 기본적으로 작성자 이름 "Reviewer"로 저장됨 (로그인 불필요)
- D1 무료 티어: 일 500만 회 읽기, 10만 회 쓰기 — 충분함
- 주석 매칭은 텍스트 기반이며, 원본 텍스트가 변경되면 기존 강조 표시는 자연스럽게 사라짐
- 지속성 상태는
$HOME/.openclaw/published-content/<project-name>/에 위치 — 모든 에이전트 간 공유 - 테마 파일은
cloudflare-pages에서 동기화됨 — 여기서themes/또는render.js를 직접 편집하지 말 것.cloudflare-pages/references/에서 수정한 후bash scripts/sync-themes.sh(cloudflare-pages 스킬에서) 실행
HTML 콘텐츠 규칙
검토 페이지를 위한 HTML 콘텐츠를 생성할 때는 다음 규칙을 엄격히 따라야 합니다:
시맨틱 HTML만 사용
- 순수 시맨틱 HTML 출력 —
<style>태그, 인라인 스타일,<html>/<head>/<body>래퍼 없음 - 표준 태그 사용:
<h1>-<h4>,<p>,<table>,<ul>/<ol>,<blockquote>,<details>,<hr>
구조적 규칙
<table>— 비교, 점수, 데이터 그리드<blockquote>— 핵심 요점 또는 중요한 인용문<details><summary>— 접을 수 있는 섹션<div class="toc">— 목차<p class="meta">— 메타데이터 줄 (날짜, 작성자 등)<div class="footer">— 바닥글 텍스트
배지 클래스
<span class="badge badge-green">통과</span>— 긍정적<span class="badge badge-yellow">경고</span>— 주의<span class="badge badge-red">실패</span>— 부정적
컴포넌트 라이브러리 (중요 — 반드시 사용)
content.html을 생성할 때 다음 컴포넌트를 적극적으로 사용하여 콘텐츠에 시각적 계층을 부여해야 합니다. 순수 <p> + <ul>의 평면적인 HTML은 불합격입니다.
콜아웃 상자 — 핵심 정보 강조
<div class="callout">기본 콜아웃: 일반적인 중요 정보</div>
<div class="callout callout-conclusion"><strong>결론:</strong> 핵심 판단 및 최종 제안</div>
<div class="callout callout-warning"><strong>참고:</strong> 위험, 우려 사항, 주목해야 할 문제</div>
<div class="callout callout-important"><strong>중요:</strong> 핵심 데이터, 무시할 수 없는 사실</div>
경로 카드 — 옵션/경로 비교
<div class="path-card">
<div class="path-label">방안 A</div>
<p>설명 내용...</p>
</div>
<div class="path-card recommended">
<div class="path-label">방안 B (권장)</div>
<p>설명 내용...</p>
</div>
추론 체인 — 논리적 추론 과정
<div class="reasoning-chain">
<ol>
<li>1단계 추론...</li>
<li>2단계 추론...</li>
<li>따라서 결론 도출...</li>
</ol>
</div>
실행 항목 — 행동 제안
<div class="action-items">
<ol>
<li><strong>단기 (1주 이내):</strong> 구체적 행동...</li>
<li><strong>중기 (1개월):</strong> 구체적 행동...</li>
</ol>
</div>
최종 권장 사항 — 최종 제안 (어두운 블록)
<div class="final-rec">
<p><strong>최종 권장 사항:</strong> 한 문장으로 된 핵심 결론. 문서 마지막에 배치하여 마무리합니다.</p>
</div>
키워드 — 태그
<div class="keywords">
<span class="kw">태그1</span>
<span class="kw">태그2</span>
</div>
섹션 구분선 — 장 구분 (magazine/refined 테마에서 가장 효과적)
<div class="section-divider"><span class="num">Section 01</span></div>
고지 사항 — 문서 마지막 면책 조항
<p class="disclaimer">본 보고서는 AI가 생성했으며 참고용으로만 제공되며 전문적인 조언을 대체하지 않습니다.</p>
콘텐츠 품질 기준
content.html을 생성할 때 반드시:
- 각 h2 섹션에는 최소 1개의 컴포넌트 (callout / path-card / table / reasoning-chain 등)가 포함되어야 함
- 핵심 결론은 반드시 callout-conclusion을 사용해야 하며, 일반 단락에 숨기지 말 것
- 비교가 있으면 path-card 또는 table을 사용하고, 순수 텍스트 나열은 피할 것
- 문서 마지막에는 final-rec가 있어야 함 (내용에 명확한 결론/제안이 있는 경우)
- TOC는 반드시
<div class="toc">로 감싸야 하며,<ul>을 그대로 사용하지 말 것
사용 가능한 테마
editorial— 장문 분석 스타일 (serif 본문 + sans 제목, 따뜻한 회색 배경, 진한 청회색 강조, 740px 좁은 컬럼). 심층 분석, 연구 보고서에 최적. 특징: callout 상자, path 카드, 추론 체인, 실행 항목.magazine— 잡지 장문 스타일 (Playfair Display 제목 + DM Sans 본문, 어두운 히어로 헤더, 빨간색 강조, "Section 01" 번호 매기기, *** 구분선). 시각적 임팩트가 강한 에디토리얼 기사에 최적. Google Fonts 필요.swiss— 스위스 국제주의 스타일 (IBM Plex Mono 본문 + Instrument Serif 제목, 순수 흰색, 검정+빨강+파랑, 그리드 레이아웃, 900px). 초깔끔하고 합리적이며 엔지니어링 느낌의 문서에 최적. Google Fonts 필요.refined— 고급스러운 정교한 스타일 (Cormorant Garamond serif 본문 + Outfit sans 레이블, 크림색 배경에 양피지 질감, 금색 + 세이지 그린 + 장미색, 중앙 정렬, 700px). 프리미엄 백서, 임원 브리핑에 최적. Google Fonts 필요.
테마 선택
- 사용자가 특정 테마를 지정한 경우 (예: "회색인 것"/"회색 그거"/"editorial 스타일", "magazine 스타일"/"잡지 풍"/"검은 것", "swiss 스타일"/"흰 것"/"미니멀", "refined"/"금색"/"정교"/"fancy"), 해당 테마를 사용합니다.
- 사용자가 지정하지 않은 경우, 콘텐츠 유형에 따라 자동 선택:
editorial: 심층 분석, 장문 논증, 학교/제품 비교, 연구 브리핑, 공식 보고서, 평가 — 기본 선택magazine: 드라마틱한 시각적 표현이 필요한 고임팩트 에디토리얼swiss: 초깔끔하고 합리적이며 엔지니어링 스타일의 문서, 기술 명세, 비교, 데이터 요약refined: 프리미엄 백서, 임원 브리핑, 고급스러운 문서, 중요 분석
- 확실하지 않은 경우
editorial을 기본으로 합니다.