feedback-to-pr
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseFeedback → Cursor Cloud Agent → PR
反馈 → Cursor Cloud Agent → PR
Wire a product feedback loop end-to-end:
floating control → DOM screenshot + fetch/console ring buffer → dialog →
(row per user) → background job emails confirmation and
launches a Cursor Cloud Agent () with the screenshot +
logs → Cursor webhook marks and emails the PR link → GitHub webhook
on merge marks and emails "shipped".
POST /api/feedbackautoCreatePr: truepr_openmergedStatus lifecycle: (or ).
submitted → agent_running → pr_open → mergedfailedImplement this in the target app. Do not redesign the loop — the gotchas below
are load-bearing.
搭建端到端的产品反馈流程:
悬浮控件 → DOM截图 + fetch/console环形缓冲区 → 对话框 →
(每条用户反馈对应一条数据库记录)→ 后台任务发送确认邮件并
启动带有截图和日志的Cursor Cloud Agent()→ Cursor Webhook标记并发送PR链接邮件 → GitHub Webhook在合并时标记并发送“已发布”邮件。
POST /api/feedbackautoCreatePr: truepr_openmerged状态生命周期:(或)。
submitted → agent_running → pr_open → mergedfailed在目标应用中实现此流程。请勿重新设计流程——以下注意事项是流程正常运行的关键。
Prerequisites
前置条件
- Route handlers (Next.js App Router or equivalent)
- A database that can store a feedback row (Postgres + any ORM is fine)
- Session/auth that yields a user id + email
- A background job runner with retries (Inngest, etc.)
- Transactional email (Resend or equivalent)
- Cursor Cloud Agents API access + GitHub App grant on the target repo
If the app has no organizations concept, omit org fields — everything else stands alone.
- 路由处理器(Next.js App Router或同类工具)
- 可存储反馈记录的数据库(Postgres + 任意ORM均可)
- 可获取用户ID和邮箱的会话/认证系统
- 支持重试的后台任务运行器(如Inngest等)
- 事务邮件服务(如Resend或同类工具)
- Cursor Cloud Agents API访问权限 + 目标仓库的GitHub App授权
如果应用没有组织概念,可省略组织字段——其余部分均可独立使用。
What to build
构建内容
| Piece | Role |
|---|---|
| Shared types | |
| Network recorder | Patch |
| Screenshot | DOM capture (e.g. |
| Widget | Client provider + dialog; snapshot page on open; |
| Submit route | Auth required; Zod-validate body; rate-limit (~5/hr); persist row; emit job event |
| Feedback table | message, pageUrl, userAgent, screenshot (+ dims), networkLogs, consoleLogs, cursorAgentId, branchName, prUrl, status |
| Job | (1) confirmation email, (2) create Cursor agent with prompt + screenshot, (3) store agent id → |
| Cursor client | |
| Cursor webhook | Verify HMAC over raw body; on |
| GitHub webhook | |
| HMAC helper | SHA-256 hex, optional |
Adaptation points: the app's session helper, design-system dialog/button, Cursor prompt path hint ("work in "), schema migrate, job registration.
apps/web| 组件 | 作用 |
|---|---|
| 共享类型 | |
| 网络记录器 | 对 |
| 截图功能 | DOM捕获(如 |
| 小部件 | 客户端提供者 + 对话框;打开时捕获页面快照;调用 |
| 提交路由 | 需要认证;使用Zod验证请求体;速率限制(约5次/小时);持久化记录;仅发送包含 |
| 反馈数据表 | 包含message、pageUrl、userAgent、screenshot(含尺寸)、networkLogs、consoleLogs、cursorAgentId、branchName、prUrl、status字段 |
| 后台任务 | (1) 发送确认邮件,(2) 使用提示词和截图创建Cursor Agent,(3) 存储Agent ID → 将状态标记为 |
| Cursor客户端 | 调用 |
| Cursor Webhook | 基于原始请求体验证HMAC签名;当状态为 |
| GitHub Webhook | 当 |
| HMAC工具类 | SHA-256十六进制编码,可选前缀 |
适配点:应用的会话工具、设计系统的对话框/按钮、Cursor提示词路径提示(如“在目录中工作”)、数据库 schema 迁移、任务注册。
apps/webEnv vars
环境变量
| Var | Notes |
|---|---|
| Cursor Dashboard → API Keys |
| |
| |
| invent it; same value in the GitHub webhook form |
| verified domain |
| public tunnel in dev; falls back to app public URL in prod |
App public URL (e.g. | browser-facing origin — not the tunnel |
| 变量 | 说明 |
|---|---|
| Cursor控制台 → API密钥 |
| Agent需编辑的仓库地址: |
| 通过 |
| 自行生成;需与GitHub Webhook配置中的值一致 |
| 已验证的域名 |
| 开发环境使用公网隧道;生产环境回退到应用公网URL |
应用公网URL(如 | 浏览器可访问的域名 —— 请勿使用隧道地址 |
One-time external setup
一次性外部配置
- Cursor ↔ GitHub — grant the Cursor GitHub App on the repo. Verify with
.
GET https://api.cursor.com/v0/repositories - GitHub webhook — , secret =
${WEBHOOK_PUBLIC_URL}/api/webhooks/github, events: Pull requests only.GITHUB_WEBHOOK_SECRET - Dev tunnel — HTTPS tunnel to the local app port → . Run the job runner alongside the app.
WEBHOOK_PUBLIC_URL
- Cursor ↔ GitHub — 为仓库授权Cursor GitHub App。通过调用验证权限。
GET https://api.cursor.com/v0/repositories - GitHub Webhook — 地址为,密钥为
${WEBHOOK_PUBLIC_URL}/api/webhooks/github,仅监听Pull requests事件。GITHUB_WEBHOOK_SECRET - 开发环境隧道 — 将本地应用端口通过HTTPS隧道映射到。需与应用同时运行任务运行器。
WEBHOOK_PUBLIC_URL
Hard-won gotchas
经验总结的注意事项
- Never point the auth/public app URL at the tunnel. Cross-origin auth dies
with "Failed to fetch". That is what is for.
WEBHOOK_PUBLIC_URL - Cursor's "Failed to verify existence of branch 'main'" means no repo access, not a wrong branch. Fix the GitHub App grant.
- Confirmation email is the FIRST job step, before agent creation — otherwise a Cursor failure means the user never hears anything.
- Job event carries only . Payloads/step returns are size-capped (~512KB); the screenshot stays in the DB and is re-read in the step.
{ feedbackId } - Webhook signatures verify over the raw body (before parsing). Status-guarded UPDATEs (
await req.text()+ returning) make replays no-ops — only email when a row actually transitioned.WHERE status IN (...) - Cloud agents appear at cursor.com/agents, not in the IDE agent list.
- Screenshot is optional end-to-end (iframes/cross-origin images blank out).
- Swallow email failures in webhook handlers after the DB write, or the provider redelivers forever over a mail blip.
- Cursor without
FINISHED→ markprUrl, don't leavefailed.agent_running
- 切勿将认证/应用公网URL指向隧道地址。 跨域认证会因“Failed to fetch”失败。才是用于此场景的地址。
WEBHOOK_PUBLIC_URL - Cursor提示“Failed to verify existence of branch 'main'”意味着无仓库访问权限,而非分支名称错误。需修复GitHub App授权。
- 确认邮件是任务的第一步,需在创建Agent之前发送——否则若Cursor失败,用户将收不到任何通知。
- 任务事件仅携带。 负载/步骤返回结果有大小限制(约512KB);截图需存储在数据库中,在步骤中重新读取。
{ feedbackId } - Webhook签名需基于原始请求体验证(解析前先执行)。基于状态的更新操作(
await req.text()+ 返回结果)可确保重放请求无副作用——仅当记录状态实际变更时才发送邮件。WHERE status IN (...) - 云Agent显示在cursor.com/agents,而非IDE的Agent列表中。
- 截图在整个流程中是可选的(iframe/跨域图片会显示为空)。
- 在Webhook处理器中,数据库写入完成后需忽略邮件发送失败,否则邮件服务会因短暂故障而持续重发。
- 若Cursor状态为但无
FINISHED→ 标记为prUrl,不要停留在failed状态。agent_running
Verification
验证步骤
- Typecheck/lint clean; job runner reports the new function.
- Submit feedback → DB row, confirmation email, Cursor agent RUNNING.
- Simulate webhooks if not tunneled: signed payloads → →
pr_open; replay idempotent; bad signature → 401; closed-without-merge → no-op.merged - Negatives: unauthenticated → 401; over rate limit → 429.
See for the status machine diagram.
references/architecture.md- 类型检查/代码扫描无错误;任务运行器能识别新增的任务函数。
- 提交反馈 → 生成数据库记录、发送确认邮件、Cursor Agent处于RUNNING状态。
- 若未使用隧道,可模拟Webhook:签名的负载 → 标记为→ 标记为
pr_open;重放请求具有幂等性;无效签名返回401;未合并的关闭PR不触发任何操作。merged - 异常场景验证:未认证请求返回401;超过速率限制返回429。
状态机图请查看。
references/architecture.md