Working inside Cursor / Claude Code / Aider / Copilot
Claude Code: planning prompts
Claude Code, Cursor's agent mode, and similar agentic CLIs work differently from a one-shot prompt. They run a loop: read files, propose a change, apply it, run tests, observe the result, decide what to do next. Prompting these tools is less about getting one good output and more about bounding the agent's behaviour so it doesn't go in circles or off-script.
The single most useful pattern is the plan-then-execute prompt. Before the agent touches any file, it states what it intends to do. You read the plan, approve or adjust it, and only then does the agent edit code.
A good plan-then-execute prompt looks like this:
I'm going to ask you to refactor
src/auth/session.tsso thatvalidateSessionis async and returnsnullinstead of throwing on invalid tokens.Before you change any file, output a plan in this format:
Files I will edit
- (one bullet per file)
Changes per file
- (one bullet per change, with the function or section name)
What I will NOT do
- (one bullet per non-change to confirm understanding)
Wait for me to reply "go" before applying the plan.
The "wait for me to reply 'go'" is the gate. Without it, the agent often acknowledges the plan and immediately starts editing. With it, you get a checkpoint where you can correct misunderstandings cheaply.
Why does the "What I will NOT do" section matter so much? It catches the most common agent failure: silent scope creep. The agent decides that since it's editing session.ts, it should also "improve" the imports, fix a typo in a comment, or extract a helper. Every one of those is an unwanted change disguised as helpfulness. By forcing the agent to enumerate non-changes, you make it commit to leaving things alone.
The plan-then-execute state machine:
A good plan-then-execute response looks like this (paraphrased):
## Files I will edit
- src/auth/session.ts
- src/auth/session.test.ts
## Changes per file
- session.ts: change `validateSession` to `async`, return `null`
on invalid token, remove the `throw` path
- session.test.ts: update existing tests to await the call,
add new test for the null-on-invalid case
## What I will NOT do
- Will not change other functions in session.ts
- Will not modify imports unless required by the new async signature
- Will not refactor adjacent code for style or clarity
You read the plan in fifteen seconds. If it looks right, you reply go. If something's off, you reply with a correction: "Skip the test file — the test will be added in a separate PR." The agent updates the plan and asks for go again.
A second pattern useful for longer agentic sessions: invariants. State up front the things that must remain true throughout the session, and ask the agent to confirm them after each step.
Invariants for this session:
- The repo must always pass
npm run typecheck.- No new dependencies in
package.json.- No modifications to files outside
src/auth/.After each apply, run typecheck and report whether invariants 1, 2, 3 still hold.
Now the agent has a self-check. If a step breaks an invariant, the agent surfaces it immediately rather than letting the breakage pile up.
This is also why agentic prompts tend to live in long context windows. The plan, the invariants, the running observations — they all need to remain visible to the model so it can act consistently. Short context windows force constant re-prompting; longer ones let the agent stay aligned for entire feature-sized sessions.
Next up: shaping Copilot completions with the comments above the cursor. :::
Sign in to rate