Dart 3.12 introduced experimental primary constructors that reduce boilerplate. This post documents a week-long engineering journey to build a deterministic CLI tool for safely migrating codebases to this new syntax. The author first tried an LLM agent skill but found it unreliable, token-intensive (200k+ tokens, 20+ minutes), and inconsistent across runs. Observing that GPT-4 was spontaneously building a Dart AST parser to solve the problem pointed toward the right approach: a deterministic CLI using Dart's analyzer package. The tool implements 3 migration rules but 31 skip rules to ensure safety. Key lessons include: 'it compiles' ≠ 'it's correct'; feeding agents the official language spec beats feeding them examples; and the best architecture separates deterministic migration logic (CLI) from adaptive orchestration (agent). The resulting CLI migrates ~100K lines in under a second with identical results every run, and can be orchestrated by a cheap model like Haiku rather than requiring frontier models.

14m read timeFrom codewithandrea.com
Post cover image
Table of contents
Writing an Agent SkillGPT Was Solving the Problem by Creating a Dart AST ParserGoing Deeper into the Rabbit Hole"It Compiles" Is Not the Same as "It's Correct"The Mistake I Didn't Know I Was MakingThe Tool Does One Thing (the Agent Does the Rest)What I'd Tell You to Take AwayThe Result — and How to Get It
944 Impressions