Most people open Cursor, type a prompt into the chat panel, get a wall of code back, and paste it in. That works fine once. It falls apart the moment your change touches three files and depends on a helper the model never saw.
What follows is the workflow I landed on after a few months of daily use. The running example is a small Node/Express API where we need to swap offset pagination for keyset pagination on GET /api/orders. Real task, real constraints, real prompts.
Step 1: Give Cursor a Rules File Before You Ask for Anything
Cursor reads a project rules file on every request. If that file doesn’t exist, the model guesses at your conventions and guesses wrong. It writes CommonJS into an ESM repo, or hands you a class when the rest of the codebase is functional.
Create .cursor/rules/project.mdc (older builds look for .cursorrules at the root) and keep it under a page. Long rule files get ignored the same way long prompts do.
- Runtime: Node 20, ESM only, no require() calls
- Validation: zod schemas in src/schemas, one file per resource
- Errors: throw AppError from src/lib/errors, never return raw strings
- Tests: vitest, colocated as *.test.ts, database not mocked
- Never edit src/generated, the ORM rebuilds it
That last line alone saved me a week of the model “helpfully” regenerating client files. If you run a different assistant, the discipline transfers. This walkthrough on configuring Continue.dev with real prompts shows the same guardrails wired into an open-source stack.
Step 2: Scope the Context Yourself Instead of Hoping for the Best
Typing @ in the chat box pulls up an index of your repo. Three of them do most of the work:
- @file for one file, e.g. @file src/routes/orders.ts
- @folder to pull a whole directory, e.g. @folder src/services
- @git to include your staged diff, which is how you get feedback on work in progress
That repo-wide index is the part that separates Cursor from a chat window bolted onto a text editor. It can trace a symbol across files, which a raw paste-and-ask session cannot.
For our pagination job, the first message was:
“Using @file src/routes/orders.ts, @file src/services/order-service.ts and @file src/schemas/order.ts, I want to replace offset/limit pagination with keyset pagination on (created_at, id). Show me the changes you’d make but don’t write them yet.”
Notice the last sentence. Asking for a plan before code costs ten seconds and regularly saves an hour, because you catch the wrong assumption before it spreads across four files.
Step 3: Use Tab and Inline Edits for Anything Local
Not every change deserves the chat panel. Tab completion suggests multi-line edits as you type, and Cmd+K (Ctrl+K on Windows) opens an inline prompt that rewrites only the selected block.
A Cmd+K prompt that beats “improve this”
Select the body of getOrders, hit Cmd+K, and type:
“Keep the signature identical. Return { items, nextCursor } where nextCursor is base64 of created_at and id, or null when there are no more rows. Use the existing query builder, no raw SQL.”
Two details carry the weight. “Keep the signature identical” prevents a cascade of type errors in every caller. “Use the existing query builder” keeps the diff consistent with the rest of the file. Vague instructions get you a rewrite you throw away.
Step 4: Hand Multi-File Work to Agent Mode and Read the Diff
When the change spans route, service, schema and tests, switch to Agent mode and describe the outcome, not the edits:
“Add keyset pagination to GET /api/orders. Update the zod schema, the service, the route handler, and add two tests: a first-page case and a stale cursor that returns an empty list. Follow the project rules. Run the test suite when you’re done.”
Agent mode reads files, edits them, runs commands and iterates on failures by itself. The half of that instruction that matters most is the last one. Left alone, a model will confidently declare success on code that doesn’t compile.
What to check before you accept
- Did it add a database index on (created_at, id)? Usually not, and a keyset query without one degrades fast.
- Did it keep the old offset parameters “for backwards compatibility,” leaving you two code paths to maintain?
- Are the tests asserting real behaviour, or just that the function returns an object?
Step 5: Feed It Failures, Not Descriptions of Failures
Paste the raw output. Not “the test is failing,” but the whole assertion diff with the file and line number. Cursor is unusually good at matching an error to a cause when it can see both the stack trace and the source.
If your team mixes assistants, the loop is portable. A step-by-step Codeium workflow for writing, testing and refactoring follows the same rhythm: scoped context in, pasted failures back, diff reviewed.
Step 6: Get a Second Opinion From a Clean Context
One habit worth building. After Agent mode finishes, open a brand new chat with no history and ask it to review @git for bugs. A fresh session finds different things than the session that wrote the code, because it isn’t anchored to its own reasoning.
Then run your linter and type checker yourself. Model confidence has no relationship to correctness.
Where This Workflow Breaks Down
The loop above works because the project has clean seams: schemas in one place, services in another. When those seams vanish, output quality drops with them.
- A 900-line route file gives the model too many plausible places to put logic
- Conventions that live only in your head never reach the rules file
- Copy-pasted helpers across modules means @file pulls in the wrong one
At that point it’s a code problem before it’s a tool problem. There’s a good argument that architecture quietly erases the signals an AI agent depends on, and every oversized function is a little of that happening.
Prompts Worth Keeping in a Scratch File
- “Read @folder src/services and summarise the conventions you see. Don’t write code.”
- “List every caller of this function before changing it.”
- “Write the failing test first, run it, then make it pass.”
- “Show me three approaches with trade-offs, then wait for my pick.”
- “Review @git for bugs. Be specific about file and line.”
The gap between people who get real value from Cursor and people who bounce off it is rarely the model. It’s whether they front-load context and verify what comes back. Write the rules file this afternoon. It takes fifteen minutes and quietly changes every request you make after it.

