proof について
proofは、人とエージェント向けの共同Markdown編集スキルです。Web APIまたはmacOSのProofアプリを通じて、作成者を記録した編集、コメント、提案を扱います。
主な機能
- 01Web APIで共有ドキュメントを作成・編集
- 02macOS Proofアプリのローカルブリッジに接続
- 03コメントの追加・返信・解決
- 04編集提案の送信・承認・却下
- 05エージェント名を操作に記録
活用シーン
- 01共有Markdownドキュメントのレビュー依頼
- 02構造化されたフィードバックの収集とローカル同期
- 03共同編集で提案やコメントを追跡
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ everyinc/ compound-engineering-plugin --skill proofインストール後、Claude Code で/proofを入力して読み込まれたか確認します。
同梱ファイルreferences/hitl-review.md
詳細
Proof - 共同編集可能なMarkdownエディター
Proofは、人間とエージェント向けの共同編集ドキュメントエディターです。次の2つのモードに対応しています。
- Web API - HTTP経由で共有ドキュメントを作成、編集します(インストール不要)
- Local Bridge - localhost:9847経由でmacOSのProofアプリを操作します
IDと帰属
Proofドキュメントへの書き込みには、すべて帰属情報が必要です。次の2つのフィールドでエージェントのIDを指定します。
- マシンID(すべての操作での
by、X-Agent-Idヘッダー):ai:compound-engineering— 安定した、小文字とハイフンで構成された、機械で解析可能な値です。マーク、イベント、APIレスポンスに表示されます。 - 表示名(
POST /presenceのname):Compound Engineering— 人が読める名前で、Proofのプレゼンスチップとコメント作成者バッジに表示されます。
X-Agent-Idヘッダーを付けてプレゼンスに投稿し、ドキュメントのセッションごとに表示名を一度設定します。Proofは、そのセッション中、この名前をエージェントIDに紐付けます。これらの値は、このスキルを呼び出すすべてのユーザーのデフォルトです。HITLレビュー(references/hitl-review.md)を実行するユーザーは、別のサブエージェントにドキュメントを担当させる場合、異なるidentityペアを渡すことができます。ユーザーが明示的に上書きしない限り、IDは統一されたままにしてください。ai:compoundやその他の場当たり的な値は使用しないでください。
Human-in-the-Loopレビュー・モード
呼び出し元(例:ce-brainstorm、ce-plan)がローカルのMarkdownドキュメントをアップロードし、Proofで構造化された人間のフィードバックを収集して、最終ドキュメントをディスクに同期する必要がある場合は、ループ仕様の全容(呼び出し規約、マークの分類(変更/質問/異議/曖昧)、冪等な取り込み処理、例外ベースの終了報告、同期時のアトミック書き込み)を確認するために、references/hitl-review.mdを読み込んでください。
Web API(共有での主な方法)
共有ドキュメントを作成する
認証は不要です。共有可能なURLとアクセストークンが返されます。
curl -X POST https://www.proofeditor.ai/share/markdown \
-H "Content-Type: application/json" \
-d '{"title":"My Doc","markdown":"# Hello\n\nContent here."}'
レスポンス形式:
{
"slug": "abc123",
"tokenUrl": "https://www.proofeditor.ai/d/abc123?token=xxx",
"accessToken": "xxx",
"ownerSecret": "yyy",
"_links": {
"state": "https://www.proofeditor.ai/api/agent/abc123/state",
"ops": "https://www.proofeditor.ai/api/agent/abc123/ops"
}
}
共有リンクにはtokenUrlを使用してください。_linksには、正確なAPIパスが記載されています。
共有ドキュメントを読み込む
curl -s "https://www.proofeditor.ai/api/agent/{slug}/state" \
-H "x-share-token: <token>"
共有ドキュメントを編集する
すべての操作は POST https://www.proofeditor.ai/api/agent/{slug}/ops に送信します。
注: /api/agent/{slug}/ops のパスを使用してください(作成レスポンスの _links に記載されています)。/api/documents/{slug}/ops は使用しないでください。
保護されたドキュメントの認証:
- ヘッダー:
x-share-token: <token>またはAuthorization: Bearer <token> - トークンは URL パラメーター
?token=xxxまたは作成レスポンスのaccessTokenから取得します。 - ヘッダー:
X-Agent-Id: ai:compound-engineering(プレゼンスに必須。帰属情報を一貫させるため、ops にも含めてください)
ワイヤー形式に関する注意。 /api/agent/{slug}/ops ではトップレベルの type フィールドを使用します。一方、/api/agent/{slug}/edit/v2 では、各エントリに op を含む operations 配列を使用します。混同しないでください。op を /ops に送信すると、422 が返されます。
すべての変更には baseToken が必要です。 各書き込みの直前に /state.mutationBase.token(または /snapshot.mutationBase.token)から読み取り、リクエスト本文に含めてください。BASE_TOKEN_REQUIRED または STALE_BASE が返された場合は、再読み込みして一度だけ再試行してください。references/hitl-review.md の baseToken の手順を参照してください。
Idempotency-Key ヘッダーは、安全な自動再試行のため、すべての変更での使用を推奨します。/state.contract.idempotencyRequired が true の場合は必須です。
テキストにコメントする:
{"type": "comment.add", "quote": "text to comment on", "by": "ai:compound-engineering", "text": "Your comment here", "baseToken": "<token>"}
コメントに返信する:
{"type": "comment.reply", "markId": "<id>", "by": "ai:compound-engineering", "text": "Reply text", "baseToken": "<token>"}
コメントを解決/未解決にする:
{"type": "comment.resolve", "markId": "<id>", "by": "ai:compound-engineering", "baseToken": "<token>"}
{"type": "comment.unresolve", "markId": "<id>", "by": "ai:compound-engineering", "baseToken": "<token>"}
置換を提案する(保留中 — ユーザーが承認または却下する必要があります):
{"type": "suggestion.add", "kind": "replace", "quote": "original text", "by": "ai:compound-engineering", "content": "replacement text", "baseToken": "<token>"}
提案してすぐに適用する(変更履歴に記録されますが確定済み — ユーザーは却下して元に戻せます):
{"type": "suggestion.add", "kind": "replace", "quote": "original text", "by": "ai:compound-engineering", "content": "replacement text", "status": "accepted", "baseToken": "<token>"}
status: "accepted" は、提案マークを作成し、1 回の呼び出しで変更を確定します。このマークは、編集ごとの帰属情報と却下して元に戻す機能を備えた監査証跡として残ります。kind: "insert" | "delete" | "replace" で動作します。
既存の提案を承認または却下する:
{"type": "suggestion.accept", "markId": "<id>", "by": "ai:compound-engineering", "baseToken": "<token>"}
{"type": "suggestion.reject", "markId": "<id>", "by": "ai:compound-engineering", "baseToken": "<token>"}
suggestion.resolve はサポートされていません。代わりに承認または却下を使用してください。
一括書き換え(ドキュメント全体の置換):
{"type": "rewrite.apply", "content": "full new markdown", "by": "ai:compound-engineering", "baseToken": "<token>"}
/edit/v2 によるブロック単位の編集(別のエンドポイントで、形式も異なります):
curl -X POST "https://www.proofeditor.ai/api/agent/{slug}/edit/v2" \
-H "Content-Type: application/json" \
-H "x-share-token: <token>" \
-H "X-Agent-Id: ai:compound-engineering" \
-H "Idempotency-Key: <uuid>" \
-d '{
"by": "ai:compound-engineering",
"baseToken": "mt1:<token>",
"operations": [
{"op": "replace_block", "ref": "b3", "block": {"markdown": "Updated paragraph."}},
{"op": "insert_after", "ref": "b3", "block": {"markdown": "## New section"}}
]
}'
operations 内でサポートされる op の種類:replace_block、insert_before、insert_after、delete_block、replace_range(fromRef と toRef を使用)、find_replace_in_block(occurrence: "first" | "all" を指定)。/snapshot を読み込み、安定したブロック ref ID と mutationBase.token を取得してください。
クライアントが接続中でも編集できます。 /edit/v2、suggestion.add(status: "accepted" を含む)、およびすべてのコメント操作は、コラボレーション中も動作します。LIVE_CLIENTS_PRESENT によりブロックされるのは rewrite.apply のみです。これは処理中の Yjs 編集を上書きしてしまうためです。
処理が行き詰まった場合。 最新の情報を読み込んで一度再試行しても変更が失敗し続ける場合、または読み取り間で状態に不整合が見られる場合は、失敗したリクエスト ID、スラッグ、生のレスポンスを添えて POST https://www.proofeditor.ai/api/bridge/report_bug を呼び出してください。サーバーが情報を補足して、課題を登録します。
既知の制限(Web API)
- ブリッジ形式のエンドポイント(
/d/{slug}/bridge/*)には、クライアントバージョンのヘッダー(x-proof-client-version、x-proof-client-build、x-proof-client-protocol)が必要です。これらがない場合は 426 CLIENT_UPGRADE_REQUIRED が返されます。代わりに/api/agent/{slug}/opsを使用してください。
ローカルブリッジ(macOS アプリ)
Proof.app が起動している必要があります。ブリッジのアドレスは http://localhost:9847 です。
必須ヘッダー:
X-Agent-Id: claude(プレゼンス用の識別情報)Content-Type: application/jsonX-Window-Id: <uuid>(複数のドキュメントを開いている場合)
主要なエンドポイント
| メソッド | エンドポイント | 目的 |
|---|---|---|
| GET | /windows | 開いているドキュメントの一覧を取得します |
| GET | /state | Markdown、カーソル、単語数を読み取ります |
| GET | /marks | すべての提案とコメントを一覧表示します |
| POST | /marks/suggest-replace | {"quote":"old","by":"ai:compound-engineering","content":"new"} |
| POST | /marks/suggest-insert | {"quote":"after this","by":"ai:compound-engineering","content":"insert"} |
| POST | /marks/suggest-delete | {"quote":"delete this","by":"ai:compound-engineering"} |
| POST | /marks/comment | {"quote":"text","by":"ai:compound-engineering","text":"comment"} |
| POST | /marks/reply | {"markId":"<id>","by":"ai:compound-engineering","text":"reply"} |
| POST | /marks/resolve | {"markId":"<id>","by":"ai:compound-engineering"} |
| POST | /marks/accept | {"markId":"<id>"} |
| POST | /marks/reject | {"markId":"<id>"} |
| POST | /rewrite | {"content":"full markdown","by":"ai:compound-engineering"} |
| POST | /presence | {"status":"reading","summary":"..."} |
| GET | /events/pending | ユーザーの操作をポーリングします |
プレゼンスのステータス
thinking、reading、idle、acting、waiting、completed
ワークフロー:共有ドキュメントをレビューする
https://www.proofeditor.ai/d/abc123?token=xxx のようなProof URLが渡された場合:
- URLからスラッグ(
abc123)とトークンを抽出します - API経由でドキュメントの状態を読み取ります
- opsエンドポイントを使ってコメントを追加するか、編集を提案します
- 作成者は変更をリアルタイムで確認できます
# Read
curl -s "https://www.proofeditor.ai/api/agent/abc123/state" \
-H "x-share-token: xxx"
# Get baseToken for the next mutation
BASE=$(curl -s "https://www.proofeditor.ai/api/agent/abc123/state" \
-H "x-share-token: xxx" | jq -r '.mutationBase.token')
# Comment
curl -X POST "https://www.proofeditor.ai/api/agent/abc123/ops" \
-H "Content-Type: application/json" \
-H "x-share-token: xxx" \
-H "X-Agent-Id: ai:compound-engineering" \
-d "$(jq -n --arg base "$BASE" '{type:"comment.add",quote:"text",by:"ai:compound-engineering",text:"comment",baseToken:$base}')"
# Suggest edit (tracked, pending)
curl -X POST "https://www.proofeditor.ai/api/agent/abc123/ops" \
-H "Content-Type: application/json" \
-H "x-share-token: xxx" \
-H "X-Agent-Id: ai:compound-engineering" \
-d "$(jq -n --arg base "$BASE" '{type:"suggestion.add",kind:"replace",quote:"old",by:"ai:compound-engineering",content:"new",baseToken:$base}')"
# Suggest and immediately apply (tracked, committed)
curl -X POST "https://www.proofeditor.ai/api/agent/abc123/ops" \
-H "Content-Type: application/json" \
-H "x-share-token: xxx" \
-H "X-Agent-Id: ai:compound-engineering" \
-d "$(jq -n --arg base "$BASE" '{type:"suggestion.add",kind:"replace",quote:"old",by:"ai:compound-engineering",content:"new",status:"accepted",baseToken:$base}')"
ワークフロー:新しいドキュメントを作成して共有する
# 1. Create
RESPONSE=$(curl -s -X POST https://www.proofeditor.ai/share/markdown \
-H "Content-Type: application/json" \
-d '{"title":"My Doc","markdown":"# Title\n\nContent here."}')
# 2. Extract URL and token
URL=$(echo "$RESPONSE" | jq -r '.tokenUrl')
SLUG=$(echo "$RESPONSE" | jq -r '.slug')
TOKEN=$(echo "$RESPONSE" | jq -r '.accessToken')
# 3. Bind display name via presence
curl -s -X POST "https://www.proofeditor.ai/api/agent/$SLUG/presence" \
-H "Content-Type: application/json" \
-H "x-share-token: $TOKEN" \
-H "X-Agent-Id: ai:compound-engineering" \
-d '{"name":"Compound Engineering","status":"reading","summary":"Uploaded doc"}'
# 4. Share the URL
echo "$URL"
# 5. Make edits using the ops endpoint (baseToken required)
BASE=$(curl -s "https://www.proofeditor.ai/api/agent/$SLUG/state" \
-H "x-share-token: $TOKEN" | jq -r '.mutationBase.token')
curl -X POST "https://www.proofeditor.ai/api/agent/$SLUG/ops" \
-H "Content-Type: application/json" \
-H "x-share-token: $TOKEN" \
-H "X-Agent-Id: ai:compound-engineering" \
-d "$(jq -n --arg base "$BASE" '{type:"comment.add",quote:"Content here",by:"ai:compound-engineering",text:"Added a note",baseToken:$base}')"
ワークフロー:Proofドキュメントをローカルに取得する
現在のProofドキュメントの状態をローカルのMarkdownファイルに同期します。次の用途で使用します。
- HITLレビューの終了時の同期(
references/hitl-review.mdPhase 5)。ドキュメントがローカルファイルを元に作成された場合 - Proofドキュメントのスナップショットをオンデマンドでディスクに保存する場合(タブを閉じる前、アーカイブ時、引き継ぎ時)
- ライブのProofバージョンに合わせてローカルの作業コピーを更新する場合
SLUG=<slug>
TOKEN=<accessToken>
LOCAL=<absolute-path>
# One read to a temp file — avoids passing markdown through $(...), which would strip trailing newlines.
STATE_TMP=$(mktemp)
curl -s "https://www.proofeditor.ai/api/agent/$SLUG/state" \
-H "x-share-token: $TOKEN" > "$STATE_TMP"
REVISION=$(jq -r '.revision' "$STATE_TMP")
# Atomic write: stream .markdown bytes directly to a temp sibling, then rename.
TMP="${LOCAL}.proof-sync.$$"
jq -jr '.markdown' "$STATE_TMP" > "$TMP" && mv "$TMP" "$LOCAL"
rm "$STATE_TMP"
jq -jr(-jは末尾の改行なし、-rは生の文字列)は、シェル変数を介さずにMarkdownのバイト列を一時ファイルに直接出力するため、末尾の改行がそのまま保持されます。同じファイルシステム内でのmvはアトミックです。書き込み中にクラッシュしても、ファイルが中途半端な状態になるのではなく、元のファイルがそのまま残ります。
取得を直接依頼されていない場合は、書き込む前に確認してください。 別の操作(例:HITLレビューの完了)の副作用としてワークフローが取得を行う場合は、「レビュー済みのドキュメントを<localPath>に同期しますか?」のように、書き込みが行われることを簡潔に伝えて確認します。通知なしの上書きは、ユーザーがそのセッション中にローカルファイルの存在を忘れていたり、明示的に取得を依頼するまではProofを正本として扱うつもりだったりする可能性があり、予期せぬ動作となります。
安全性
- 編集前に
/stateの内容を正とします - コラボレーション中は
edit/v2(ブロックへの直接変更)またはsuggestion.add(変更履歴付きの変更)を使用します。rewrite.applyは、接続中のユーザーがいるとLIVE_CLIENTS_PRESENTによってブロックされるため、クライアントがいない場合に限って使用します - 1回の置換で複数の表セルにまたがらないようにします
- 一貫した変更元の記録のため、すべてのopに
by: "ai:compound-engineering"を指定し、ヘッダーにX-Agent-Id: ai:compound-engineeringを含めます - 変更のたびに新しい
baseTokenを読み取ります。STALE_BASEの場合は再読み込みし、1回だけ再試行します