A Coding Agent vs Copilot Autocomplete: What Changes When the Tool Can Edit the Repo
Quinn Reed
September 30, 2026
For two years my relationship with AI in the editor was a grey ghost of text and the Tab key. Copilot guessed the rest of the line, sometimes the rest of the function, and I either took it or kept typing. I was still the one moving through the file. The tool was fast, occasionally uncanny, and it never once touched a file I was not looking at.
Then I gave a coding agent a real ticket: swap our date handling from Moment to date-fns across a mid-sized TypeScript service. Forty minutes later I had a diff across nineteen files, a changed lockfile, two updated snapshot tests, and a new helper module I had not asked for. Most of it was right. Some of it was quietly wrong in a way that autocomplete had never been able to be wrong, because autocomplete had never been allowed to decide which files mattered.
That afternoon is the cleanest way I know to explain the difference. It is not that one tool is smarter. It is that the job of integrating the change moved from me to the tool, and the place where I say yes moved with it.
Autocomplete keeps you as the integrator
With inline completion, the unit of approval is tiny. A line, a block, maybe a test case. You see it appear at your cursor, in the file you chose, in the function you were already thinking about. You accept it with one key, and if it is wrong you usually know within seconds, because you are about to type the next line and the suggestion either fits your plan or it does not.
That tight loop hides how much work you are still doing. You picked the file. You held the call graph in your head. You knew that formatInvoiceDate is also used by the PDF renderer and the CSV export, so you went and changed those too. Autocomplete filled in keystrokes. The integration, the part where a change becomes coherent across a codebase, stayed in your skull.
I did not appreciate this until I stopped doing it. When people say Copilot made them “maybe 20% faster,” I believe them, and I think the reason the number is modest is exactly this: the expensive thinking was never delegated. You still walk the repo. You just walk it with less typing.
An agent takes the walk for you
A coding agent gets a goal instead of a cursor position. It searches, opens files, decides which ones are relevant, edits several of them, runs a command, reads the output, and edits again. The approval moment is no longer “does this line look right.” It is “is this whole diff the change I meant,” and you are answering that question after the fact, about work you did not watch happen line by line.
On the date-fns migration, the agent did several things I would have done more slowly. It found every Moment import, including two in a scripts folder I had forgotten about. It rewrote the formatting calls with the right format tokens, which differ between the libraries in small, annoying ways. It ran the unit tests and fixed a timezone assertion that failed.
It also did three things I would not have done. It created src/lib/dates.ts as a wrapper, which is defensible but was a design decision I wanted to make myself. It updated two snapshot files so the tests passed, and one of those snapshots now encoded a date that rendered a day early for users west of UTC. And it bumped a transitive dependency in the lockfile because the install step asked it to.
None of these would have been possible with autocomplete. Not because autocomplete is more careful, but because it never had the authority to create a file, run the tests, or touch the lockfile. The capability that saved me an afternoon is the same capability that introduced a timezone bug.

The errors change shape, not just size
Autocomplete mistakes are local and visible. A wrong argument order. A hallucinated method on an SDK. An off-by-one in a loop you are staring at. They are irritating, but they sit right under your eyes, and your next keystroke is effectively a review.
Agent mistakes are structural. The code in each file tends to look fine. The problem is in the relationship between files, or in a choice about scope. Did it change the thing the ticket was about, or did it also “tidy” the adjacent module? Did it update the test to match new behaviour when the behaviour was the bug? Did it pick the right one of two similar helpers, or create a third?
The snapshot problem is the one that stuck with me. Each file in the diff was reasonable. The test suite was green. The only way to catch it was to ask a question the diff did not prompt: why did an expected value in a fixture change during a library swap that should have been behaviour-neutral? A library migration that changes expected output is not a refactor. It is a behaviour change wearing a refactor’s clothes.
With autocomplete, I would have been the one editing that snapshot, and I would have felt the wrongness in my hands. With an agent, the wrongness arrived pre-packaged inside a passing build.
Where the time actually goes now
People frame agents as “more output per hour.” For me the more honest framing is that the time moves from writing to specifying and reviewing.
Before an agent run, I now spend five to ten minutes writing down what the change is and is not. For the date migration, the second attempt had lines like: do not create a wrapper module; do not modify any __snapshots__ files, report failing snapshots instead; do not touch the lockfile beyond adding date-fns and removing moment. That paragraph took longer to write than most of my autocomplete sessions lasted.
After the run, review is heavier than reviewing my own work, because I cannot rely on the memory of having made each decision. I read the diff file by file with the ticket open. I look for files I did not expect. I read every test change twice, since a changed assertion is the cheapest place for an agent to hide a disagreement with reality.
Net, the migration took me about ninety minutes including both runs and review. By hand it would have been most of a day, mainly the tedious search for call sites and the fiddly format-token mapping. That is a real win. It just is not a win of the “type a sentence, go to lunch” variety.
What I still use autocomplete for
I did not turn inline completion off. It is still the better tool for a specific kind of work: writing new code inside a function whose shape I already know. Filling in a switch over an enum. Writing the fifth test case after I have written four. Translating a SQL query into the query builder’s syntax line by line. In those moments I want a fast guess at my cursor, not a planner that goes off and reads the repo.
Autocomplete also wins when I am thinking with my fingers. Some code I only understand by writing it. Handing that to an agent produces code I then have to understand from scratch, which is slower than having written it. The suggestion-at-cursor model respects that my attention is the scarce resource and keeps me in the file.
Agents win on changes whose difficulty is mostly breadth rather than depth. Renames that cross packages. Library swaps. Adding a field that has to flow through a model, a serializer, an API schema and three tests. Updating call sites after a signature change. Anything where the hard part is finding all the places, not deciding what each place should say.
The heuristic I use: if I could describe the change completely in two sentences, and the tricky part is finding every place it applies, it goes to the agent. If I need to think while I write, it stays with me and the Tab key.

The repo has to be readable by something that is not you
Autocomplete mostly sees the file you are in and a few neighbours. It rarely matters that your repository layout is strange, because you are the one navigating. Once a tool navigates for you, the layout becomes an input.
The agent’s extra wrapper module came partly from our own mess. We had two half-finished date utilities already, utils/time.ts and helpers/formatDate.ts, neither obviously canonical. Faced with that, the agent made a third, cleaner one. I would have done the same thing as a new hire. The fix was not a better prompt. It was deleting one of the two old helpers and writing a one-line note in our agent rules file saying which module owns date formatting.
Autocomplete forgives a confusing repo because you are the map. An agent turns every confusing corner into a decision it makes on your behalf.
Permissions are the real difference
Strip away the marketing and the distinction is about what the tool is allowed to do. Autocomplete can propose text at your cursor. An agent can typically create and delete files, edit any file in the workspace, and often run shell commands: tests, installs, formatters, sometimes git.
Each of those permissions pays for itself on some tasks and costs you on others. Running tests lets it fix its own mistakes, and also lets it “fix” tests. Installing packages lets it complete the migration, and also lets it change your dependency tree. Editing any file lets it catch the forgotten call site in scripts/, and also lets it rewrite a module you never mentioned.
I now think about agent sessions the way I think about giving someone commit access. What should they be able to touch for this task? What would I want them to ask about first? Most tools let you narrow this, with approval prompts for commands or a mode that plans before editing. Using those controls feels slower at first. It is much faster than reverse-engineering a lockfile change you did not want.
What changed in my review habits
A few habits came directly out of the migration and have stuck:
- I start every agent task on a clean working tree. If the diff is the only change,
git diff --stattells me instantly whether the file list matches my expectations. - I read the file list before any code. Nineteen files for a library swap was plausible. A new file I did not ask for was the first flag.
- Test and fixture changes get read first, not last. They are where the tool records what it decided “correct” means.
- Lockfile changes get their own look. I diff the resolved versions, not just the manifest.
- If a change should be behaviour-neutral, any changed expected value is a bug until proven otherwise.
None of these were necessary with autocomplete, because I was present for every decision. They are the tax on delegation. I pay it willingly on the right tasks.
So which one do you want?
Both, for different moments. If your day is mostly writing new logic in files you understand, inline completion is still the tool that stays out of your way, and an agent may make you slower by making you review work you would rather have done. If your backlog is full of changes that touch many files for mechanical reasons, an agent will give you back hours, provided you accept that you have changed jobs from author to reviewer for those tasks.
The mistake I made on that first run was treating the agent like a bigger autocomplete: accept the output because it compiles and the tests pass. Autocomplete trained me to trust the green squiggle-free file under my cursor. An agent needs a different reflex. The question is not whether each line looks right. It is whether the tool made the same decisions about scope, structure and behaviour that I would have made, and the only way to know is to look at the parts of the diff I did not expect to see.
My date migration shipped on the second attempt, with no wrapper module, untouched snapshots, and one clean lockfile change. The agent did most of the typing. I did the deciding. That split is what actually changed when the tool got permission to edit the repo.