validating-and-publishing-canvases について
PostHog canvas の検証と公開手順を説明するスキルで、canvas の編集や保守を担当する人向けです。機能宣言、バージョン保護、ビルド確認に加え、必要に応じた下書きのステージングと承認後の公開を扱います。
主な機能
- 01ソースファイルと依存関係を確認
- 02実行機能とネットワーク元を宣言
- 03検証を実行して診断を解消
- 04バージョンを保護して公開・編集
- 05公開後にビルド状態を確認
- 06下書きをステージングして承認後に昇格
活用シーン
- 01新しい canvas プロジェクトを公開
- 02並行変更を保ちながら編集
- 03公開前に下書きをプレビューして確認
MCP 対応
canvas の機能宣言で指定するコネクター呼び出し向けに、PostHog AI(Max)の MCP ツールが記載されています。このスキル自体が MCP 経由で動作するとは説明されていません。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ posthog/ ai-plugin --skill validating-and-publishing-canvasesインストール後、Claude Code で/validating-and-publishing-canvasesを入力して読み込まれたか確認します。
詳細
キャンバスの検証と公開
キャンバスのソースは PostHog に保存され、公開ごとにバージョン管理されます。公開には保護措置が設けられています。各編集は特定のバージョンに基づいており、サーバーは新しい変更を上書きしません。公開するたびにサーバー側のビルドがキューに追加され、キャンバスには最後に成功したビルドが表示されます。
ソースプロジェクト
canvas-source-retrieve の戻り値は次のとおりです。
project—schemaVersion(1)、files(パス → 内容)、entryHtml("index.html")、dependencies(プラットフォームで固定された正確なバージョン)、canvasSdkVersion、capabilities。current_version_id— 編集の基準となるバージョンです。保持してください。公開時に必要です。 一度も公開されていないキャンバスではnullです。初回の公開時には、そのnullを渡してください。
index.html と dependencies は返されたとおりに維持してください。相対パスのソースファイルと、許可されたアセットはプロジェクトに追加できます。自己完結型のモジュールワーカーには ?worker を使用し、バイナリアセットは assets 内の base64 エントリーとして表現してください。新しい npm 依存関係や依存関係のバージョンのずれは検証に失敗します。
機能を宣言する
ホストは実行時に project.capabilities を適用するため、宣言していない ph 呼び出しはビルドには成功しても、レンダリングされたキャンバスでは失敗します。以下を宣言してください。
capabilities.posthog.insights— キャンバスがph.loadInsightに渡すすべてのインサイトの短縮 ID。capabilities.posthog.captureEvents—ph.captureに渡すすべてのイベント名。capabilities.posthog.inlineQueries: true—ph.queryを呼び出す場合。capabilities.posthog.agentRequests: true—ph.agent.requestを呼び出す場合。capabilities.connectors— キャンバスがph.connectors.callを通じて読み取るサードパーティープロバイダーごとに、{ "provider", "tools" }エントリーを 1 つ指定し、そのプロバイダーで呼び出すすべてのツールを列挙します。プロバイダーはネイティブ ID(github)またはmcp:<server host>(mcp:mcp.calendly.com)です。不明なプロバイダー、登録されていないネイティブツール、プライベートな MCP ホストは検証に失敗します。宣言するすべてのツールは、カタログでis_read_only: trueである必要があります。アップストリームのヒントだけではアクセス権は付与されません。コネクターを使用するキャンバスでは、共有状態を宣言できません。capabilities.network.origins—fetch、XMLHttpRequest、外部スタイルシート、画像、フォント、メディアファイル、フレームで使用する HTTPS オリジンをそれぞれ指定します。リモートスクリプトは引き続きブロックされます。パス、認証情報、クエリ、フラグメント、ワイルドカードは含めないでください。ホストはパブリックである必要があります。ループバックアドレスとプライベート IP、intranetのような単一ラベルの名前、および.local、.localhost、.internal、.home.arpaの各サフィックスはすべて拒否されます。そのため、https://localhost:8010のようなローカル開発ホストは、invalid_network_originエラーで検証に失敗します。宣言したオリジンに送信されるデータは PostHog の外部に送られ、昇格前の機能レビューに表示されます。
検証の前に、すべてのソースファイルに含まれる外部 URL のリテラルをすべて洗い出してください。ナビゲーションリンクと ph.openExternal() の URL はナビゲーションとして分類し、ネットワークオリジンを指定する必要はありません。リクエスト URL またはリソース URL ごとに、スキームとホスト、および任意のポートのみを宣言してください。リクエストのリダイレクト先となるオリジンと、スタイルシートがフォントや画像を参照する際に使用するすべてのセカンダリオリジンも含めてください。ある CDN のホスト名が別の CDN のホスト名もカバーすると推測してはいけません。
検証では、宣言されていないリテラル呼び出しとリソース URL が拒否され(capability_missing_* 診断)、公開前に修正できます。動的 URL やリダイレクト先は推測できないため、検証に問題がなくても洗い出しが必要です。
クリーンになるまで検証する
canvas-validate-create は副作用がないため、必要に応じて何度でも呼び出せます。
診断には severity、安定した code、message が含まれます。ファイル固有の問題の場合は、
path と line も含まれます。
error診断があると公開できません。すべて修正してください。よくあるもの:import_not_allowed(通常のインポートは、ソースプロジェクトで返された依存関係に限られます)、forbidden_dynamic_import/forbidden_require/forbidden_inline_script、invalid_path、capability_missing_insight/capability_missing_capture_event/capability_missing_inline_queries/capability_missing_agent_requests/capability_missing_network_origin、dependency_not_admitted/dependency_version_mismatch、platform_token_redeclared(プラットフォームのスタイルシートがすべての要素に設定する Quill トークンと同名の CSS 変数です。そのため値が適用されません。独自の変数には接頭辞を付けてください)、およびパス/サイズの違反です。warning診断があっても公開は妨げられませんが、注意してください。network_fetch/network_xhrは、コードがネットワークに直接アクセスすることを意味します。正確な HTTPS オリジンを宣言するか、phブリッジを使用してください。
公開時のガード
公開するとすぐに反映され、キャンバスの初回バージョンでも、その後の編集でも、変更を保存するデフォルトの方法です。各バージョンには、公開者と作業を行ったタスクが記録されるため、後から履歴を確認できます。ユーザーが下書き、プレビュー、またはレビューの手順を求めた場合に限り、代わりに下書きをステージングします。詳しくは、下の「下書きを作成してから昇格」を参照してください。
公開方法は2つあり、どちらにもガードがあります。
- 編集 —
operationsを指定してcanvas-edit-createを呼び出します。ソースがすでにあるキャンバスへの変更では、これがデフォルトです。 編集の意味はそのベースに依存するため、ここではガードが必須です。 - プロジェクト全体 — 初回バージョンの公開時、またはすべてを置き換えるときに、完全な
projectを指定してcanvas-publish-createを呼び出します。
canvas-edit-create で編集する場合:
- ファイル内の変更には
str_replaceを使います。old_stringには、読み取ったファイルからコピーしたテキストを、前後の数行とともに指定し、完全に一致する箇所が1つだけになるようにします。 たとえば名前を変更する場合など、すべての一致箇所を変更するにはreplace_all: trueを設定します。 - 新しいファイルの作成やファイル全体の書き換えには、完全な
contentを指定してwriteを使います。ファイルを削除するにはdeleteを、移動するにはnew_pathを指定してrenameを使います。 ph.stateスコープなど、新しい機能が必要な変更では、追加分を含む完全な新しい機能(現在の機能と追加分)をcapabilitiesに指定し、同じ編集リクエストで送信します。そのためにcanvas-publish-createに切り替えないでください。- 1つの変更に含まれる操作はすべて、1回の呼び出しにまとめます。操作は順番に適用され、どれか1つでも失敗すると編集全体が拒否されます。
- 400エラーには、失敗した各操作がインデックス付きで示されます。
edit_no_matchにはファイル内で最も近い行が表示され、edit_ambiguous_matchには一致した行が列挙されます。 診断内容をもとに該当する操作を修正し、編集を再送信します。置換が2回続けて失敗した場合は、ファイル全体をwriteしてください。 - レスポンスには新しい
current_version_idが返されます。次の編集ではそれを渡してください。 このセッション中にキャンバスを公開または編集している場合、次の編集の前にcanvas-source-retrieveを呼び出さないでください。ソースはすでに把握しており、キャンバスが変更されたときは409version_conflictで通知されます。
canvas-publish-create でプロジェクト全体を公開する場合:
- 必ず
expected_current_version_idを渡します。これは読み取ったcurrent_version_id(初回公開時は明示的にnull)です。ガードなしで公開すると、同時に行われた編集が気付かないうちに上書きされるおそれがあります。 - 変更内容を説明する短い
promptを含めます。これはバージョン履歴のエントリーのラベルになります。 nameは、キャンバスの名前を変更するとき(例:名前のないキャンバスの初回構築時)にのみ指定します。- 要求された変更ごとに1回公開します。その後ユーザーが別の編集を求めた場合は、ソースを再度読み取って(最新バージョンが進んでいる可能性があります)もう一度公開します。無関係な変更を1つのバージョンにまとめたり、作業途中の状態を細かな編集ごとに公開したりしないでください。
- 429は、チームのビルド容量が一時的に上限に達したことを意味します。約30秒待って同じ公開を再試行してください。何も保存されていません。
レスポンスには新しい current_version_id が返されます。
公開後:ビルドを待つ
公開すると、バージョンのサーバー側ビルドがキューに追加されます。ビルドの準備が整うまでキャンバスは更新されず、結果を見守っている人はいません。確認するのはあなたです。 公開または編集のレスポンスには、すでに build.build_status が含まれています。その値が ready または failed なら、別の呼び出しをせずに対応してください。queued または building の間だけ、数秒おきに canvas-builds-retrieve をポーリングし、キューに追加したビルドが終了状態になるまで待ちます(最長約 2 分)。
queued/building— 処理中です。少し待ってから再度ポーリングしてください。ready— キャンバスのpublished_build_idがこのビルドに進みます(より新しい公開によって先に置き換えられた場合を除きます)。キャンバスに関するタスクは完了です。failed— ビルドのエラー診断を確認し、プロジェクトを修正して再度公開してください。失敗したビルドが最後に成功したビルドに置き換わることはないため、キャンバスには引き続き以前のバージョンが表示されます。ここでタスクを終えると、古いキャンバスが残り、失敗も見過ごされてしまいます。
実行時エラーレポート(レンダリングされたキャンバスで例外が発生したときに作成され、オーサリングタスクに記録されるもの)には、発生元のビルドが記載されています。古いビルド ID のレポートは過去の情報であり、現在のコードの証拠ではありません。対応する前に、直前に公開したビルドと照らし合わせてください。特に、ドキュメントに記載された ph API(例:ph.state)が未定義だというレポートは、そのアーティファクトが古いホストランタイムでビルドされたことを意味します。現在のビルドで置き換えるため、再度公開してください。API やその機能宣言を削除して「修正」してはいけません。
ドラフトを作成してから昇格する
公開は、そのビルドの準備が整った時点で即座に反映されます。これがデフォルトの動作です。ユーザーがプレビューを先に確認したい、公開前にレビューしたい、または明示的に「まだ公開しないで」と依頼した場合にのみ、ドラフトを使用してください。ドラフトは実際にビルドできるバージョンですが、ヘッドになることはありません。誰かがドラフトを昇格するまで、ライブキャンバスには現在のバージョンが引き続き表示されます。これは、コンパイルチェックのみを行い、ビルドもプレビューも生成しない canvas-validate-create とは異なります。
- ステージする — 完全な
projectを指定してcanvas-draft-createを呼び出します(公開時と同じ形式、機能、検証を使用)。ドラフトは何にも基づかず、何とも競合しないため、expected_current_version_idは指定しません。レスポンスには、ドラフトのversion_id、キューに追加されたbuild、およびcapability_wideningが返されます。capability_wideningは、ライブバージョンを超えてドラフトが宣言するインサイト、キャプチャイベント、インラインクエリ、ネットワークオリジンを示します。値が空でない場合、昇格する前にユーザーへ提示してください。これは変更によって新たに付与されるアクセス権です。 - ビルドを待つ — 公開後と同じ方法で、ドラフトのビルドが終了状態になるまで
canvas-builds-retrieveをポーリングします。ビルドに失敗したドラフトは、昇格するのではなく、新しいドラフトをステージして修正します。 - プレビューする —
version_idを指定してcanvas-source-retrieveからドラフトのファイルを読み取ります。ビルドがreadyになると、そのバージョンを開いた際にアプリでドラフトがレンダリングされます。ドラフトはcanvas-versions-retrieveには表示されません(公開履歴のみが一覧表示されます)。また、ドラフトを元に戻すこともできません。保留中のドラフトはcanvas-drafts-retrieveで一覧表示します。 - 昇格する — ユーザーがドラフトを承認した場合、または公開を依頼した場合に行います。レビューを依頼されたドラフトは、ユーザーから指示があるまでステージしたままにしてください。
canvas-promote-createにより、ドラフトがライブヘッドになります。expected_current_version_idには、canvas-source-retrieveから取得したライブのcurrent_version_idを指定します。これは公開時と同様に保護されており、ヘッドが変わっていると 409 が返されます(下記の手順で復旧してください)。ビルドがまだreadyのドラフトは再ビルドなしでライブになります。それ以外の場合は新しいビルドがキューに追加されるため、手順 2 と同様に待ってください。ドラフトをライブにする方法は、昇格のみです。
409 version_conflict からの復旧
409 は、同時公開またはリバートによって、キャンバスがベースにしたバージョンより先に進んだことを意味します。レスポンスには、現在の current_version_id が含まれます。自分のバージョンを無理に反映させるために、ガードなしで再試行してはいけません。
canvas-source-retrieveでソースを再取得します。- 最新のソースに編集を再適用します(新しいヘッドにはユーザー自身の編集が含まれている可能性があるため、それらは保持し、返信では報告しないでください)。
- 新しい
current_version_idを指定して、再度公開します。
バージョン履歴の仕様
公開するたびにソース全体の新しいバージョンが追加され、ヘッドポインターが更新されます。ユーザーはアプリ内で古いバージョンにリバートできます(その際、再公開と再ビルドが行われます)。実際に読み取ったバージョンを基準に公開することが重要です。これにより、ユーザーのリバート、別のエージェントによる公開、自分の編集が、互いを気づかないうちに消してしまうのを防げます。