Doc Review Skill(文書レビュースキル)
記事や文書を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はビルド成果物です — 再デプロイ時にはソースファイルから再生成し、直接編集しないでください
ワークフロー
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>
デプロイスクリプトは自動的に以下を実行します:
- 専用のD1データベース
review-<project-name>を作成(プロジェクトごとに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>(シークレット更新 + 再デプロイ + meta.json更新を自動実行) - 再デプロイ時にパスワードの再指定は不要(シークレットはデプロイ間で永続化)
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を渡して元のパスワードを維持する必要があります。そうしないと新しいパスワードが生成され、古いシークレットが上書きされます
⚠️ 再デプロイは同じプロジェクト名を使用する必要があります。名前を変更すると新しいページ+新しい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>
3つのステップをすべて実行して初めてクリーンアップ完了です。
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— ナレッジベースやその他のパスにある.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の無料枠: 1日あたり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>第一段階の推論...</li>
<li>第二段階の推論...</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— 長文分析スタイル(セリフ本文+サンセリフ見出し、暖かいグレーの背景、深いブルーグレーのアクセント、740pxの狭いカラム)。深い分析、研究レポートに最適。特徴:コールアウトボックス、パスカード、推論チェーン、アクションアイテム。magazine— 雑誌長文スタイル(Playfair Display見出し+DM Sans本文、ダークなヒーローヘッダー、レッドアクセント、「Section 01」の番号付け、***の区切り線)。インパクトのあるエディトリアルピース、視覚的に印象的なレポートに最適。Google Fontsが必要。swiss— スイス国際主義スタイル(IBM Plex Mono本文+Instrument Serif見出し、純白、黒+赤+青、グリッドレイアウト、900px)。超クリーンで合理的、エンジニアリング的なドキュメントに最適。Google Fontsが必要。refined— 高級感のある洗練スタイル(Cormorant Garamondセリフ本文+Outfitサンセリフラベル、パーチメントテクスチャのクリーム色の背景、ゴールド+セージグリーン+ローズ、中央揃えレイアウト、700px)。プレミアムホワイトペーパー、エグゼクティブブリーフに最適。Google Fontsが必要。
テーマの選択
- ユーザーがテーマを指定した場合(例:「グレーのやつ」「editorialスタイル」、「magazineスタイル」「雑誌風」「黒いの」、「swissスタイル」「白いの」「ミニマリスト」、「refined」「ゴールド」「高級」「fancy」)、そのテーマを使用します。
- ユーザーが指定しない場合、コンテンツタイプに基づいて自動選択:
editorial: 深い分析、長文の議論、学校/製品の比較、調査レポート、正式なレポート、評価 — デフォルトの選択magazine: 劇的なビジュアル表現が効果的なインパクトのあるエディトリアルピースswiss: 超クリーンで合理的、エンジニアリング的なドキュメント、技術仕様、比較、データサマリーrefined: プレミアムホワイトペーパー、エグゼクティブブリーフ、高級感のあるドキュメント、重要な分析
- 不明な場合は、
editorialをデフォルトとします。