mcpField
R
run-posthog

run-posthog

github.com/posthog开发40.5k139 次安装今天更新
代码仓库

关于 run-posthog

run-posthog 是用于启动 PostHog 并验证实时应用变更的仓库技能,为开发者和 Agent 提供就绪检查及浏览器 QA 指引。

主要功能

  1. 01使用 hogli 启动 PostHog
  2. 02检查应用与进程就绪状态
  3. 03创建测试工作区和数据
  4. 04通过浏览器 MCP 验证变更
  5. 05将代码变更映射到应用路由

适用场景

  1. 01启动 PostHog 进行本地开发
  2. 02检查应用是否已就绪
  3. 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

对于 Agent 管理的 QA,除非用户要求调整服务,否则使用普通后台栈。在 devbox 上,对于新建/已停止的 box,优先使用 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 启动路径。

首次启动需要 60-90 秒,因为 Django 需要导入且 Vite 需要预热。使用 hogli down -y 停止(会保持 Docker 服务运行,以便快速重启)。

栈是否就绪?

有两个就绪标准。不要将它们混为一谈。

/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 支撑场景的 /verify 就绪(洞察、仪表盘、Web 分析)以及 POST /api/setup_test/...:

  • 还要求 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"——查看最近的标准输出/标准错误。
  • mcp__phrocs__toggle_process process="<unit>"——重启单个单元。自动模式会在共享栈上阻止此操作(被视为重启共享基础设施)。如果被阻止,请让用户批准,或运行 phrocs stop && hogli up -d 进行完全干净的重启。

驱动 UI 进行 /verify

每个空的 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-10s。参考调用位置: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 配方:

  1. new_page 到 http://localhost:8010/login。

  2. 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
    
  3. 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
    
  4. navigate_page 到 http://localhost:8010/project/{team_id}{scene-path}。

  5. wait_for 文本或 [data-attr] 元素。PostHog 几乎为每个渲染的元素都附加了 data-attr;用它作为"页面已完成水合"的信号。networkidle 和 load 永远不会稳定下来,因为 PostHog.js 和 Vite HMR 一直在轮询。

  6. take_screenshot。对于大多数"这个元素是否存在?"的验证,来自 wait_for 的可访问性快照本身就足够了 —— 无需进行像素对比。

对于仅 API 调用(创建 fixture、在没有浏览器的情况下访问端点),使用 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>.tsxgrep 查找使用位置,截图显示它的场景

当路径不明显时,可以 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 是精准的工具,但 auto 模式会在共享 stack 上阻止它 —— 退而求其次可以用 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 是一个粗粒度的全进程信号。 在判定 stack 不可用之前,请用进程特定的 phrocs 状态、curl 探针和目标路由来确认。
  • Vite 在 :8234 上提供服务,而不是你浏览的 URL。 你浏览的是 http://localhost:8010(Envoy 风格的代理)。该代理将 /static/* 反向代理到 Vite,其余全部代理到 Django。直接访问 :8234/ 会返回 404,因为 Vite 在开发服务器根路径上没有 index 路由。
  • Worktree 共享 Docker 容器,但会争抢端口。 同一台机器上的所有 worktree 都解析到相同的 posthog-clickhouse-1 / posthog-db-1 容器,因此数据库状态是全局的。但端口 8000/8010/8234 一次只能被一个 worktree 占用 —— 在此处执行 hogli up -d 之前,请先杀掉另一个 worktree 的 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 token 正常流转。对于非浏览器 API 调用,请使用 setup_test 响应中的 personal_api_key 作为 Authorization: Bearer <key> —— token 认证没有 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 返回 500 而不是 401 —— Postgres 或 ClickHouse 无法访问。执行 docker ps | grep posthog- 并查找不健康的容器;hogli services:ready 会等待它们全部就绪。
  • POST /api/login/ 返回 400 invalid_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/ 返回 500 Table posthog.person does not exist —— migrate-clickhouse 在启动过程中崩溃。参见上面的注意事项。
  • 页面内 fetch('/api/login/') 返回 403 —— 你是在页面上下文之外调用它(例如用 page.request.post 而不是 page.evaluate)。使用 evaluate_script / browser_evaluate,让调用从页面内发起。

评论

支持 Markdown