EEEugenio Estrada
From Visual Studio to Copilot App: My Journey

From Visual Studio to Copilot App: My Journey

Eugenio Estrada
Eugenio Estrada
Artificial IntelligenceGitHub CopilotArchitectureSoftware Engineering
Listen to article
💡

My way of working has changed alongside Copilot

  • The journey: I went from Visual Studio Community to VS Code, then the CLI, and finally Copilot App, as the assistant evolved into an agent workspace.
  • The discipline: Skills and architectural guardrails help me explain how I want to work, but they do not replace tests or review.
  • The revelation: Fusion and Projects have changed my day-to-day work: one reduces how often I have to choose a model; the other brings together work that can span multiple repositories.
  • The cost: In my recent experience, completing a task usually costs much less than it used to. That is a personal observation, not a rate or a guarantee.

For a long time, GitHub Copilot was something that lived inside my editor. I asked for a suggestion, read it, accepted or rejected it, and carried on. I still review code; that has not changed. What has changed is when the conversation begins: now it starts much earlier, when I ask myself what problem I want to solve, which boundaries must not be crossed, where the context lives, and what work can be coordinated across repositories.

I did not get here in one leap. I moved through Visual Studio Community, VS Code, the CLI, and finally GitHub Copilot App. Each tool change also changed the way I trusted the assistant. And in the last few weeks, two things have genuinely caught me off guard in the best way: Copilot Fusion and Copilot App Projects.

I do not want to write an editor comparison or promise anyone a productivity miracle. I want to tell the story of how I have learned to work with something that can do more and more, and that therefore needs clearer boundaries from me.


Where It All Began: Visual Studio Community

My first experience with Copilot was not in Visual Studio Code, but in Visual Studio Community. Everything happened right next to the cursor: a suggestion appeared beside my code, and I decided whether it was worth keeping. It was there while I programmed, but it never occurred to me that it could become the center of anything.

Looking back, I feel a certain nostalgia for that direct relationship with code: an idea, the editor, and the patience to shape it. I do not miss every bit of friction from that time, or think things were better just because they were slower. But I do like remembering how much the way we share that process with a tool has changed.

It was useful from the start, and I also saw its limits straight away. There were times when it hallucinated: it assumed things existed when they did not, or suggested convincing solutions that did not fit the project. When it rewrote files, it sometimes introduced errors. I learned something I have not forgotten: a fluent answer does not mean the change is correct.

That distrust never went away. Over time, it turned into a much more useful question: what does the assistant need to know and verify before it touches anything?

Changing Ground: VS Code and Then the CLI

I moved to VS Code because that was where I could see the experience evolving fastest. It was no longer just about completing a line: project context, chat, and agent capabilities were taking up more space. The editor still mattered, but I was starting to think in units of work larger than the file I had open.

Then I moved to the CLI. There, the agent worked alongside the same tools I use to understand and validate a repository: reading files, searching for references, running commands, and seeing what happens. For me, the difference was not that the model answered better; it was that I could ask the environment and check some of what it proposed.

That is what I call the harness: not just the model, but everything around it that organizes context, tools, permissions, instructions, and the execution loop. Editing tools make it possible to keep changes more focused than rewriting an entire file; language-server integrations through LSP can provide information about symbols and diagnostics; and MCP opens the door to connecting external services. What is available depends on the environment and how it is configured.

Seeing the harness built by GitHub’s team evolve into the Microsoft Copilot harness, and extend beyond GitHub Copilot, makes me look at this journey differently. What began for me alongside the code is becoming a shared foundation for different agent and model experiences. It reinforces something I have learned along the way: the model matters, but so does the environment that lets it act.

None of this puts an end to hallucinations or guarantees a change is right. But it did change how I talk to the agent: I no longer have to accept an assumption when there is a tool that can check it. For me, the leap was not giving up review. It was having more evidence in hand when I reviewed.

Arriving at Copilot App

Copilot App was the next stop. For the first time, I could keep agent sessions close to the repositories, branches, issues, and pull requests I was already working with. I could also run several tasks in separate workspaces and decide how much autonomy to give each session. It felt like moving from a collection of separate pieces to seeing the work as a whole.

Git worktrees also became part of my day-to-day work with the app. Each session can work in its own directory and branch while I carry on elsewhere, without the changes getting mixed together. Worktrees share the Git repository data but keep working files separate, so I can work in parallel without cloning the entire repository for every task. I go into more detail in my article on Git worktrees and context switching.

I am careful not to mistake file isolation for a security boundary or a fix for conflicts between changes. I still need to review each branch and see how the pieces fit together when they meet again.

The editor still matters to me. What has changed is where I organize the work: I can frame a task, follow a session, and review its changes without everything having to happen in the tab of the file I am editing.

And that is when I realized something: the more autonomy I give an agent, the more clearly I need to explain what I want. What outcome I am after, what it must not break, and when it should stop. That is why skills and architectural guardrails have taken a central place in the way I work.

Learning to Delegate Without Losing Context

Skills: Writing Down How I Work

A skill lets me capture how I approach a type of task and reuse it without writing the same instructions from scratch every time. I organize it in a folder with a SKILL.md file and, when needed, resources or scripts. Copilot can load it when the task and the skill description make it relevant.

The distinction that works for me is this: general instructions describe a repository’s usual rules; a skill brings together the process and context for a specific task. Instead of expecting the agent to guess how I want to work every time, I make it explicit and reviewable.

Writing a good skill takes more than making a wish list. I try to think about what should trigger it, what information it needs, which steps really matter, and how to verify the result. I also try to keep it focused: a huge instruction that attempts to solve everything ends up competing with the task for context.

I am not kidding myself: skills are not an infallible barrier. The agent can misread them, apply them only partially, or rely on an outdated version. That is why I treat them as part of the project: they need review, maintenance, and checks, especially when they include scripts or come from third parties.

Guardrails: Making Room for Autonomy Without Losing the Architecture

The other piece is architecture guardrails: boundaries that say which architectural decisions must be respected when the code changes. To me, they are not a magic setting in the app or a guarantee that everything generated will be right. They are a combination of instructions, conventions, and verifiable checks.

An instruction can explain which dependencies are allowed between layers, what the integration rules are, or where each responsibility belongs. A test, static analysis, or review policy can verify some of those rules. They complement one another: an instruction guides; an executable check detects the violations it knows how to measure.

That distinction matters a lot to me. If I only ask an agent to respect the architecture, it can do so superficially. If I also spell out the boundaries and have tests that fail when they are crossed, the safety net is much more tangible. No test captures the full intent of a design, and no guardrail replaces a person reviewing the trade-offs around performance, security, and maintenance.

I can give the agent instructions inside the repository. But deciding which constraints should exist, how they are enforced, and when they need to change is still our responsibility.

Linear and Better Stack: Context Beyond the Code

Code does not contain all the context behind a task. My workflow also includes Linear, for project management, and Better Stack, for incident tracking. Bringing that context closer to the agent saves me from starting every conversation with a description disconnected from the actual work.

With Linear, I distinguish between its GitHub integration and giving a local session direct access to Linear. The Copilot integration lets me start and steer cloud agent sessions from a Linear issue, using its description and comments as context. That does not mean every Copilot App session can browse my entire Linear workspace on its own: access depends on the integration and its configured permissions.

For Better Stack, I use MCP. Its server can connect assistants to incident and telemetry information, among other things. What it can do depends on authentication and which tools are enabled; if a task only involves investigation, write access is not necessary.

These connections are useful to me, but they also expand the surface I need to trust. An issue, a log entry, or an external response can contain incomplete information or instructions that should not be treated as authoritative. That is why I prefer least-privilege access, pay attention to what enters the context, and review anything that could have effects outside the workspace.

Models and Costs: What I Have Observed

As I have learned to delegate better, I have also seen costs change. I have noticed a major improvement in token efficiency from the GPT 6 family, especially 6.1, while Copilot billing has moved from premium requests to GitHub AI Credits.

For the tasks I have observed, I have gone from seeing costs of 5to5 to 20 per task to figures that tend to fall between 0.50and0.50 and 3. It is rare for a task I work on to exceed that latter amount now. These are my observations, not a controlled study or a forecast for other accounts; with this data, I also cannot separate the effects of the model, the harness, context, task complexity, or the billing change.

With usage-based billing, the cost depends on the model and the input, output, and cached tokens; one AI Credit equals US$0.01. Since plans and allowances vary, I compare periods, tasks, and plans, not just model names.

What has changed for me is the sense that experimenting and iterating is now within reach for more tasks. That shift in scale is a useful lead-in to the two features that have caught my attention most lately: one changes how models are selected, the other how work is coordinated.

Fusion and Projects: Choosing and Coordinating Together

Copilot Fusion: Letting Go of the Model Selector

For much of this journey, choosing the model was part of every task. With Copilot Fusion, I no longer choose a specific model; I choose a system that decides at runtime which models and execution pattern to use. It can handle a request with one model, escalate a draft, or bring in several models to critique a response.

The selectable levels serve different purposes:

  • Fusion Standard balances cost, quality, and latency, choosing one model for each task.
  • Fusion High allows broader orchestration for substantial, well-scoped tasks, when additional model calls may be worthwhile.
  • Fusion Max prioritizes capability and deeper reasoning while still taking efficiency into account.

Over the past few weeks, Copilot Fusion Standard has become my default way of working.

Availability depends on the plan and which models are enabled. There is also Fusion Fast for a specific VS Code inline-chat scenario, but it is not a level I can select in Copilot App.

What affected me was not that Fusion makes decisions disappear, but that it moves some of them elsewhere. I can put more thought into defining the problem and the level of effort I need, and less into manually deciding which model should step in at each point. That does not mean High or Max will always save money: they can make additional calls and use more credits.

There is another nuance I do not want to miss: Fusion and subagents are different things. Fusion does not start subagents by itself. And if it discards a draft, changes that draft has already made in the workspace are not automatically undone. Reviewing the result and the diff is still essential.

Projects: Moving Beyond One-Off Tasks

If Fusion changed how I think about models, Projects changed how I think about the scope of work. I can now start with a goal and keep sessions, results, and progress around it, instead of losing the thread between separate tasks. Work can span several repositories, stay within one, or need no repository at all; I can also organize recurring tasks. Projects is still in public preview, so I keep in mind that the experience may change.

For me, the difference is between asking for an isolated change and keeping sight of a larger goal. Rather than treating every session as a conversation unrelated to the others, I can organize the work around a shared intent and follow its results. When several repositories are involved, that coordination matters even more, because the problem I want to solve does not always fit within a single repository boundary.

That does not mean the app automatically understands every dependency or can merge changes without judgment. Each session needs a clear scope, enough context, and a way to verify its result. When pieces depend on one another, I still need to decide the order, review the contracts between repositories, and test the whole. A set of individually correct changes does not guarantee a correct integration.

Fusion and Projects have been my two big revelations of the last few weeks precisely because they work at different levels: Fusion organizes model use within a request; Projects helps coordinate work toward a goal. Confusing the two would mean missing what interests me most about having them together.

GitHub as a Hub and Remote Control

There is another piece that completes this way of working: keeping GitHub as a hub for repositories, issues, pull requests, and sessions without always having to be at my machine. For Copilot CLI sessions where remote control is enabled, I can follow progress and respond to questions or permission requests from GitHub.com or GitHub Mobile.

I want to be precise here: remote control does not turn a local session into one that runs in the cloud. The work continues on the local machine; the web or mobile app is another window for following and steering it. I also do not assume that every Copilot App session has exactly the same options: that depends on the surface and its configuration. What I value is being able to keep the thread close to GitHub without confusing where I view it with where it runs.

Looking Beyond a Single Provider

Once work is organized around projects and agents, the question I ask is where each part should run. In the CLI, I can connect directly to provider APIs such as OpenAI or Anthropic, use a router such as OpenRouter, or point to a compatible endpoint serving local models through Ollama or vLLM, on my machine or on my own on-premises infrastructure. That flexibility is specific to this workflow; it does not mean every provider is available across every Copilot surface. The model still needs to support the agent loop, including tool calls and streaming responses. And if the endpoint is outside my machine, my data is not staying local either.

It makes me happy that someone close to me is building in this space too: QDivZero, the platform created by my friend José Carlos García, lets people access models through an OpenAI-compatible API and deploy their own models on dedicated GPU infrastructure. Its offering distinguishes between public models billed by tokens and dedicated deployments whose cost depends on how long they remain active. I like seeing initiatives like this open up more ways to choose which model to use and where to run it.

That is where open-weight models seem especially interesting to me. If a team can rent compute and pay for the time it is in use rather than for every token, it changes the way the numbers work. But the costs do not disappear: an idle GPU still costs money, and utilization, operations, latency, maintenance, and a model’s quality for the task all matter. I do not think time-based billing is always better; I do think having both options will matter a lot.

Another possibility that would have seemed distant to me not long ago is moving some inference onto the device and letting an agent combine local and cloud resources. I find it significant that this is beginning to take shape in an experimental Copilot preview: Fusion can route between selected local and cloud models, or I can choose a compatible local model. That does not mean the agent is offline; inference, tools, and network access are separate boundaries.

I am also intrigued by the new Surface RTX Spark Dev Box and Surface Laptop Ultra, announced with up to 128 GB of unified memory. That does not mean all 128 GB are available for model weights: the operating system, applications, and model context use memory too. Still, it changes what I can imagine doing locally. HydraFusion began as an experimental project for orchestrating multiple models, and Copilot Fusion carries that line of work forward; routing between local and cloud models is a new, experimental step. I do not conflate the two. I am interested in seeing how orchestration can extend to where inference runs.

My impression is that models keep getting more capable and more efficient with tokens. I do not see a clear sign that this progress will stop in the near term. If it continues, where inference runs, who operates it, and how it is billed could become decisions as important as which model we choose.

Back Where I Started

When I look back, I do not see a straight line from an imperfect tool to one that no longer needs anyone watching over it. I see the scope expanding: from suggestions beside the cursor to a system that can query tools, follow procedures, work in sessions, and coordinate broader goals.

My role has changed too. I need to explain the problem better, keep skills up to date, define architectural boundaries, control permissions, and review the evidence. Moving faster does not remove the hard questions: what behavior do we want, which trade-offs will we accept, and how do we know the result is right?

There is something exciting and a little strange about that change. The software engineering I knew has not disappeared: it is still there in the decisions, in the failures we need to understand, and in the care we take reviewing what we build. What is changing is how much of the journey we spend writing each line, and how much we spend guiding and checking the work of others, including agents.

When I try to put a timeline around all this, I find it hard to believe how much has happened in less than two years. Claude Code appeared in February 2025; OpenAI’s Codex cloud agent arrived in May, and its CLI had appeared a month earlier. Since then, agentic work has gone from an intriguing possibility to a real way of organizing engineering tasks. But the story did not start there: GitHub Copilot was introduced in 2021 as a collaboration with OpenAI, powered by Codex, an OpenAI model that GitHub contributed knowledge to during its development. The 2021 Codex was a model, not the Codex agent OpenAI launched in 2025; sharing a name does not make them the same product. I think it is more accurate to say GitHub’s team was among those who saw this early stage emerge and helped shape it, not that it trained that model on its own.

That is why Fusion and Projects have meant so much to me. Not because they do the engineering for me, but because they make it feel more natural to organize work around it. That is also why I am interested in choosing between cloud and local inference, and between models hosted by third parties and models I can operate in a different way. For me, it all began with a copilot that completed code. In less than two years, the way we work with software has changed at a pace I still find difficult to take in; more and more, my job is to give it context, judgment, and a path we can verify together.

Right now...

Reading
Prophecy: Lessons on the Use and Abuse of Prediction, from Ancient Oracles to AI

Prophecy: Lessons on the Use and Abuse of Prediction, from Ancient Oracles to AI

Various Authors

Project Hail Mary

Project Hail Mary

Andy Weir

The Infinite Pleasure of Mathematics

The Infinite Pleasure of Mathematics

Mathematical Outreach

Playing
Crimson Desert

Crimson Desert

Pearl Abyss

The Legend of Zelda: Ocarina of Time

The Legend of Zelda: Ocarina of Time

Nintendo · Nintendo Switch 2