|
| 1 | +# Cursor Agent Runner |
| 2 | + |
| 3 | +Run Cursor's CLI agent on [Trigger.dev](https://trigger.dev), streamed live to a terminal UI. |
| 4 | + |
| 5 | +Type a prompt, pick a model, and watch the agent create files and write code from scratch in real time. |
| 6 | + |
| 7 | +## How it works |
| 8 | + |
| 9 | +1. User types a prompt in the browser (e.g. "Create a TypeScript CLI that converts CSV to JSON") |
| 10 | +2. Next.js API route triggers a Trigger.dev task |
| 11 | +3. The task spawns `cursor-agent` in an empty workspace |
| 12 | +4. NDJSON output from stdout is parsed and piped to a Realtime Stream |
| 13 | +5. `useRealtimeRunWithStreams` renders each event live in a terminal panel |
| 14 | + |
| 15 | +``` |
| 16 | +[Browser] <-- Realtime Streams v2 --> [Trigger.dev Cloud] |
| 17 | + | | |
| 18 | + | POST /api/trigger | task.trigger() |
| 19 | + | | |
| 20 | + +--- Next.js API route ------------------+ |
| 21 | + | |
| 22 | + cursor-agent child process |
| 23 | + stdout -> NDJSON -> stream |
| 24 | +``` |
| 25 | + |
| 26 | +## Key concepts demonstrated |
| 27 | + |
| 28 | +- **Build extensions** — install any system binary (cursor-agent) into the task container via `addLayer` |
| 29 | +- **Realtime Streams v2** — pipe NDJSON from a child process directly to the browser |
| 30 | +- **Long-running tasks** — cursor-agent runs for minutes; Trigger.dev handles lifecycle, timeouts, retries |
| 31 | +- **Machine selection** — `medium-2x` for resource-intensive CLI tools |
| 32 | + |
| 33 | +## Setup |
| 34 | + |
| 35 | +```bash |
| 36 | +# Install dependencies |
| 37 | +pnpm install |
| 38 | + |
| 39 | +# Copy env template and fill in values |
| 40 | +cp env.local.example .env.local |
| 41 | +``` |
| 42 | + |
| 43 | +Required environment variables: |
| 44 | + |
| 45 | +| Variable | Description | |
| 46 | +|----------|-------------| |
| 47 | +| `TRIGGER_SECRET_KEY` | Your Trigger.dev secret key (starts with `tr_dev_` or `tr_`) | |
| 48 | +| `TRIGGER_PROJECT_REF` | Your Trigger.dev project ref (starts with `proj_`) | |
| 49 | +| `CURSOR_API_KEY` | Your Cursor API key for headless CLI access | |
| 50 | + |
| 51 | +## Run locally |
| 52 | + |
| 53 | +```bash |
| 54 | +# Start Next.js dev server |
| 55 | +pnpm dev |
| 56 | + |
| 57 | +# In another terminal, start Trigger.dev dev |
| 58 | +npx trigger.dev dev |
| 59 | +``` |
| 60 | + |
| 61 | +Open [http://localhost:3000](http://localhost:3000). |
| 62 | + |
| 63 | +## Deploy to Trigger.dev Cloud |
| 64 | + |
| 65 | +```bash |
| 66 | +npx trigger.dev deploy |
| 67 | +``` |
| 68 | + |
| 69 | +The build extension in `trigger.config.ts` installs `cursor-agent` into the container image automatically. |
| 70 | + |
| 71 | +## Project structure |
| 72 | + |
| 73 | +``` |
| 74 | +├── app/ |
| 75 | +│ ├── layout.tsx # Root layout with Geist fonts |
| 76 | +│ ├── page.tsx # Main UI: control bar + terminal |
| 77 | +│ └── api/trigger/route.ts # Trigger task, return run ID |
| 78 | +├── components/ |
| 79 | +│ ├── terminal.tsx # Realtime terminal with auto-scroll |
| 80 | +│ ├── cursor-event.tsx # Render each NDJSON event type |
| 81 | +│ └── control-bar.tsx # Prompt input, model select, run button |
| 82 | +├── trigger/ |
| 83 | +│ └── cursor-agent.ts # The task: spawn CLI, stream NDJSON |
| 84 | +├── lib/ |
| 85 | +│ └── cursor-events.ts # TypeScript types for cursor events |
| 86 | +├── trigger.config.ts # Build extension for cursor CLI binary |
| 87 | +└── env.local.example # Env var template |
| 88 | +``` |
| 89 | + |
| 90 | +## Links |
| 91 | + |
| 92 | +- [Trigger.dev Build Extensions docs](https://trigger.dev/docs/config/extensions/custom) |
| 93 | +- [Trigger.dev Realtime Streams docs](https://trigger.dev/docs/realtime) |
| 94 | +- [Cursor CLI Output Format](https://cursor.com/docs/cli/reference/output-format) |
| 95 | + |
| 96 | +## Stack |
| 97 | + |
| 98 | +Next.js 16 · Trigger.dev v4 · Tailwind CSS · Geist Mono |
0 commit comments