Skip to content

GitHub Copilot in VS Code

Lesson 2 of 8Intermediate14 min readGitHub Copilot & AI Engineering · GitHub CopilotVerified: VS Code Copilot documentation and GitHub customisation support matrix, September 2026

VS Code is Copilot’s most complete surface. Features generally appear here first, and the customisation matrix is fullest here — which makes it the reference implementation and, occasionally, a misleading one: what works in VS Code does not necessarily work anywhere else.

This lesson covers what the editor offers and, importantly, which parts are VS Code specific.

VS Code exposes several distinct ways to work, and choosing the right one is most of using it well.

Inline suggestions. Completions as you type. Narrow context, high frequency, low verification cost.

Inline chat. A conversation anchored to a selection, in place. Good for “explain this” and “change this to do X” on a bounded region.

Chat view. The conversational panel. Attach files, ask questions, iterate.

Smart actions. Context-menu operations — explain, fix, generate tests, generate documentation — that are essentially pre-written prompts with the right context already attached.

Agents. The autonomous surface: multi-step tasks, file edits, terminal commands, iteration. This is where VS Code has moved furthest, and it has its own vocabulary.

Worth knowing because the terms are specific and appear in the interface.

The agent loop — the cycle of planning, acting, observing the result and adjusting. This is what distinguishes an agent from chat that produces edits.

Sessions — agent work you can pause and resume, rather than a single request-response.

The agent harness — the coordinating layer that runs the loop. Relevant because it can differ: VS Code has its own, and Copilot CLI is increasingly used as a harness across surfaces.

Subagents — separate agents spawned to handle delegated work in an isolated context, allowing parallel or background work. A subagent’s context is its own, which is the point: it keeps a large subtask from consuming the main conversation’s context.

Execution environments — agents can run against your local machine, remote machines, or cloud infrastructure. Which environment an agent is operating in determines what its commands can reach, and is worth being deliberate about.

Remote agent sessions and the Agents window provide views onto work running elsewhere, including sessions started as cloud agent tasks.

The single most effective habit in VS Code: attach the files that matter rather than relying on the editor to infer them.

What contributes context, roughly in order of reliability:

What you explicitly attach. Files, selections, symbols. Deterministic, and the thing you control.

The active editor and selection. Usually included.

Workspace search. The agent surfaces can search and read files they judge relevant. Powerful, and non-deterministic — it may not find the file you had in mind.

Terminal output. Where the integration exposes it, a failing command’s output is available, which is what makes the run-read-adjust loop work.

The practical consequence, repeated from the cluster hub because it matters more than any other technique: an answer that seems wrong is usually an answer given without the file that would have made it right. Attaching a caller, a test or an interface definition improves output more than rephrasing ever does.

TaskMode
Finish a line or an obvious blockInline suggestions
Rename, extract, tighten a selected regionInline chat
Understand unfamiliar codeChat view, with the file attached
Generate tests for a specific functionSmart action, or chat with the file
A change across several filesAgent
Anything requiring run-read-adjustAgent
A long task you want to step away fromAgent session, or delegate to the cloud agent

The escalation principle: start with the least autonomous mode that can do the job. Inline chat on a selection is easier to verify than an agent editing six files, and if it suffices it is the better choice.

VS Code supports the fullest set, which is convenient and is the source of the most common cross-surface confusion.

MechanismLocationNotes
Repository instructions.github/copilot-instructions.mdAlways on
Path-specific instructions.github/instructions/**/*.instructions.mdApplied to matching files
Agent instructionsAGENTS.mdRead by agent surfaces
Prompt files.github/prompts/*.prompt.mdPublic preview, and IDE-only
Agent skills.github/skills/<name>/SKILL.mdLoaded when judged relevant
Custom agents.github/agents/NAME.mdSelectable personas with tool restrictions
MCP serversmcp.jsonExternal tools and data
Hooks.github/hooks/*.jsonPreview in VS Code
Pluginsplugin.json packageBundles of the above

VS Code also supports bring-your-own-model configuration alongside the standard model picker, which is relevant for organisations with a specific model requirement.

VS Code is where MCP configuration is most commonly done, and the mechanics are worth knowing here even though MCP + GitHub covers the concept properly.

Servers are configured in an mcp.json, and once connected their tools become available to the agent alongside its built-in ones. The GitHub MCP server is the common first one — it gives an agent the ability to read issues, pull requests and repository metadata without you pasting them.

Two configuration decisions matter more than the rest.

Read-only where possible. The GitHub MCP server supports a read-only mode — a /readonly URL suffix on the remote server, or the equivalent environment setting locally — which disables write tools entirely. For most day-to-day use, reading issues and pull requests is the whole value, and write access adds risk without adding much.

Only what you need. Each connected server expands both capability and attack surface. A server connected because it was available is a set of tools an agent may use, and a route by which untrusted content can reach it.

The trust question is the same one as for plugins: an MCP server is code you are giving an agent the ability to invoke. Third-party servers deserve the scrutiny of a dependency.

VS Code exposes browser tooling that lets an agent load a running web application, interact with it and observe the result — closing the loop for front-end work in the way that running tests closes it for back-end work.

The engineering value is real: an agent that can see that its change rendered incorrectly can fix it, where one working only from source cannot. It is the observe step applied to a domain where the observable behaviour is visual rather than a test result.

Two cautions. What it validates is what it looked at — a rendered page in one viewport, not your accessibility requirements or your browser support matrix. And an agent driving a browser against a running application is an agent interacting with whatever that application is connected to, which should be a local development environment rather than anything shared.

The failure mode on long agent runs is not usually a wrong decision. It is context exhaustion, which presents as the agent becoming vaguer, repeating itself, or losing track of a constraint it was given twenty minutes earlier.

Three mechanisms address it.

Sessions let work pause and resume rather than living in one unbounded conversation.

Subagents isolate a subtask’s context. Delegating “read these forty files and tell me which ones handle authentication” to a subagent keeps forty files out of the main conversation — the answer comes back, the reading does not.

Starting fresh. Underrated. A new session with a tight goal and the two relevant files attached frequently outperforms continuing a session that has drifted.

The signal to watch for: when the agent starts re-reading files it has already read, or asking about something you established earlier, the context is full. Continuing past that point produces work you will have to check more carefully than work done fresh.

The agentic features can edit files and run commands, so VS Code exposes trust and safety controls including permission level settings.

The considerations mirror the CLI’s, because the underlying question is identical:

What can it edit? Workspace scope, and whether it can reach outside it.

What can it run? Terminal command approval. This is the control that matters most, because a command has effects the editor cannot undo.

What is in your environment? An agent running commands in your integrated terminal inherits your shell environment — including any credentials in it.

The rule from the CLI cluster applies unchanged: narrow, specific allowances rather than blanket approval. Approval fatigue is real and “allow everything” solves it by removing the control.

Practical habits that improve results more than any configuration.

State acceptance criteria. “Add retry handling to the payment client; three retries with exponential backoff; existing tests must still pass; add a test for the exhaustion case” produces something judgeable. “Improve the payment client” does not.

Let it run the tests. The observe step is what makes the loop work. An agent that cannot see a failure cannot correct it.

Read the plan. Where the agent produces one before acting, that is the cheapest intervention point in the whole interaction — correcting a plan costs a sentence, correcting six edited files costs a review.

Interrupt early. If the first two actions are heading somewhere wrong, stop. Agents commit to an approach, and a long run in the wrong direction is harder to salvage than a fresh start.

Review the diff, not the conversation. The conversation is the agent’s account of what it did. The diff is what it did. Use VS Code’s source control view.

The canonical agent task, done in a way that keeps it verifiable.

The task. Add a timeout parameter to an HTTP client, thread it through the three call sites, and cover it with a test.

  1. Branch first. git switch -c agent/client-timeout.

  2. State the criteria, not the steps:

    Add an optional timeout parameter to HttpClient.__init__, defaulting to 30 seconds. Thread it through to the underlying request calls. Update the three call sites in services/ to pass the value from configuration. Add a test that asserts the timeout is applied. Existing tests must still pass.

  3. Read the plan. If it proposes changing the request library or refactoring the client, stop — the plan stage is where that costs nothing to correct.

  4. Let it run the tests. The observe step. It should notice its own breakage.

  5. Review the diff, not the transcript. Specifically: are there exactly three call sites changed, and is the default what you asked for?

  6. Run the tests yourself. The agent’s report that they pass is a claim; running them is evidence.

  7. Check what it did not mention. A quick git diff --stat shows whether the change is the size you expected. A surprise here is the most common finding.

Steps 5 to 7 take three minutes and are the entire difference between delegation and hope. Step 7 in particular catches the class of thing agents do quietly — reformatting a file it touched, updating an unrelated import, adding a dependency.

When Copilot behaves unexpectedly, the causes cluster.

Instructions not applying. Check the file path exactly — .github/copilot-instructions.md, not .github/COPILOT_INSTRUCTIONS.md. Path-specific instructions apply only when matching files are in scope.

A feature is missing. Plan, organisation policy, or preview status. Policy is the most common and the least visible.

Answers ignore obvious context. It was not attached. Attach it explicitly rather than assuming workspace search found it.

The agent stops short. Frequently a context limit on a long session. Starting a fresh session with a tighter goal usually works better than continuing.

Suggestions contradict conventions. Either the instructions do not say it, or they say it among two hundred other lines. Instructions are followed less reliably as they grow.

VS Code is not always the right place, and knowing when to leave it saves time.

Stay in VS Code for anything where you want to see the diff as it happens, where the work is code-centric, and where you will iterate on the result. That is most feature work.

Move to Copilot CLI when the context is terminal output — a failing build, a kubectl response, a Terraform plan. Copying that into an editor loses fidelity, and the CLI can run the commands itself.

Move to the cloud agent when the task is well specified and you do not want to watch. The trade is supervision for a pull request you review afterwards.

Use code review for work somebody else wrote. Reviewing a colleague’s branch in your editor is possible and loses the review thread that the pull request keeps.

The three surfaces share configuration, which is what makes moving between them cheap: repository instructions, skills and custom agents apply in all of them. Prompt files do not, which is the portability trap from earlier and the main thing that ties a workflow to the editor.

Keeping the editor’s features in perspective

Section titled “Keeping the editor’s features in perspective”

VS Code ships Copilot features fastest, which produces a specific bias worth naming: it is easy to build a workflow around something that is preview-only, editor-only, or both.

A useful discipline when adopting a new capability:

Ask whether the team can use it. A feature behind a preview flag or an individual setting is not something a repository can depend on.

Ask whether it survives leaving the editor. Configuration in the repository travels; configuration in your VS Code settings does not.

Ask whether it is load-bearing. A convenience that disappears is an inconvenience. A control that disappears is a gap.

The durable investments are the ones in the repository: instructions, skills, custom agents, hooks, MCP configuration. Those work across surfaces, get reviewed, and outlive whichever editor a given contributor uses — which is the argument the next lessons make in full.

Relying on workspace search instead of attaching files. Non-deterministic where you needed deterministic.

Using an agent for something inline chat would do. More autonomy than the task needs is more to verify.

Approving terminal commands without reading them. The editor’s undo does not cover a shell command.

Building a workflow on prompt files and expecting it in code review or the CLI. They are IDE-only and in preview.

Working on a branch you care about. One command prevents it.

Reading the conversation instead of the diff. The diff is what happened.

Letting instructions grow. Long files are followed less reliably, not more.

VS Code’s source control view is the right tool for this, and using it well is a short list.

Read the diff file by file, not the summary. The summary is the agent’s account.

Check the file list first. git status or the source control panel. Files you did not expect are the highest-signal finding, and they are invisible if you only read the files you were thinking about.

Look for the things agents do quietly. Reformatting a file it touched. Adding an import that is now unused. Updating a lock file. Changing a comment to match a rename. None are wrong; all are things you did not ask for and should notice.

Stage selectively. VS Code lets you stage individual hunks. Staging the parts you have reviewed, and leaving the rest, turns a large agent diff into something you can work through — and the leftover unstaged changes are exactly the ones that need a second look.

Commit in logical pieces. An agent produces one large change; your history does not have to reflect that. Splitting it as you review produces both better history and a more careful review, for the same reasons as git add -p.

VS Code is where Copilot is most capable and most configurable. That makes it the best place to learn what the tooling can do, and the worst place to assume that what you built will work everywhere else.

  • VS Code offers inline suggestions, inline chat, chat view, smart actions and agents
  • The agent loop — plan, act, observe, adjust — is what distinguishes agents from chat with edits
  • Sessions, subagents and remote sessions manage long or parallel work and its context
  • Attached context is deterministic; workspace search is not
  • Escalate to the least autonomous mode that can do the job
  • VS Code supports the fullest customisation set, including prompt files and hooks in preview
  • Prompt files do not work on github.com or in Copilot CLI
  • Terminal command approval is the control that matters, because commands are not undoable
  • Read the plan, interrupt early, and review the diff rather than the conversation

Use a disposable repository open in VS Code.

  1. Ask a question about a function without attaching the file, then with it attached. Predict: how different are the answers?

  2. Add .github/copilot-instructions.md with a specific convention. Ask for code that would violate it. Predict: does it comply?

  3. Use inline chat on a selection to rename a variable throughout a function. Then ask an agent to do the same across the file. Compare effort and verification cost.

  4. Give an agent a task with explicit acceptance criteria, on a fresh branch. Read its plan before it acts. Predict: would you have caught a wrong approach at the plan stage?

  5. Let it run the tests. Predict: does it correct itself when one fails?

  6. Review the resulting diff in the source control view rather than reading the chat. Predict: does the diff contain anything the conversation did not mention?

  7. Delete the branch.

AI-assisted engineering learning pathEleven lessons on getting value from Copilot and agents without giving up review discipline.