Course · Cursor · Context · @-tag & self-gathering
Self-gathering, hand-pinning, and chat as your session
Self-gathering context
Section titled “Self-gathering context”The headline change in Cursor 2.0 is that you often don’t have to point at anything at all. Self-gathering context (agentic retrieval) means the agent pulls its own context - it searches the codebase, reads the files it decides are relevant, and follows references on its own, rather than waiting for you to @-tag everything up front (typing @ to attach a file or folder to your prompt). The 2.0 changelog puts it directly: the agent “can now self-gather context without needing to manually attach it in the prompt input” - which is exactly why the older @Web, @Definitions, @Link, and @Linter Errors menu items were retired. (source)
What this looks like in practice on budgetcli, the course’s illustrative TypeScript personal-finance API: you describe the problem in plain language and let the agent find the code. This chapter pictures budgetcli as a monorepo with an API surface, a worker under apps/worker/ that fetches and parses incoming transaction feeds, and shared utilities under packages/shared/; those paths illustrate that layout and are not files in a shipped repo.
> transactions from one feed show up with no merchant name. everything else gets one. find why and fix it.
• Searching: merchant, payee, counterparty • Reading apps/worker/src/extract.ts, apps/worker/src/fetch.ts • Reading packages/shared/src/transaction.ts
The extractor reads the payee field, but this feed serves it under the key "counterparty" instead of the spec's "merchant". The selector only matches merchant=, so the merchant name is dropped…No @-tags. You named a symptom; the agent’s own searches over its local index found extract.ts - a file you might not have known to point at. On a repo you don’t fully know yet (and an inherited budgetcli is exactly that), self-gathering is often better than hand-pinning, because the agent’s search isn’t limited by your incomplete mental map of the layout. The honest rule: for “find where X happens” problems on familiar-enough code, describe the problem and let it gather. Reaching for @-tags first, out of habit, can actually narrow the agent to a worse slice than it would have found itself.
But “often better” is not “always.” There are cases where retrieval reliably guesses wrong, and knowing them is what turns two gestures into one skill.
When hand-pinning still wins
Section titled “When hand-pinning still wins”Self-gathering is a retrieval heuristic, and heuristics have failure modes you can predict. Two cases where you should pin context by hand rather than trust auto-gather:
1. Large or sprawling repos, where retrieval surfaces the wrong slice. The bigger and more uniform the codebase, the more ways there are for the agent’s searches to land in a plausible-but-wrong neighborhood. budgetcli has three packages that all have a client.ts; a query about “the API client” can pull the API surface’s fetch wrapper when you meant the worker’s upstream HTTP client. The agent then reasons fluently about the wrong file. Symptom to watch for: the agent’s edits touch a package you didn’t expect. The fix is to stop describing and start pointing - @-attach the folder apps/worker/ or the file apps/worker/src/http.ts - to fence retrieval into the right subtree.
2. Ambiguous symbols, where a name resolves to the wrong definition. This is the sharpest case. budgetcli defines parse() in the worker’s feed extractor and re-exports a different parse() from a shared util. Ask the agent to “fix parse” and self-gathering has to guess which one you mean from surrounding context - and it can guess wrong, confidently, because both are real. Cursor used to offer a by-name symbol attachment (@Code) for exactly this, but that menu entry was removed around the 2.0 release (forum discussion), so the durable disambiguation move today is to pin the file that holds the right definition and name the symbol in prose - the file scope rules out the other parse() even though you can’t pin the function directly:
> the feed extractor's parse() drops the amount field on pending rows. fix parse() in @apps/worker/src/extract.ts - not the shared util's parse.
• Reading apps/worker/src/extract.ts
Fixing the pending-row branch in this file's parse()…The pattern under both: auto-gather is a guess; hand-pinning is a constraint. When the cost of the agent guessing wrong is high - a big repo where wrong means “edited the wrong package,” or an ambiguous symbol where wrong means “fixed the wrong function” - spend the two seconds to pin and remove the guess. When the cost is low and your map of the code is incomplete, let it gather. That judgment, not a rule about always- or never-tagging, is the skill.
Continuity: the chat is your session
Section titled “Continuity: the chat is your session”Everything above lives inside a chat, and in the editor the chat is also your continuity layer - Cursor keeps a history of past conversations you can reopen, so context you built up doesn’t vanish when you switch tasks or close the window. The deliberate move that matters here is the opposite of resuming: start a new chat when you switch tasks. A fresh chat gives the agent a clean window with none of the previous task’s material - which both improves output and delays hitting the context limit. Cursor can compact a conversation to free up space in the context window (the CLI exposes this as /summarize, with /compress as an alias), but compaction is lossy, so you’d rather not lean on it for unrelated work. Riding one long thread across three different bugs is how the agent goes hazy; a new chat per task is how you keep each window sharp. Here’s that judgment made visible - a session playing out with its context window x-rayed, pausing where you’d have to decide. The commands and repo wear generic names (the replay’s billing-app is an illustrative stand-in, not budgetcli); in Cursor, /compact is the CLI’s /summarize (/compress is an alias), and /clear is starting a new chat:
This is also where the editor and the CLI differ in ergonomics - though less than you’d expect. Cursor’s CLI is the agent command (cursor-agent is the legacy alias of the same tool; CLI changelog). It does not trade the @ primitive for flags: its docs describe selecting files and folders with @, the same attach gesture as the editor (using the CLI). And the continuity moves above have direct terminal spellings: /clear starts a new chat session (/new, /new-chat, and /newchat are aliases), /resume reopens a recent chat, and /fork branches the current chat into a new session (slash-command reference; spellings as of September 2026).
If you want the spec-level view of how any of these primitives are defined across tools, that’s Foundations: context window management. This chapter was the muscle memory: see how the window fills once, point when you know, let it gather when you don’t, and take the wheel back the moment the stakes of a wrong guess go up.
What the agent sees is one dial. Which engine reads it - and what that engine bills you for the turn - is the next one. Next: models, Auto, Composer, and billing.