mcpField
B
building-canvases

building-canvases

github.com/posthog開発95109 回インストール今日更新
リポジトリ

building-canvases について

PostHog で独立したアプリを作るためのスキルです。サンドボックス iframe で動く freeform canvas の選択、編集、公開を案内し、React、HTML、データクエリ、検証の各スキルへ作業を振り分けます。

主な機能

  1. 01依頼に応じた canvas の選択・作成
  2. 02ツール経由でのソース取得と編集
  3. 03用途に応じた React または HTML の選択
  4. 04編集可能なコンポーネントのパラメーター設定
  5. 05検証、公開、ビルド結果の確認

活用シーン

  1. 01PostHog でのダッシュボードや分析ツールの作成
  2. 02フォーム、チェックリスト、軽量ワークフローの作成
  3. 03ドキュメントやナラティブレポートの制作
  4. 04ジェネレーティブグラフィックやアニメーションの作成

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/posthog/ai-plugin --skill building-canvases

インストール後、Claude Code で/building-canvasesを入力して読み込まれたか確認します。

同梱ファイルreferences/blocks.md

詳細

キャンバスの構築

キャンバスは、PostHog 内のサンドボックス化された iframe で動作する、クライアントサイドのブラウザーアプリケーションです。 そのソースはリポジトリではなく PostHog にあり、canvas-* ツールを使って読み書きします。キャンバスをローカルファイルに書き込んではいけません。ツール経由で公開することで保存されます。

キャンバスの作業は、通常のタスクなら何からでも始められます。専用のキャンバスモードや、事前に作成されたキャンバスは必要ありません。ユーザーが PostHog 上に置くボード、ドキュメント、フォーム、ビジュアライゼーション、小規模なアプリを求めた場合は、キャンバスの依頼として扱い、このスキルに従ってください。

このスキルが担当するのは freeform キャンバス(スタンドアロンアプリ)です。ほかに、grid キャンバス(ユーザーのホームキャンバスを含むウィジェットグリッド)と component キャンバス(グリッドに配置する再利用可能なウィジェット)の 2 種類があります。対象がグリッドまたはホームキャンバス、配置、再利用可能なウィジェット/コンポーネントの場合は、代わりに composing-grid-canvases を読み込んでください。このスキルが、ストアの検索 → 設定 → フォーク → 構築という手順と、レイアウトのパッチ適用ループを担当します。コンポーネントのソース作成には、引き続き以下の実装用スキルを使います。

対象のキャンバスを特定する

  • タスクでキャンバス ID が指定されている場合(キャンバスから開始されたタスクでは指定されています)、それが対象です。別のキャンバスを作成してはいけません。
  • それ以外の場合、対象のチャンネルはタスクが作成されたチャンネルです。これはタスクのコンテキスト(channel_context ブロックまたは生成指示)に記載されています。canvas-list を使って、そのチャンネルのキャンバスを一覧表示します(channel で対象を絞ります)。リクエストが指していると明らかなキャンバス(同じボードやツールの以前のバージョンなど)があれば、よく似たものを新たに作るのではなく、それを基に構築してください。結果がどこに保存されたのかユーザーに分かるよう、返信でその旨を伝えます。
  • 既存のキャンバスがどれも適切でない場合に限り、同じチャンネルで canvas-create を使って作成します。リクエストに基づく短く分かりやすいタイトルを付け、「Untitled canvas」は使わないでください。
  • 対象を選ぶためにチャンネルを調べ回ってはいけません。ユーザーが指定したチャンネルを ID に解決する場合に限り、channel-list を使います。一覧の先頭には個人用の #me チャンネルが表示されますが、#me を既定にしてはいけません。そこに保存されたキャンバスは、ほかのユーザーには見えません。タスクでキャンバスもチャンネルも指定されていない場合は、推測せず、使用するチャンネルを尋ねてください。

実装用のコンパニオンスキルを読み込む

このスキルが担当するのは、キャンバスの選択と作成ライフサイクルです。実装の要件はコンパニオンスキルが定めています。ソースを書き始める前に、該当するコンパニオンスキルをすべて読み込んでください。

  • ダッシュボード、データボード、フォーム、ツール、アプリケーションのような状態を持つもの、または PostHog に自然になじむ見た目にするものには、building-react-quill-canvases を使います。使用可能なインポート、Quill の構成、テーマ設定、チャート、読み込み状態とエラー状態、日付ピッカーを担当します。
  • ドキュメント、記事、焦点を絞った実験、生成グラフィックス、<canvas>、またはアプリケーションコンポーネントが役立つ構造を追加しない WebGL 作業には、building-html-canvases を使います。セマンティックなマークアップ、ブラウザー API の直接利用、アニメーションのクリーンアップ、Quill を使わないテーマ設定を担当します。
  • キャンバスが PostHog のデータを読み取る場合、イベントをキャプチャする場合、または遷移する場合は、querying-canvas-data を使います。ph SDK、保存済みインサイトの優先設定、結果の形式、変数、日付範囲、クエリごとの段階的な読み込み、宣言されたデータ機能を担当します。データを扱う場合は、いずれかの実装スキルと併せて読み込んでください。
  • すべてのキャンバスで、validating-and-publishing-canvases を使います。プロジェクトの構成、機能の宣言、検証診断、安全措置付きの公開、下書き、ビルド、競合からの復旧を担当します。

適切であれば、実装方法を組み合わせてください。React にアプリケーションの枠組みを任せ、ブラウザーのグラフィックスコードでキャンバス要素を扱うことも、ほぼ静的なページにインタラクティブな領域を 1 つだけマウントすることもできます。

これは判断が必要な選択であり、永続化されるモードではありません。選択によってユーザーに見える要件が変わり、それを推測できない場合に限り、ユーザーに確認してください。

ブロック

キャンバスには、数値、目標、トレンド、トップリスト、ファネル、リテンション、保存済みインサイト、ライブイベントフィード、SQL テーブル、フィルター、比較・更新コントロール、コールアウトなど、あらかじめ用意されたブロックを配置できます。 これらは src/blocks/ にある React コンポーネントで、デスクトップアプリでキャンバスにドラッグして配置するため、ソースコードの一部です。 src/blocks/runtime.tsx があるキャンバスを変更する前に、references/blocks.md をお読みください。

パラメーター

ユーザーが変更したい値は、パラメーターとして公開してください。そうすれば、新しいタスクを実行しなくてもデスクトップエディターで変更できます。 パラメーターは必須ではありませんが、変更する価値のある値(タイトル、コピー、イベント、プロパティ、しきい値、上限、色)がある各パネル、カード、ツールには追加してください。 パラメーターには React コンポーネントが必要です。プレーンな HTML キャンバスにはパラメーターがありません。

エディターでの editable() の使い方

デスクトップエディターでは、ユーザーは見出し、段落、セクションなど、キャンバス上の任意の要素を選択できます。移動、複製、削除したり、テキストをダブルクリックして変更したりできます。これらの操作に editable() の呼び出しは必要ありません。

editable() を使うと、コンポーネントが1つのブロックになります。するとエディターは、そのブロックを1つの単位として扱います。

  • クリックすると、ブロック内の要素ではなくブロック全体が選択されます。
  • 移動、複製、削除はブロック全体に対して実行されます。
  • サイドパネルにはブロックのパラメーターがフィールドとして表示されます。値を変更すると、新しい値がソース内のブロックの props に書き込まれます。
  • ブロック内の要素にアクセスするには、ブロックをダブルクリックして開きます。

そのため、カード、チャート、テーブル、フォームなど、ユーザーが1つのものとして捉え、1つのものとして設定する部分に editable() を使ってください。その周囲のページレイアウトはプレーンな JSX のままにします。するとユーザーはカードをブロックとして選択しつつ、ページの見出しやセクションも直接選択できます。ページ全体を保持するコンポーネントに editable() を使うと、ページ全体が1つのブロックになり、クリックするたびにそのすべてが選択されます。

パラメーターの追加
  1. 各パネルを個別のコンポーネントにします。コンポーネントは、デフォルト値を持つこれらの値を props として受け取ります。
  2. @posthog/canvas-sdk の editable(name, props, params) をコンポーネントのルート要素に展開して渡します。name はコンポーネント名です。params では各 prop を対応するフィールドにマッピングします。
  3. <SignupFunnel blockId="b-k3m9x2" title="Signup" windowDays={14} /> のように、リテラルの props を使ってコンポーネントを使用します。エディターは変更をこれらの props に書き込むため、インラインで計算しないでください。
  4. <SignupFunnel blockId="b-k3m9x2" … /> のように、使用箇所ごとに一意の blockId prop を指定して、ユーザーがエージェントに特定のカードを指定できるようにします。使用できるのは英字、数字、_、-、.、: のみです。それ以外の場合、エディターは ID を無視します。リストでは、``blockId={kpi-${item.id}}` のように、項目の安定したキーから ID を作成します。
import { editable } from '@posthog/canvas-sdk'

export function SignupFunnel(props: { blockId?: string; title?: string; steps?: string[]; windowDays?: number }) {
  const { title = 'Signup funnel', steps = ['$pageview', 'signed_up'], windowDays = 14 } = props
  return (
    <Card
      {...editable('SignupFunnel', props, {
        title: { type: 'text', label: 'Title', default: 'Signup funnel' },
        steps: { type: 'events', label: 'Steps', default: ['$pageview', 'signed_up'] },
        windowDays: { type: 'number', label: 'Conversion window (days)', min: 1, max: 90, default: 14 },
      })}
    >
      …
    </Card>
  )
}

フィールドの種類:text、longtext、number(min、max、step を指定できます。min と max の両方を指定すると、エディターにはスライダーが表示されます)、boolean、select(options は文字列、または { value, label })、event、events、property、insight(保存済みインサイトの短い ID)、color。各フィールドには description も指定できます。 各フィールドには、例のように prop のデフォルト値と同じ default を指定してください:{ type: "boolean", label: "Show legend", default: true }。prop が設定されていない場合、エディターは default の値を表示します。 color パラメーターのデフォルトには、var(--primary) のようなテーマトークンを指定します。これにより、ユーザーがエディターで16進数の色を選ぶまでは、キャンバスがライトモードとダークモードに追従します。 パラメーターを通じて渡す値は、JSON 値(文字列、数値、ブール値、文字列配列)のみにしてください。関数やクエリ結果は含めないでください。

画像

キャンバス内の画像には、公開メディアライブラリの URL を使用します。最初に posthog:media-images-list を purpose="canvas" で呼び出し、適した画像がすでにある場合は再利用してください。

ローカル画像を追加するには:

  1. ファイル名と purpose="canvas" を指定して、posthog:media-image-upload-start を呼び出します。
  2. シェルから、返された upload_url にファイルをマルチパートフォームデータとして POST します。返された form_fields の各項目を含め、ファイルのパートを最後に配置してください。
  3. 返された ID を指定して posthog:media-image-upload-complete を呼び出し、返された永続 URL を画像の src として使用します。
  4. URL の正確なオリジンを project.capabilities.network.origins に追加します。キャンバスの検証ではこの宣言が確認され、公開された成果物ではこれが Content Security Policy に使用されます。

キャンバスのメディア URL は公開されており、認証は不要です。シークレット、認証情報、顧客データ、機密性の高いスクリーンショットは決してアップロードしないでください。画像は 4 MB 未満で、PNG、JPEG、GIF、WebP、AVIF、BMP のいずれかとしてデコードできる必要があります。画像データを Base64 エンコードしてツール呼び出しに含めないでください。

一般的なリクエストパターン

これらはルーティングの例として使用し、固定テンプレートとして扱わないでください。

  • 製品ダッシュボード、ウェブ分析ボード、メトリクスエクスプローラー: React + Quill とデータクエリを使用します。
  • チェックリスト、フォーム、軽量なワークフロー: React + Quill を使用し、PostHog の読み取り、イベントの記録、ナビゲーションにはデータクエリを追加します。チェックリストやランブックの場合は、building-react-quill-canvases の実例(references/checklist-example.md)を出発点として使用してください。チームで共有する進捗には、ステップごとの ph.state キーを使用します。利用可能な API で提供されていない永続性を示唆しないでください。
  • ドキュメントまたはナラティブレポート: ほぼ静的な閲覧体験には HTML を使用します。ライブの PostHog データ、フィルター、アプリケーションのようなインタラクションが必要な場合は、React + Quill とデータクエリを使用します。
  • 生成グラフィックまたはアニメーション: HTML とブラウザーのグラフィックス API を使用します。アプリケーションの状態管理や UI 外枠を大幅に簡素化できる場合にのみ React を追加します。

リクエストに dashboard や web-analytics などの従来のパターン指定が含まれている場合は、上記の対応する形式を適用します。パターンはヒントであり、ユーザーの実際のリクエストが優先されます。

イテレーションの流れ

  1. canvas-source-retrieve を使って、現在のソースとバージョンポインターを読み込みます。 current_version_id を控えておきます。公開時には、この値を使ったガードが必要です。
  2. 上記で選択した実装用コンパニオンを使って、プロジェクトファイルを編集します。キャンバスに表示される PostHog データについては、 querying-canvas-data に従ってください(保存済みインサイトは ph SDK を使って読み込みます。データを取得したり、独自の PostHog クライアントを使ったりしてはいけません)。すべての数値を検証可能にしてください。インサイトに基づく指標には PostHog の保存済みインサイトへのリンクを付け、アドホッククエリには、そのスキルの「検証可能性」セクションに従って、実行したクエリを正確に表示します。また、 すべての ph 呼び出しを project.capabilities で宣言してください(インサイトの短縮 ID は capabilities.posthog.insights に、キャプチャしたイベントは captureEvents に、アドホッククエリには inlineQueries: true を、ph.agent.request には agentRequests: true を指定します)。ホストはこれらを実行時に強制し、宣言されていない呼び出しは検証で拒否されます。
  3. validating-and-publishing-canvases に従ってください。必要に応じて canvas-validate-create で検証し、エラー重大度の診断をすべて修正します。
  4. プロジェクトを公開して保存します。公開はデフォルトの動作で、すぐに公開状態になります。
    • 初回バージョン(current_version_id が null):canvas-publish-create を使ってプロジェクト全体を公開し、expected_current_version_id: null を渡します。
    • すでに公開済み(current_version_id が設定済み):canvas-edit-create を使って変更箇所のみを送信し、ファイル内の変更には str_replace 操作を使用します。 公開中の current_version_id を expected_current_version_id として渡します。 プロジェクト全体を置き換える場合に限り、canvas-publish-create を使ってプロジェクト全体を公開します。
    • ユーザーが公開前の下書き、プレビュー、またはレビューの手順を希望した場合に限り、canvas-draft-create で下書きを作成します。 診断と競合からの復旧については、validating-and-publishing-canvases スキルに従ってください。
  5. ビルドの完了を待ちます。下書きと公開のどちらも、ビルドが 1 件キューに追加されます。公開または編集のレスポンスには build.build_status が含まれています。値が ready または failed の場合は、その値を使用します。それ以外の場合は、ビルドが ready または failed になるまで canvas-builds-retrieve を数秒おきに(最長約 2 分間)ポーリングします。failed の場合は、ビルドのエラー診断を読み、プロジェクトを修正して再度保存します。ビルドに失敗した状態でタスクを終了してはいけません。

キャンバスの準備ができたら、依頼された変更ごとに 1 回だけ保存してください。細かな編集のたびに保存する必要はありません。ユーザーが下書きを希望した場合は、下書きのプレビューと公開への昇格が可能であることを返信の最後に伝えてください。下書き → ビルド → プレビュー → 昇格の流れについては、validating-and-publishing-canvases スキルを参照してください。

返信の最後に、キャンバスが属するチャンネル名を記載し、キャンバスツールが返す url フィールドを使ってリンクしてください(canvas-create、canvas-list、公開およびソースのレスポンスに含まれます)。キャンバスへの有効なリンクとして使用できるのは、このフィールドのみです。リンクを独自に作成してはいけません。推測した URL(プロジェクトページやウェブルート)は解決されません。

ランタイムのメモリとアクション

  • ph.state — 永続的なキーと値のメモリです:ph.state.get(key, { scope })、 ph.state.set(key, value, { scope })(値を null にするとキーが削除されます)、ph.state.list({ scope })。 スコープ "user"(デフォルト)は各閲覧者専用です。"shared" はキャンバスごとに値が1つで、 チーム全体から参照できます。使用するスコープは capabilities.posthog.state で宣言してください。 値は JSON 形式で、シリアライズ後のサイズは最大64 KB、スコープごとのキー数は最大256個です。大きなデータは PostHog(インサイト、データウェアハウス)に保存し、そこを参照してください。シークレットや閲覧者の個人情報を state に保存しないでください。

  • ph.actions.invoke(verb, payload) — 閲覧者として PostHog に書き込みます。すべての verb を capabilities.posthog.actions で宣言してください。宣言されていない verb や登録されていない verb は検証に失敗し、 ホストが実行時に拒否します。アクションは明示的なユーザー操作(閲覧者がクリックするボタンなど)に結び付けてください。読み込み時やレンダリング時には実行しないでください。レジストリが信頼できる情報源です。canvases-actions-retrieve ツールで一覧表示し、各 verb の usage(ペイロード/結果の形式、 動作、必要な確認メッセージ)に従って組み込んでください。

  • ph.tools.read(tool, args) および ph.tools.call(tool, args):閲覧者として許可リストにある PostHog MCP ツールを実行します。たとえば、機能フラグを読み取り、そのロールアウトを変更できます。すべての ツールを capabilities.posthog.tools で宣言してください。read は読み取り専用ツールを受け付けます。call はデータを変更するため、 クリック操作に結び付けてください。ホストは閲覧者に確認を求めます。許可リストと、フラグの書き込みに必要なバージョン処理については querying-canvas-data を参照してください。

  • ph.connectors.call(provider, tool, args) — 表示時に閲覧者自身の接続を使って、GitHub や任意の MCP ストアサーバーから最新のサードパーティーデータを読み取ります。GitHub、Calendly、その他のサービスを自分で呼び出して、その結果をソースに貼り付けないでください。公開時点でそのスナップショットは古くなり、すべての閲覧者に作成者のデータが表示されます。各プロバイダーとツールを capabilities.connectors で宣言してください。canvas-connectors-retrieve ツールで確認できます。結果の処理と未接続時の処理については querying-canvas-data を参照してください。

  • ph.agent.request(prompt) — 閲覧者の承認を得て、キャンバスの作成エージェントに変更を依頼します。capabilities.posthog で agentRequests: true を宣言してください。直接のクリックまたはフォーム送信からのみ呼び出してください。ホストは正確なプロンプトを表示し、計算リソースを消費する前に閲覧者に承認を求めます。レンダリング中、マウント中、ポーリング中の呼び出しは拒否されます。エージェントは変更を新しいバージョンとして公開します。作成者以外からのリクエストは実行を開始するのではなく、作成タスクのスレッドに記録されます。

ソースプロジェクトの構成

  • ソースツールから返されるエントリーシェルとして index.html を維持してください。
  • src/canvas.tsx は通常の React エントリーコンポーネントとして維持します。ただし、プロジェクト内の追加の相対 TypeScript、TSX、JavaScript、JSON、SVG、CSS、および許可されたアセットファイルをインポートできます。
  • 自己完結型のモジュールワーカーは ./worker.ts?worker でインポートできます。ワーカーから別のローカルモジュールをインポートすることはできません。
  • 画像には上記の公開メディアライブラリのフローを使用してください。その他のバイナリアセットは、許可されたコンテンツタイプの base64 コンテンツとして、プロジェクトの assets マップに格納してください。WOFF/WOFF2、WebAssembly、汎用オクテットストリームのアセットに対応しています。
  • プラットフォーム依存関係マップは、返された内容をそのまま維持してください。npm パッケージを追加しないでください。相対パスのローカルインポートはプロジェクトファイルを指し、パッケージ名のみのインポートはプラットフォームで固定されたものに限られます。

コメント