How I Rebuilt My 10-Year-Old Open Source Package with Cursor and Claude

· 9 min read

When I decided to rebuild my ten-year-old Laravel package, I did it with AI coding tools — the beta with Cursor, the stable release with Claude. This is what the workflow actually looked like, what each tool did, and what I would trust it with again.

Some context first. The package started as a small tool that let a Laravel application post content to Telegram, X, and Facebook from one call. It grew an open source community I never expected, survived a long maintenance gap, and eventually needed more than maintenance: it needed a rewrite. I have written about that ten-year history separately — this article is only about how the rewrite was made.

TL;DR

  • I gave Cursor the full expectations for the package, had it write tests, reviewed those tests myself, then let it loop on the code until everything passed. The loop ran about half an hour.
  • Reviewing the tests before the loop is the step that makes this workflow defensible. Skip it, and the same AI is writing both the exam and the answers with nobody checking the exam.
  • Passing tests did not mean working integrations. I could not verify Facebook myself, so I shipped a beta and openly asked users to test it.
  • The stable version: a full structural split into a core engine and a Laravel wrapper, was built later with Claude. Cost is what made me switch tools.
  • The result supports 11 platforms instead of 3.

The starting point

Version 2 began as one project. All the platform logic, all the Laravel integration, one codebase, three supported platforms: Telegram, X, and Facebook.

I did not begin by asking an AI to write code. I began by explaining, in detail, everything the software was expected to do — every behavior, every platform, every option. That explanation is the highest-leverage part of the entire workflow, and it is the part most people rush. The tool can only loop toward a target; the explanation is the target.

The loop: tests first, review second, then let it run

The workflow that produced the beta:

  1. Explain all expectations for the software to Cursor.
  2. Ask it to write tests covering those expectations.
  3. Review the tests myself. Not the implementation — the tests. Do they actually encode what I described? Are they testing behavior or testing nothing?
  4. Tell it to write and fix code until every test passes. Then step back.

Cursor went into a loop: run tests, see failures, fix code, run again. It took roughly half an hour to bring everything green. When it finished, I reviewed the code, tested the package myself, asked for some minor changes, and then had it write the documentation and the README.

Then I published the beta.

People now have names for parts of this. Letting an AI generate code freely from a description gets called vibe coding. What I was doing is stricter, closer to what is now called an agentic TDD loop: the tests are written first, a human audits them, and only then does the agent iterate against them.

That review step in the middle is the whole difference. If the same AI writes the tests and the code and nobody checks the tests, then the tests are not an independent standard — they are the AI grading its own work. Reading the tests before starting the loop was the one point in the process where my judgment was genuinely load-bearing. Everything after that was supervision.

What the loop cannot tell you

Every test passed. That did not mean the package worked.

Tests verify the code against the expectations you wrote down. They do not verify that a real platform, with real credentials, accepts what the code sends. I had no Facebook application set up, so I had no way to test the Facebook integration end to end myself.

I did not pretend otherwise. I published the version as a beta and opened an issue asking users to help test the platforms I could not verify. The community had kept this package alive through a maintenance gap before; asking them to help validate a release was a natural extension of that.

This is the honest boundary of the workflow: a green test suite is a claim about the code, not about the world. For a package whose entire job is talking to third-party APIs, the loop gets you to "internally consistent," and only real credentials on real platforms get you to "working." Budget for that second step, or borrow your community's ability to do it — openly.

Switching tools: the stable version

The stable v2 was built later, and with a different tool, for an unglamorous reason: cost. My Cursor tokens ran out fast, and I was paying a lot for them. I moved to Claude on the 5x plan, and that is where the real structural work happened.

The stable version is not the beta polished. It is a different architecture:

  • owlstack/owlstack-core — a framework-agnostic PHP engine holding all the platform logic.
  • owlstack/owlstack-laravel — a thin Laravel wrapper around that core.

The rewrite replaced the old static calls with dependency injection, returns structured result objects instead of raw arrays, and dispatches events on success and failure. Platform support went from three to eleven: Telegram, X, Facebook, LinkedIn, Instagram, Discord, Slack, Reddit, Pinterest, WhatsApp, and Tumblr. The package also moved to its new home as part of the OwlStack project.

The core/wrapper split is the change that matters most for the next ten years. In the old design, Laravel specifics and platform API logic were tangled together, so every Laravel major version touched code that had nothing to do with Laravel. Now the engine tests and evolves independently, and the wrapper is small enough that framework upgrades stay cheap.

What I actually learned about working this way

The explanation is the work. Both phases started the same way: describing expectations exhaustively before any code existed. The quality of everything downstream — tests, loop, final code — was bounded by the quality of that description. If you cannot state what the software should do, no tool can loop its way there.

Review the tests, not just the code. Code review after the fact is natural and I did it. But the test review before the loop is where you buy your confidence. It is also much faster than reviewing implementation, which is what makes this workflow efficient rather than just automated.

The loop is impressive to watch and boring to supervise — which is the point. Half an hour of an agent iterating toward green, with my involvement reduced to having defined "green" correctly. The impressiveness is real, but the discipline around it is what made the output shippable.

Tools are interchangeable; the workflow is not. I used two different AI tools across the two phases, and switched for cost rather than capability. The constant was the method: expectations, tests, review, loop, human verification, honest labeling of what was not verified. That method would survive the next tool change too.

Know what you did not verify, and say so. Shipping a beta with an open call for platform testing was better than shipping a "stable" release with untested integrations. The label did the honest work.

Frequently Asked Questions

What is an agentic TDD loop?

A workflow where an AI agent first writes tests from your stated requirements, a human reviews those tests, and the agent then iterates on the implementation until the full suite passes. The human review of the tests is what distinguishes it from letting an AI generate code unchecked: it makes the tests an audited standard rather than the AI grading itself.

Is this the same as vibe coding?

It is a stricter relative. Vibe coding generally means describing what you want and accepting generated code with little inspection. Here, the tests are inspected before the agent loops, and the final result is reviewed and manually tested. The freedom is in the middle of the process, not at the boundaries.

Can AI-generated tests be trusted?

Not automatically, and that is precisely why the workflow includes reviewing them. Generated tests can be superficial, can test implementation details instead of behavior, or can miss requirements entirely. Reading them against your own list of expectations is fast, and it is the single highest-value review in the process.

Do passing tests mean the software works?

They mean the code matches the expectations encoded in the tests. For software that integrates with external platforms, real-world verification with real credentials is a separate, unavoidable step. In my case I could not verify one platform myself, so I released a beta and asked the community to test it.

How long did the AI take to make all tests pass?

Around half an hour of autonomous iteration for the beta version, after the tests were written and reviewed. The preparation before that — explaining the full expectations of the package — took longer, and mattered more.

Subscribe toChangelog

📚
One useful email, most weeks.

Weekly notes on software engineering and building income on the side, plus what I am learning as I ship my own products.

By submitting this form, you'll be signed up to my free newsletter. I may also send you other emails about my courses. You can opt-out at any time. For more information, see our privacy policy.