When I built DotaKB, a macOS menu bar app that auto-switches your keyboard input source when Dota 2 runs, I wanted to try something different: instead of writing every line myself, I set up two agent roles and let them loop until the app actually worked.
The developer/QA loop
One agent plays the role of the developer. It reads the task, writes or edits the code, and explains what it changed. A second agent plays QA — it builds the app, runs it, and checks whether the behavior actually matches what was asked. If QA finds a bug or a gap, it writes a clear report and hands it back to the developer agent. This repeats until QA has nothing left to flag.
The key thing that made this work was keeping the two roles honest. The developer agent is naturally optimistic about its own code, so it needs a separate, skeptical pass before anything is called done. Splitting the roles forced that skepticism instead of hoping I would catch every issue myself during a quick manual check.
What I'd do differently
Menu bar apps are small enough that this loop finishes in a handful of rounds, which made it a good first real test case. For bigger apps I'm now scoping the loop per feature instead of per whole app, so each round stays fast and the QA agent has a narrow, testable target instead of the entire codebase.
Overall this cut down a lot of the back-and-forth manual debugging I used to do, and it's now part of how I build most of my side projects.