DEV Community

Cover image for I Dogfooded My 49KB AI Coding Agent — It Fought Back 5 Times

I Dogfooded My 49KB AI Coding Agent — It Fought Back 5 Times

Yesterday I wrote about building an AI coding agent that ships in under 50KB. A fair comment kept coming up: "sounds cool, but does it actually work?"

Fair question. So today I did the thing every builder dreads: I dogfooded the version sitting on npm — not my dev repo, the actual npm i -g stew-ai package a stranger would get.

It fought back. Five times.

Round 1: The auth flow was broken

First command a new user runs after installing is either stew register or stew login <key>. Here's what 2.7.5 actually did:

$ stew whoami
❌ Error: apiKey is not defined
Enter fullscreen mode Exit fullscreen mode

A ReferenceError. In production. The whoami command referenced an apiKey variable that was scoped to a different function — a classic closure bug that my offline tests never caught, because the broken path only triggers when a real key exists in ~/.stew/config.json.

While fixing it, I found four more:

  1. whoami crash — the scope bug above. apiKey lived in authCommand, not whoamiCommand.
  2. stew login <key> ignored the key — the CLI treated the first argument as the action name, so your key was parsed as a command and you got dropped into the interactive prompt anyway.
  3. register() sent the wrong field name — the SDK posted full_name while the FastAPI backend expects name. A silent 422.
  4. usage() authenticated wrong — the SDK sent the key as a Bearer header while the endpoint expects an api_key query param. whoami could never show your plan.
  5. 422 errors printed as [object Object] — FastAPI validation errors were stringified raw, so users saw garbage instead of "Missing/invalid field: name".

Five bugs. All in the first 60 seconds of a new user's experience. All invisible in my test suite.

This is why you dogfood the published artifact. My tests ran against source files; the bug shipped anyway.

The fix: same day, with receipts

All five fixes went into v2.7.6, plus five regression tests so each bug can never quietly return:

check('auth: whoamiCommand no longer throws ReferenceError (apiKey scoped)', ...);
check('auth: direct alias routing — "stew login <key>" passes key, not action', ...);
check('SDK: register() sends "name" field (backend contract), not full_name', ...);
check('SDK: usage() passes api_key as query param (backend contract)', ...);
check('StewError: FastAPI 422 detail array becomes readable message', ...);
Enter fullscreen mode Exit fullscreen mode

26/26 pass, package is 49.1KB — still under the 50KB budget, still zero dependencies.

And the flow a user actually experiences now:

$ stew login stew_O9X...
✅ Logged in! API key saved to ~/.stew/config.json

$ stew whoami
👤 S.T.E.W Account
  API Key: stew_O9X...P8b2
  Plan: free
Enter fullscreen mode Exit fullscreen mode

Round 2: Actually building something

Auth works — fine. But the real question was whether the agent could code. So I opened the REPL (stew code) and asked it to build a single-file landing page for a fictional Afrobeat festival in my hometown:

Build a stunning single-file index.html for a fictional Afrobeat concert in Enugu, Nigeria called 'Enugu Sound Fest 2026'. Dark theme, orange/green gradient accents, animated hero, artist lineup grid, live countdown timer, tickets section. Pure HTML/CSS/JS, no external dependencies.

It generated the whole page — hero, lineup grid, countdown, tickets. But when I opened the file, one line was broken:

el.textContent = ${d}d ${h}h ${m}m ${s}s;   // ← template literal lost its backticks
Enter fullscreen mode Exit fullscreen mode

So I did what any user would do: went back into the REPL and told it what was wrong. It rewrote the line with plain concatenation and applied the patch:

Stew Code fixing the broken countdown line in the terminal

And the rendered result, screenshotted from the actual file it wrote:

The landing page Stew Code built — Enugu Sound Fest 2026

Build → spot the bug → describe it → agent fixes it → verify. That loop worked, end to end, over the free API tier.

Honest friction notes

Dogfooding also surfaced things I'm not proud of, so you get those too:

  • The file-apply format is too picky. The CLI only writes files when the model formats code blocks in one exact way (a // filepath: marker on the first line). The model often guessed a different format and the change silently didn't apply. It worked when I told it the exact format — but a user shouldn't have to know the magic words. That's next on the fix list.
  • A queued message wedged the REPL while a response was streaming — I had to restart the session. Input needs a lock during streaming.

Both of those are now tracked with the same rigor as the auth bugs: found by using the thing, not by staring at the code.

The takeaway

If you build a tool for other people, the most valuable hour you can spend is being one of them — installing the published package, running the first three commands a stranger would run, and believing every error message you see.

The five worst bugs in my auth flow survived 21 passing tests and two published versions. They died in one afternoon of pretending to be my own user.

Go break it. I'll fix what you find.

Top comments (1)

Collapse
 
marcusykim profile image
Marcus Kim

The fact that whoami only crashed when a real key existed in ~/.stew/config.json is exactly why source-level tests were giving false confidence. The full_name versus name mismatch and Bearer-header versus query-param mistake also point to a missing contract test between the CLI and FastAPI, not just isolated command bugs. I'd add a release smoke test that installs the packed npm artifact into a clean temporary home, runs login, whoami, usage, and one file edit; it costs more CI time, but protects the first minute users actually experience.