Refactoring Legacy Codebases

Chris Diaz May 21, 2026 1:00:00 77 transcript lines 31 terms defined Watch on YouTube Source page

Learn practical strategies for tackling tech debt and refactoring legacy code with AI agents, from implementation planning and content migration to browser iteration, subagents, and Bugbot review.

Terms in this video

Transcript

as uh as we're watching people join this meeting, it always reminds me of watching popcorn in the microwave. You know, you hear it popping a lot, right? And then it starts to slow down and trickle. And so, I'm watching the participants as they come in and watching for it to slow down before we get started.

This session is being recorded. And so, we will share the link in a follow-up. My name's Chris. I'm going to be hosting today. I'm part of our field engineering team here at Cursor. So, I work with a lot of our customers for implementation, adoption, and evaluation of our agentic coding solutions. Based out of Austin, Texas myself.

Um but excited to be presenting with you all today. Uh I'm going to hand it over to Matt for an introduction. Matt, would you like to say hi and share a little? Yep. Hi everybody. I'm Matt Kresky. Uh also on the field engineering team here. Really just making customers, helping customers adopt, and uh and get the most out of Cursor. Uh based out of Southern California. I see a few San Diego's and and uh in the chat. So, nice to meet everybody. Uh

I'll be moderating the uh the chat today. So, uh feel free to add any questions there. All right. So, just want to call out as we get started, right? There are a variety of surfaces where you can use Cursor. And we are going to be focused on using the Cursor desktop application today.

And also uh one of our cloud agent offerings. If you haven't tried or seen the SDK yet, this is new from us. We've got quite uh a few new releases and things that are coming from this. >> [clears throat] >> And you always have access to these self-serve resources as well. This cursor.com/workshops, this is where workshops like what we're recording today will be posted. And so you can see past workshops here and you after today's session you'll also be able to have this available

there to see as well. We also keep our blog up to date and publish articles there quite frequently, including research, new features, uh or big events happening within Cursor. And our docs are always a good source of information as well. So the work that I'm going to be doing today is I'm going to be walking through how um I'm migrating a legacy Spring application, uh where the front end's using Thymeleaf, and moving that to use React.

Um this is a an open-source repo called Pet Clinic. Maybe you've seen it before. It's it's a legacy Spring code base. And we're going to use the front end to rewrite and automate user acceptance tests. We've also uh I've kicked off a fully automated migration as well in this repo. And so we'll show what that looks like using cloud agents. But my approach is that I'll have used a few different sub-agents to help decompose this migration task into repeatable phases. And so each of those phases

are handled by specialized sub agents. And so this allows us to create a repeatable system for doing this type of work. But we've also set up some rules that provide constraints on patterns, conventions, and those are also going to help with ensuring a consistent, predictable migration.

The sub agents that are in use for this approach, first I start with an inventory sub agent. And so this is crawling through the code base to identify what are the different modules that need to be migrated, what's the path to prioritization. I then have a test generation agent that's going to create new tests >> [snorts] >> if the tests aren't already present. Because these tests will help us capture what the existing code does. Right? And so it gives us a baseline to

confirm if we're preserving that behavior or not as we migrate the code. And then when it comes to actually moving the Spring Thymeleaf code to React, I have a migration [clears throat] agent which is focused specifically on converting that code. And then at the end, I have a verification modernization agent that's looking at the migrated code and making sure that it actually produces the expected outputs that the identical code did, but is also refactoring it into a

um truly idiomatic way where we are using modern code conventions, right? And not just converting the syntax of one code to the syntax of another, but we're taking advantage of all the features and functionality that a modern language provides.

And so, like I mentioned earlier, we're going to show two different surfaces here. One's how I would approach this task very human in the loop, where I'm going step-by-step using cursor to help me with this. We're going to be creating and putting tasks in Linear today.

And I'll be using these Linear tasks to guide the work that the agent does. But then, I'm also going to show what it might look like to try one-shotting this with a cloud agent. >> [clears throat] >> Chris, real quick, before you get into that, there was a great question about how to kind of choose the best model for this type of task and and the different kind of price comparisons there. Any any I know it's it's a much longer discussion, so I don't want to derail us, but I'm curious kind of what your

thought process is going into it. Yeah. So, I like using some of the higher-reasoning models for this type of work just because the higher-reasoning models are going to the higher-reasoning models are going to do a better job of understanding like the business logic of why this code needs to behave a certain way or why this code even exists in the first place.

And so, one of the um when it comes to models, right, within cursor, we're going to provide you with access to a few different ones. Um Composer 2.5, we just released last uh just a few days ago and this is benchmarking very well compared to OpenAI and Anthropic's latest models.

And you know, so it's on promo right now. Highly suggest giving it a try. Um but often times for these types of tasks, I recommend using something like either GPT-55 or Opus-47 for that initial inventory and planning. And then something like Composer-25 or Codex for actually writing the code.

Um I think these higher reasoning models are going to give you a much better results than like the medium reasoning models. And when you compare the pricing of Composer-2.5 versus something like um Gemini or uh Gemini Flash, which is one of the more powerful medium reasoning models, it's it just makes a lot more sense to use something like Composer because of the high reasoning capabilities and for that price point.

That said, we always want to start off with creating a plan for how we want to handle these tasks. And so, what I went ahead and did earlier was I ran the inventory sub agent. Um I started off with creating a plan for it. And so, what this inventory sub agent does This is meant to go through the code base and find Oops, that's the the results of the inventory. Okay, so here's the inventory sub agent. This is meant to go through and find what are those major components

that need to be migrated. And so in here we describe what the role of that sub agent is, what inputs it can expect, what outputs we're expecting. Right? And then rules and things that it should follow. And so that output ends up looking like this where we now have an inventory of all of the major components um or REST APIs right and specific notes.

From here I'm using the Linear MCP server to take that inventory and start turning that into different tasks. And so we see here it's created uh multiple issues for this. And then it batches those issues into different phases. And so if I were to come over here to Linear, I can see the project that Cursor helped create for me. And so I get some information on the scope, the source of truth. And I can click over here on issues and I can now see all of the different issues.

I have my four phases here. And then I've got all the specific issues and things that need to be migrated. I find it really helpful um to use something like Linear, Jira, Azure DevOps, some work tracking tool when I'm doing this type of work just because it gives me uh a very easy way to keep track of progress and have a source of truth that can be shared and commented on by the rest of my team.

You could do this in kind of cursor, right, with creating a markdown file and having it keep up a progress uh keeping progress notes as well. Um but for working with broader teams, I find that being able to track this work and assign different issues to different folks, this makes things a lot easier.

And so, by having that created, we used Opus for creating that. Let's use uh Composer 2.5 for executing on this, and we're going to use fast mode today since we're demoing. But I could just start with um use the linear MCP server to get phase two of our migration tasks.

Let's create a plan for executing on those systematically. And so, I'm using voice to text. Um I like talking to my code bases. But we'll now launch this task to get phase two and then create a plan to start executing on that. We see Cursor now going through and starting to rip through and get all of the different issues. While this is happening, I can even parallelize a little bit. Maybe I wanted to also start creating a plan for phase three.

Use the linear MCP server and create a plan for executing phase three of our migration. >> [snorts] >> I don't want to execute on phase three yet just because uh there there may be some dependencies, but we could go ahead and launch creating a plan for how to handle those. So, we've got that later.

I can check out my plan for phase two. This looks good so far. Um we've got uh our references to different documentations. We have our primary sub-agent that we're going to be using, which is that migration sub-agent. And so, this is what the migration sub-agent looks like. Um but this kind of highlights, you know, what are the things to check for, what are the things to do as we work through these tasks.

I have some other sub-agents in here, uh like a security scanning sub-agent. Um you know, if I was using feature flags, I have some feature management sub-agents. I want to add in here, uh let's just have my security sub-agent run at the end, as well as just confirm that we're our output's matching what's expected.

Um you know, one big thing when doing these types of migrations, we talked about generating tests. Test-driven development's really effective because we can make sure that the code that we're generating, right, goes against those tests that exist already. And so, that might be something I want to add to this test plan.

Let's update this plan to use test-driven development approach, right? Um maybe generating tests that don't exist by using the test gen sub-agent. But let's also run uh security scan at the end just so we're aware of any issues or vulnerabilities. Um so document [clears throat] that approach in the plan as well as what work is going to be delegated to what subagents.

We'll put that in there. We'll let this work for a moment. While this is working, Matt, I do want to check in with you. How's chat looking? It's uh it's busy in a good way. There's a There's a good question here, I think, about how to manage the size of a task that's kind of small enough for for human and agent review, you know, so the PRs don't become huge.

Um might be might be something for for kind of Graphite and Bug Bot down the or something down the line, but curious if you have uh something to mention now. Yeah. Yeah, I think that actually uh is a really big question right now, right? Because just as these coding agents are generating more code, that means more code for us as humans to review.

And so Cursor does offer solutions to help with this. One is Bug Bot, which uh is helpful for doing automated scans of of the code of the PRs that's changed, right? And so if we can start automating that initial review part and then automate the remediation of anything that's found in the initial review, that's going to help us with saving time and making larger PRs easier to review.

But the other thing, and so y'all will hear more about this in probably like 2 weeks. Um we're we're going to be releasing uh some other stuff related to Graphite, which is a company we acquired a few months ago. And Graphite changes the way that we as humans review code by walking us through what code has been changed.

So, stay tuned for more on that. Um, it's agent-assisted code review. But, in the meantime, leveraging something like BugBot, um, or even just here in the code base, uh, let's see. Um, I'll show you all once we start editing some files. We also have a cursor review agent that can help with reviewing changes as well.

Thanks for that, Matt. So, taking a look at the plan, we've added in where what work's going to get delegated to different sub-agents. And so, this is very clear. Um, we've refocused this to be around test-driven development. We see what the layers, uh, of what's going to be built out looks like. This looks good to me.

I could now launch this plan in few different ways. I could tell it to just continue here in the chat, or up here, I could tell it to build. And I could launch it with different models if I wanted. We're going to launch it with Composer 2.5. Um, but I could build this locally, right? Or I could parallelize the build using new our new multitask mode.

And so, we're going to use multitask. And we can see it switch to multitask mode down here. What multitask mode is allowing for, it's allowing for even more parallelization of the agents doing work. And so, while our root parent agent has been able to spin up different sub agents to do work in parallel, often times there would still be a sequence to the sub agents that get spun up. The parent agent would work for or would wait for work to be completed before launching new tasks. And so, what

multitask now allows it to do is it allows it to judge where can I parallelize different work streams that don't have dependencies on other tasks that need to be done. And so, we see we've got one sub agent here running. And because this is a dependency on some of the other work, um, it's going to resume more work once this sub agent finishes.

So, we'll check back in in a moment and see how that how that's progressing. But, this approach of starting with inventorying, planning, then launching the migration sub agents, this is how I work with a lot of our customers to do these types of migrations. >> [clears throat] >> We've got some code changes now. And so, if I click on this review button, I can now see a diff of all of the changes.

Up here at the top, there's this button for find issues. This is a way to launch an agent to start reviewing the code here in cursor before we even create a commit or PR. I can give it some additional optional instructions. Right, I could have it review just the agent changes, or I could have it do a diff against uh a different branch. I could even change the approach to it just doing a quick review, right, or deep review.

>> [snorts] >> We're going to go with a quick review today, just agent changes. We'll go ahead and launch this. And so, this is one of the built-in ways that cursor can help with reviewing the code before it gets to that PR. As it goes through, if it finds issues, it will surface those issues and show pop-ups uh throughout the diff files of where those might be.

While that runs, it looks like we have completed uh phase two. This looks good to me. So, coming in on my phase three task where we started the plan, I'm feeling lucky today. Um So, this plan looks good. Uh if I wasn't doing a demo today, I'd probably iterate on this plan a little bit, but we're going to go ahead and build this plan and have it start working on phase three.

I'm going to come back and check in on Linear. And so, one of the things we might want to do is have it update have the agent update the Linear status of all these different tasks from phase two. And so, we'll tell it to do that. Update the task status in Linear for each of these work items for phase two.

Okay. So, we've kicked off phase three. We're updating Linear. >> [clears throat] >> And we are about two-thirds of the way through reviewing our code changes. I now see as it's still updating Linear, but we've got many of the tasks moved into done now. And I can come in uh uh and right and just see reference yet that this work's done, but I have that documentation of what work was done, what the task was.

Okay. Agent review finished. Uh so, this took almost 3 minutes and it found no issues. Great for us, right? We can continue on and uh hit commit here. All right. So, while phase three runs, let's talk about cloud agents. So, what the work I've been doing so far is very human in the loop, right? Um it's synchronous. I'm working with the agent. There's back and forth.

I'm prompting it. I'm giving it instructions. I'm reviewing the plans it generates. That works really well for working in the IDE or our agents window or working with the CLI, [snorts] right? Um there's there's some optimization for latency, and it feels very much like pair programming.

Cloud agents, working with cloud agents is going to feel like you are managing a team of agents. You give them tasks, and then they work in a much more autonomous manner to solve those tasks. And so, this is why it's asynchronous work versus synchronous human in the loop. These cloud agents can be long running, and you can run multiple in parallel on different tasks.

And so, this lets you scale capacity, right? And so, we can see a quick demo here. Um but these cloud agents are running in their own isolated sandbox VM. And they're given a little more autonomy, right? Because they're meant to do their own work without human in the loop. The The idea here is you specify the intent for what you want the agent to do, and then later you get output in the form of a pull request or an artifact. And so an artifact is what we see it

testing here. These cloud agents can now create and prove the work that they've done by creating their own recordings, screenshots, and then sharing that back to you. So you can see quickly as you're reviewing the PR how it validated that work that it did. >> [cough] >> So when I come over here to the cursor dashboard um in the web portal, we can see some of these cloud agents.

I can also see these in the agents window. I'll show what those look like in a little bit. I've got a few different cloud agents here running different things I've been running, but I'm going to click on this one which I launched earlier today. And so this is migrating that React front end to uh or sorry, migrating the Timely front end to React.

And so I gave it my prompt telling it what I wanted it to do. Um and we see it after spinning up, um it worked for a few minutes generating the plan, and then it gives us an overview of what that plan was. Up here on the right, I can click click and view to see different artifacts or aspects of the VM where this agent was running.

And so I see the plan that it generated for doing this migration. This one's not interfacing with Linear, but cloud agents do have MCP access, so they can connect with other tools. I can see that it actually has its own remote desktop. I myself can take control of this. And so, I could click around in the application as well, if I wanted to do some testing myself.

Um or maybe this is also helpful if the cloud agent ever got stuck with like uh maybe like authentication and I needed to come in and enter a password. But, I'll release control back to it. Taking a look at the work that the agent did, let's scroll through. We can see all the work. Um it ran for about an hour.

And it generated some screenshots initially of the work it did. But, then it created a video. Um and so, this video, this is a bit long at 15 minutes. But, I can accelerate this. And we see it clicking through and navigating. And so, what it's doing is it's going through the application, doing its own user acceptance testing to validate the work that it did.

And so, this ability to provide guidelines for how these cloud agents should do the testing is something really powerful as well. >> [clears throat] >> I did run it twice. I ran it with another model. Um and so, we can see another artifact. Um this one used GPT 5.5 for this cloud agent run. And so the the artifact here is about 6 minutes.

But we can see it also clicking through, interacting, checking, making sure that the different forms and fields save, and that everything works as expected. Chris, uh there's a few few questions around uh kind of the testing and validation of the code that's produced, right? So, um kind of a two-parter, right? How how do you kind of ensure the same functionality between the refactored code base? And then where I think the question is going is probably the the

test gen sub agent. Uh and so there was just some questions around that if it's a custom implementation or if it's something that's available out of the box. Yeah. So, there's a couple ways of doing the testing, right, and the validation. Part of what we're doing in this migration process is generating new tests. And so we want to convert existing tests um to from from existing tests for the legacy code, right, to also exist for the new code that we're going to write.

And so that's that's our approach for how we're going to handle the automated testing side of things. Um regression tests, unit tests, things like that. Let's do TDD. And then as we're building the code, right, um or when we're done writing the code, we can have the agent run those tests to make sure that the code passes.

But that's also part of what this sub agent do it is doing, that verification sub agent. It's making sure that the behavior from the test that we generated is preserved from the legacy code to the new code. And so sub agents are how we can customize how Cursor handles all the different types of automated tests that it can run.

And so that's part one, right? And then part two is going to be what is like the the UAT, the the user acceptance testing, the manual testing look like. And so you could use something like Playwright, of course, for this. But these cloud agents this is not Playwright or anything. This is just the cloud agent that has computer use. And so you can define what is the test process for this app application.

And so the cloud agent will follow what that test process is. And it has that ability to do this user acceptance testing and record it. Um I think that being very clear with what your expectations are for these agents uh and for these tests is what's going to lead you to be more successful.

So it's always worth investing some time up front in being very clear with what outcomes you expect what outcomes you need to achieve. And you can even have Cursor help you write what these tests look like. Um but by being very clear about those outcomes and having that documentation that then lets you start automating future usage and future practice of these cloud agents.

Chris, one other one other question kind of since uh we're talking quite a bit about sub agents, um what's your approach or your guidance on on how to be, I guess, token efficient with these, right? Um you know, monitor agents if they're stuck in, you know, kind of tool calls and things like that, setting limits, uh how do you approach that with customers?

Yeah. The >> [clears throat] >> the single biggest thing you can do is using plan mode. Start with plan mode because it's going to help you align with the agent up front. The scope of the work that's going to be done. And so it gives you insight into how the agent's thinking about solving this task. And so you can correct it on what's out of scope, where it's hallucinating, what assumptions are wrong. And so and iterate on that plan.

Because uh the better your plan is, the less rework that's going to need to be done later. Right? And that's where a lot of the token consumption comes in is when the agent's doing work that it doesn't need to do or it's made assumptions that are incorrect or you have to redo work that was done improperly.

So starting with plan mode, um I think the second thing is leveraging skills. And so skills are a way for you to give knowledge to an agent for how to do certain tasks. This can also help you with being more efficient with tokens and context. Right? The agent only knows what you know, if you tell it. And so, that's a great reason to use skills. Is so that it's able to do certain tasks, um, very efficiently because you've told it how to do these types of tasks.

I think using something like linear is also helpful because you can create work tracking, right? Or be able to pull that context in. And so, if you're you have a product manager that's creating work, um, you can just pull that context in instead of your agent having to guess or make further assumptions.

>> [snorts] >> You know, there's other things you can do if um, if we're really focused on like being most efficient when it comes to costs, again, I think Composers are two right now is probably the most efficient high reasoning model when it comes to token efficiency versus capabilities.

And so, I know I'm plugging our own model, but it really is, uh, a way to be token efficient versus using something like GPT 5.5, um, or Opus 4.7, which are both a bit more exp- pensive when it comes to token per token costs. Uh, as far as, right, again, using the plans, that's going to help you with scoping the work, is setting limits on what work gets done.

>> [clears throat] >> Um, but we've also got some workshops that have been done in the past that are specifically around token efficiency, model efficiency, as well. So, highly recommend checking those out, too, if you really want to dive deep into that topic. >> [clears throat] >> All right, folks. This is everything that I had wanted to show today. Do want to say thank you so much for joining. Um, happy to stay on for a few more minutes and answer questions. And so, if you have questions, feel free to drop

them in chat. Matt, as we wrap up here, uh I'll check back in with you. Has anything else come up in chat? Um Yeah, I there there was a question about how much of uh how much of Cursor's own code has been committed via via agents or kind of without human in the loop. Um, the number I was seeing I think is is around 70% as of now. Yeah, I think um it's we're over 50% for how many of our commits are initiated from a cloud agent. And so um it's it's pretty cool to see the adoption internally.

Um, there was also So, I there was a couple questions about if uh the sub agents you were using today, uh one are they custom implementations and two, are you going to be sharing any code base or kind of you know, code from this I guess demo afterwards? >> [clears throat] >> Um we I Yes, so stay tuned. Um, I can put together a blog to share this out um, and I can also work with Emily for the follow-up if if we want to include some of the documentation here. Um,

but I can work on putting a blog together to get this out for how we approach this and send that out as a follow-up. Nice. There was a good uh, good question from from Ram as well about uh, what's the best way to kind of figure out uh, you know, between all the different models? Is there a one-stop solution to distinguish which is the uh, most efficient or or kind of most capable for task? Yeah.

I mean, it's it's constantly changing. Right? The the models, the benchmarks, uh, what's the what's the best performing model? We do publish that information on our social media feeds. Um, one thing you could do is just leverage auto mode if you want. So, you don't have to think about it.

Um, uh, again, I think Composer 2.5 offers a really good balance of high reasoning while also being cost-efficient. Um, but probably like just our socials. Uh, sometimes we do post blog updates as well comparing them. Uh, I think we just published one for the Composer 2.5 release.

Um, if not, we have some coming out where we talk about how we tested that against other models and where we saw it landing in performance. Um, but yeah, the the social media feeds, auto mode's great. Uh, and you you'll see some enhancements with auto mode coming soon, too, to give you more controls, but auto's also just a great way if you don't want to pay attention to like what's the latest model, just use auto.

And we update that regularly with what models it's running to. Nice. Thanks. Um I think I was able to answer most of the other ones. So, uh yeah, thank you again to everybody. A lot of great questions. Um and thank you, Chris. Great presentation. Yeah. Thanks so much for joining, everyone. Um we're going to continue to have more of these. So, please uh thanks for joining, and we'll see you next time on the next one. Cheers, everyone.