run-posthog について
run-posthog は、PostHog の起動と稼働中のアプリでの変更確認を支援するリポジトリ用スキルです。開発者やエージェント向けに、起動確認とブラウザー QA の手順をまとめています。
主な機能
- 01hogli による PostHog の起動
- 02アプリとプロセスの準備状態確認
- 03テスト用ワークスペースとデータの作成
- 04ブラウザー MCP による変更確認
- 05コード変更とアプリルートの対応付け
活用シーン
- 01ローカル開発用の PostHog 起動
- 02アプリが利用可能かの確認
- 03稼働中のブラウザーでの UI 変更確認
MCP 対応
phrocs MCP サーバーでプロセス状態を確認・管理し、chrome-devtools-mcp や playwright などのブラウザー MCP サーバーで検証時にアプリを操作します。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ posthog/ posthog --skill run-posthogインストール後、Claude Code で/run-posthogを入力して読み込まれたか確認します。
詳細
PostHog は Django + Vite + Celery + plugin-server で構成され、Docker 上の Postgres、ClickHouse、Kafka、Redis、Temporal に支えられ、http://localhost:8010 で Envoy スタイルのプロキシによってフロントされます。開発スタックは phrocs の下でデタッチモードで実行されるため、実行中のプロセスはこのセッションから phrocs MCP サーバーを通じて検査できます。ブラウザー MCP サーバー(chrome-devtools-mcp、playwright)が UI を操作します。このスキル自体が独自のドライバーを同梱することはありません。
/run の場合: ユーザーが操作できるようにアプリを到達可能にします。成功 = http://localhost:8010 が配信され、コアユニットが ready であること。クラッシュしたマイグレーションユニットを追いかけないでください。指示がない限りデータをシードしないでください。
/verify の場合: ビルドし(フロントエンドでは Vite HMR がこれを自動的に処理します。バックエンドの変更にはビルドは不要です)、/run と同じ起動を実行し、次にブラウザー MCP を介してライブアプリを操作して変更を観察します。この観察が検証です — テストと型チェックは代用になりません。フロントエンド/UI の変更の場合、このワークフローの深いバージョンはローカルモードのリポジトリ内 qa-frontend スキルです: diff からのシナリオ設計、再現性のためのリトライ、注釈付きのエビデンス。
以下のすべてのパスはリポジトリルートからの相対パスです。
前提条件
- flox 1.16+ がツールチェーンをプロビジョニングします —
curl -L https://downloads.flox.dev/by-env/stable/install.sh | sudo bash - Docker — macOS では OrbStack を推奨(
brew install --cask orbstack) - 1Password CLI(オプション) —
brew install 1password-cli、.env.localにop://参照が含まれる場合のみ
起動
通常の開発者スタックには、保存されたインタラクティブセットアップを使用します:
hogli dev:setup # first time only — interactive wizard picks which workers to run
hogli up -d -y # start the stack detached under phrocs
hogli services:ready -y # wait for Docker services (Postgres, CH, Kafka, Redis)
hogli wait -y # broad all-process signal; confirm with the checks below
hogli doctor # optional: stale migrations, zombie phrocs, disk pressure
エージェント管理の QA には、ユーザーがサービスを調整するよう求めない限り、通常のバックグラウンドスタックを使用します。devbox では、新規/停止中のボックスには hogli devbox:start --start-app を優先してください。アプリなしですでに実行中の場合、その中で PostHog を起動します:
hogli devbox:exec -- bash -lc 'cd ~/posthog && ./bin/hogli up -d -y'
hogli dev:intents、hogli dev:explain <intent>、hogli dev:list-units <intent> は、ルート固有の依存関係を理解するためにのみ使用してください。カスタム生成された設定は、デフォルトの QA 起動パスではありません。
初回起動は Django のインポートと Vite のウォームアップのため 60〜90 秒かかります。停止は hogli down -y で行います(高速な再起動のために Docker サービスは実行したままにします)。
スタックは準備完了ですか?
準備完了の基準は 2 つあります。それらを混同しないでください。
/run の準備完了 — アプリが到達可能で、操作できる状態:
curl -sf http://localhost:8010/_health # 200
curl -sf -o /dev/null -w '%{http_code}' http://localhost:8010/ # 200 or 302
curl -sS http://localhost:8010/api/projects/@current | grep -q '"code":"not_authenticated"' # API + DB reachable
UI QA では、backend と frontend が必須ゲートです。ルートが必要とするユニットのみを追加してください(例: mcp、feature-flags、nodejs、capture、ingestion)。ここで止めます。/run のみを求められた場合、クラッシュした migrate-* ユニットを追いかけないでください — マイグレーションの状態にかかわらず、スタックは起動、スクリーンショット、およびほとんどの UI シーン(ホーム、ログイン、設定、フィーチャーフラグ)に使用できます。
HogQL に支えられたシーン(インサイト、ダッシュボード、ウェブ分析)および POST /api/setup_test/... の /verify の準備完了:
- さらに
mcp__phrocs__get_process_status process="migrate-clickhouse"がstatus:"done" exit_code:0を示す必要があります。crashedの場合は、以下の注意点を参照してください。
phrocs MCP ツール — どちらの基準でも:
mcp__phrocs__get_process_status(引数なし) — すべてのユニット、ready、exit_code、メモリ、CPU 付き。mcp__phrocs__get_process_status process="frontend"— 単一ユニット。mcp__phrocs__get_process_logs process="backend"— 最近の stdout/stderr を tail します。mcp__phrocs__toggle_process process="<unit>"— 1 つのユニットを再起動します。自動モードでは共有スタックでこれがブロックされます(共有インフラの再起動として扱われます)。ブロックされた場合は、ユーザーに承認を求めるか、完全なクリーン再起動のためにphrocs stop && hogli up -dを実行してください。
/verify のために UI を操作する
空の PostHog シーンはイベントが存在しないため、すべて壊れているように見えます。UI の変更を検証するには、現実的なデータを含むワークスペースが必要です。正規のパスは Playwright スイートが使用するものと同じで、POST /api/setup_test/organization_with_team/ です。DEBUG=True | E2E_TESTING | CI | TEST でゲートされており、ローカル開発では DEBUG=True によってすべて満たされます。実装: posthog/api/playwright_setup.py + posthog/test/playwright_setup_functions.py:create_organization_with_team — HedgeboxMatrix 経由で 3 クラスター、エンドツーエンドで約 5~10 秒です。参照呼び出し箇所: playwright/utils/playwright-setup.ts:251。
/run と /verify では hogli dev:demo-data を避けてください — これは generate_demo_data を n_clusters=500 で呼び出し (posthog/management/commands/generate_demo_data.py:59 のデフォルト)、5~30 分かかります。これは大きな現実的なデータセットを試したい人間向けに存在するものであり、自動化された起動とスクリーンショットには不適切なツールです。
ブラウザ MCP の完全なレシピ:
-
new_pageでhttp://localhost:8010/loginを開きます。 -
evaluate_scriptでワークスペースのブートストラップを実行します。呼び出しごとにメールを変えて再実行時の衝突を避けます。パスワードは12345678に固定します。レスポンスで team_id と個人用 API キーが返ります。const r = await fetch('/api/setup_test/organization_with_team/', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ skip_onboarding: true, use_current_time: true }), }) const { result } = await r.json() // result: { user_email, team_id, personal_api_key, organization_id, ... } return result -
evaluate_scriptでページ内ログインを実行します。ページコンテキストで実行されるため、Django の CSRF ミドルウェアが正しい Cookie を認識します (playwright/utils/playwright-setup.ts:282-291)。const r = await fetch('/api/login/', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email: workspace.user_email, password: '12345678' }), }) return r.status // 200 = logged in; 403 = you're not in-page; 400 = workspace setup didn't actually create the user -
navigate_pageでhttp://localhost:8010/project/{team_id}{scene-path}に移動します。 -
wait_forでテキストまたは[data-attr]要素を待ちます。PostHog はレンダリングされるほぼすべての要素にdata-attrを付与しているので、これを「ページがハイドレートされた」シグナルとして使います。PostHog.js と Vite HMR がポーリングを続けるため、networkidleとloadは決して安定しません。 -
take_screenshotを実行します。wait_forからのアクセシビリティスナップショットは、ほとんどの「この要素は存在するか?」という検証において単独でも十分です — ピクセル比較は不要です。
API のみの呼び出し (フィクスチャの作成、ブラウザなしでのエンドポイントへのアクセス) では、setup_test のレスポンスから取得した personal_api_key を Authorization: Bearer <key> として使用します — ログインの手順は不要です。
より深い操作 (クリック、フォーム入力、コンソールの検査) には、同じ MCP ツールキット (chrome-devtools-mcp:* / playwright:*) で対応できます。プロジェクト固有のラッパーは不要です。
/verify のために: diff → URL のマッピング
フロントエンドは kea-router を使用しています。マッピングのルール:
| 編集されたパス | シーン URL (/project/{team_id}/ 配下) |
|---|---|
frontend/src/scenes/<name>/** | 通常 /<name> (例: insights/ → /insights) |
frontend/src/scenes/activity/** | /activity/events (およびその他の ActivityTab) |
frontend/src/scenes/data-management/** | /data-management/<sub> |
frontend/src/scenes/settings/** | /settings/<section> |
frontend/src/scenes/authentication/** | /login、/signup、/preflight (スコープ外) |
products/<name>/frontend/** | products/<name>/manifest.tsx の urls: ブロックに従う |
frontend/src/layout/** | どこでもレンダリングされるため、任意のシーンで検証 |
frontend/src/lib/components/<X>.tsx | 使用箇所を grep し、それをマウントするシーンをスクリーンショット |
パスが明らかでない場合に grep すべき正規のソース:
frontend/src/scenes/urls.ts— トップレベルの URL ヘルパー (urls.insights()、urls.dashboard(...)など)。frontend/src/scenes/scenes.ts— シーンとルートのレジストリ。products/<name>/manifest.tsx— プロダクトごとのルート。
注意点
migrate-clickhouseとmigrate-persons-dbは、コールドスタートのhogli up -dで起動時の競合によりしばしばクラッシュします。 これらはmigrate-postgresと並行して起動するため、Postgres がまだ準備できていないとクラッシュします。これはPOST /api/setup_test/...と HogQL に依存するシーン(インサイト、ダッシュボード、Web アナリティクス)にとっては必須の前提条件ですが、/runには該当しません。タスクが HogQL/setup_testを必要としない限り、修正しないでください。修正が必要な場合の正規の手順は、mcp__phrocs__get_process_statusでmigrate-postgresがstatus:"done"を示すまで待ち、その後クラッシュしたマイグレーションを再起動するというものです。mcp__phrocs__toggle_processはピンポイントなツールですが、共有スタックでは自動モードがこれをブロックします。その場合はphrocs stop && hogli up -dにフォールバックするとすべてを順番に再実行できます。あるいはpython manage.py migrate_clickhouseを直接実行してください(その前にset -a; source .env.services; set +aを実行してCLICKHOUSE_DATABASE=posthogとする必要があります。そうしないとdefaultが対象になります)。どちらもうまくいかない場合(部分的な実行による ZooKeeper 内の破損した CH レプリカ状態)、hogli dev:resetが唯一の手段です。これは Docker ボリュームを消去する破壊的操作です。hogli waitは全プロセスを対象とした粗いシグナルです。 スタックが使用不能だと判断する前に、プロセス固有の phrocs ステータス、curlプローブ、および対象ルートで確認してください。- Vite は
:8234で配信され、閲覧する URL とは異なります。 閲覧するのはhttp://localhost:8010(Envoy スタイルのプロキシ)です。プロキシは/static/*を Vite に、それ以外を Django にリバースプロキシします。:8234/に直接アクセスすると 404 が返ります。これは、Vite の開発サーバーのルートにインデックスルートがないためです。 - ワークツリーは Docker コンテナを共有しますが、ポートを競合します。 同じマシン上のすべてのワークツリーは同じ
posthog-clickhouse-1/posthog-db-1コンテナに解決されるため、DB の状態はグローバルです。ただし、ポート 8000/8010/8234 は一度に 1 つのワークツリーしか占有できません。ここでhogli up -dを実行する前に、他のワークツリーの granian/vite/phrocs を停止してください。 - ブラウザコンソールの CSP 警告と 401 は、認証前としては正常です。 プリフライト/ログインページは
/api/projects/@current、/api/users/@me/、および PostHog.js のリモート設定を取得しようとしますが、サインアップするまではすべて 401 になります。WASM/CSP の「Report Only」警告は開発用 CSP によるものです。 curl -X POST /api/login/を直接実行すると 403(CSRF)が返ります。 セッションログインはbrowser_evaluateを使ってページ内で実行する必要があり、そうすることで Cookie と CSRF トークンが流れます。ブラウザ以外からの API 呼び出しには、setup_testのレスポンスにあるpersonal_api_keyをAuthorization: Bearer <key>として使用してください。トークン認証には CSRF はありません。.env.localは 1Password の参照を使用している場合があります。opがインストールされていないと、参照がリテラル文字列(例:OPENAI_API_KEY=op://...)になり、下流のサービスが不可解な認証エラーで失敗します。opをインストールするか、リテラルに置き換えてください。
トラブルシューティング
hogli up -dがAnother instance of bin/start is already runningで終了する — 前回の実行がまだアクティブであるか、クリーンアップされずにクラッシュしています。mcp__phrocs__get_process_statusで何が残っているかを確認できます。何も実行されていない場合は、rm bin/start.lockを実行して再試行してください。docker infoがdial unix /Users/<you>/.orbstack/run/docker.sock: ... no such fileで失敗する — OrbStack が停止しています。open -a OrbStackを実行してください。/api/projects/@currentが 401 ではなく 500 を返す — Postgres または ClickHouse に到達できません。docker ps | grep posthog-で異常なコンテナを探してください。hogli services:readyはそれらすべてが起動するまで待機します。POST /api/login/が 400invalid_credentialsを返す —setup_testワークスペースが実際には作成していないユーザーとしてログインしています(通常は CH のクラッシュが原因です)。setup_test 呼び出しのレスポンスを確認してください。500 を返していた場合は、まず CH を修正してください(migrate-clickhouseの注意点を参照)。POST /api/setup_test/organization_with_team/が 404 を返す —DEBUG、E2E_TESTING、CI、TESTがすべて false です。ローカル開発ではデフォルトでDEBUG=Trueです。設定されていない場合は、.env.localが存在しないか、DJANGO_SETTINGS_MODULEが本番に近い設定モジュールを指しています。POST /api/setup_test/organization_with_team/が 500Table posthog.person does not existを返す — 起動中にmigrate-clickhouseがクラッシュしました。上記の注意点を参照してください。- ページ内の
fetch('/api/login/')が 403 を返す — ページコンテキストの外から呼び出しています(例:page.evaluateではなくpage.request.post)。evaluate_script/browser_evaluateを使用して、呼び出しがページ内から発行されるようにしてください。