Skip to content

March 17, 2025

Resurrecting My Trello Management Tool and Data Pipeline with Claude Code using Vibe Coding (Part 1)

By Gene Kim

Introduction

What do you do when you have a critical book deadline and need to use a tool you wrote that hasn’t worked in two years? It doesn’t deploy anymore because of some obscure error at startup in Google Cloud Run. And you haven’t touched the code in two years and don’t remember how any of it works.

Oh, and by the way, the entire data pipeline that made it so useful stopped working two years ago when Twitter limited access to their API and Zapier deprecated their integration. 

It seems like you’d be completely out of luck, right?

That’s the situation I found myself in last week. But I’ve routinely been building impossible things thanks to GenAI. In fact, I’m working on a book with Steve Yegge on how everyone can achieve the impossible!  (The book title we’ve finally converged upon: The Vibe Coding Handbook: How To Engineer Production-Grade Software With GenAI, Chat, Agents, and Beyond.)

In this blog post, I’ll share how I used Claude Code two weeks ago over two days and resurrected a critical tool I needed, fixed bugs that have bothered me for four years (!!), and, oh, by the way, I created a new Twitter data pipeline that I’ve been dreaming of for two years. 

It was an exhilarating experience using Claude Code, and it cost $80 in tokens (and 6 to 7 hours of work).

Steve started using Claude Code the same day I did. He told me the next day, “I literally couldn’t sleep. I was tossing and turning all night long because all I wanted to do was get up and use it to fix things. I’ve got all this pent-up anger at 30 years of bugs that have been piling up in this game I wrote and now I’ve got this machine that can just fix them.”

In a tweet, he wrote, “I’ve been using Claude Code for a couple of days, and it has been absolutely ruthless in chewing through legacy bugs in my gnarly old code base. It’s like a wood chipper fueled by dollars. It can power through shockingly impressive tasks, using nothing but chat.”

That feeling resonated with me. As Dr. Erik Meijer says, using Claude Code is addictive. You put in money, it fixes your code, it builds features, and you’re powerfully motivated to give it more money to do more of it!

In this post, I’ll describe why solving this problem was so important, an experience report using Claude Code, and some lessons learned.

(PS: for Clojure fans out there: so many of the posts I’ve written were about using languages I don’t normally use: Python for data analysis, JavaScript for building a Google Docs Add-On. This time, it’s all about my normal weapon of choice: Clojure and ClojureScript.)

Lessons:

  • “Vibe coding” often has the connotation of turning your brain off or only being for prototyping, but here’s an example of using Claude Code (and any coding assistant) to do the opposite. I describe a session where I felt like I was in a murder mystery, trying to reproduce and fix a bug that has been bugging me for 4 years. I iterate through specific usage scenarios, add more logging, leaning on Claude Code to diagnose what is going wrong — and finally fixing the problem
  • I describe how I hadn’t touched this project in 2 years. And despite that, under time pressures, coding assistants gave me confidence that I could resurrect this program and get an entire new data pipeline going over a weekend.
  • On the one hand, Claude Code can do amazing things — but it also requires continuous vigilance and a clear mental model of the boundaries of what you want changed. When you see changes being made where you don’t want, they make it very easy to hit the ESC key and it instantly stops the changes.
  • Despite being vigilance, you can still accidentally wake up in a room full of AI-generated horrors — I give a couple of examples where this happened to me, and yet decided that “it’s fine for now.”

Project Overview and Purpose

The program I needed to resurrect was a Trello card management tool, which was at the center of my daily workflow for nearly six years. It was a program I built for myself to manage my to-dos, but also to manage notes for writing books. 

For many things, Trello serves as my to-do list and research fact file.  Most of these Trello cards are from liked tweets that came in from Zapier. Other Trello cards were generated from starred Gmails, starred articles in Feedly (my RSS reader), and some other sources, all via Zapier. I had Trello boards for my to-dos and major projects, such as conference planning, book projects, things to research, and so forth.  (It was an evolution of the David Allen “Getting Things Done” method I’ve been using for decades.)

I had first written this app in Clojure and ClojureScript in 2016, and rewrote it in 2019 using the Fulcro and Fulro RAD framework. The primary goal was to make it super-easy to move cards between boards and lists. It has a ton of keyboard accelerators (like vim), easy ways to make new lists, a “most recently used” list of move targets, which I could repeat with just a click, and all sorts of affordances that I made to make life easier for myself. And most importantly, it made it easy to deal with super-wide boards, something that is quite cumbersome in the Trello interface.

I was shocked today to discover that since 2016, I have processed almost 12,000 Trello cards with this app. Nearly 6,000 cards have been archived, and over 5,000 cards have been moved, which means I had read the cards, maybe pondered them, maybe even written about them, or just archived them. To me, this speaks volumes about how much I used this tool.

(In the screenshot below, you can see the boards or lists on the left, and the Trello cards on the right, with the list of all cards on the bottom.)

I pulled some stats from git (actually, Claude Code did). It’s 13K lines of code. And since 2019, I’ve added/modified/deleted 30K lines of code across 300 commits, adding various things I needed over the years. This shows how much functionality I added to help make my life easier.

Here was the data pipeline pre-2023, which was populating cards into Trello.

All that came to a crashing end when Twitter turned off most of their API in 2023, unless you paid $200/month. Zapier deprecated their Twitter integration, which turned off my biggest data source to my Trello boards. That’s when the system I had been using for a decade started to fall apart, if not cease entirely.  

I mostly stopped using this tool except for the rare cases when I had to do mass Trello card operations. I hadn’t pushed any code updates in two years.  

But with The Vibe Coding Handbook book deadline looming, and countless valuable AI coding examples appearing on Twitter daily, I needed this system operational again. I needed to get the hundreds (or thousands?) of liked Twitter posts out of my Twitter account and come up with a way to get them on a continual basis. 

I also needed to figure out how to get my Trello app deploying again. As I mentioned, it hadn’t been deployed in 2 years. New deployments resulted in an uncaught exception and a mysterious error. There were also a bunch of bugs I wanted to fix, but I didn’t remember much (or anything) about the code.

One year ago, I probably would have looked at this and given up even before starting. Just imagining all the problems I could have encountered, I would have immediately concluded that the “juice wasn’t worth the squeeze.”  

But then I remembered how many things I’ve built in the last year that I could never have imagined doing before GenAI. Heck, I had even written a Google Docs Add-On a month ago!  Encouraged by these successes, I started mentally priming myself for tackling this.

Below, I show the new data pipeline I created over two days. In a future post, I’ll describe how I created the new data pipeline (despite every GitHub repo and gist describing how to do this disappearing).

In this post, I’ll focus on how Claude helped me fix the Trello card management app.

My First Session With Claude Code: What It’s Like Using It

I had signed up for Claude Code shortly after it was released but was waitlisted. But when Steve texted me saying that he had started using Claude Code, I was like, wut? How?

That’s when I discovered that Anthropic just enabled anyone to start using it. I got it installed and started using it right away. Here’s instructions on how.

Claude Code is very different than the coding assistants you see in IDEs. When you start it in a terminal window shell with “claude,” it starts in a terminal window. You see a program that’s basically an interactive curses-style application. You can use up/down arrows to get history, there are live elements at the bottom of the screen.  

But it’s a revelation. Instead of focusing on the UI, the Anthropic team seemed to have focused on what really matters: stripping away all unnecessary affordances to explore how an LLM can solve problems with and for you.

These are some notes I took at the end of my first day:

In the beginning, Claude Code doesn’t have permission to do anything. I found myself giving it more permissions to do things on its own. I was happy to give it access to sed, grep, and head. Of course, it asks to make modifications to source code files.

I was more reluctant to let it actually run the program itself (clj -M:m-run xxx), but I decided to let it on Day 2. It had the benefit of enabling it to detect compile-time errors on its own, which was awesome.  

Things got really weird when I let it do git add and git commit by itself about one hour into my first session. I feel like this is where it went totally off the rails.

I had given it a small task, and as a side effect of running the program, it realized it couldn’t start a not-relevant web server that was in a different namespace due to port collision. Then it started making changes to the web server. I was like, “Whoa, whoa, whoa. Stop, stop, stop. This is way beyond what I wanted you to do.”

I learned from Steve that at any time, you can always hit ESC, and it will immediately stop what it’s doing and give control back to you. It’s far more immediate than I originally thought. You hit ESC, and you instantly have control again. (It must “kill -9” whatever active Claude Code tasks are operating.)

This dynamic makes it very pleasant and confidence-inspiring. You give Claude Code tasks, probably leaf nodes in your task tree, that are reasonably bounded and defined. It grinds away, and it shows you code diffs. You look at them and just hit Enter when you think, “Looks good to me!”

And far from turning your brain off, which is what people associate with “vibe coding,” your brain stays constantly engaged. You need it to make sure it’s “coloring inside the lines.”

Claude Code has the notion of “context remaining.” I’m guessing this is the context window of everything it has discovered about your codebase, your objectives, and tasks. Eventually, you’ll see a notification at the bottom like “10% context remaining. /compact your session.” (They recently renamed the message.  It now reads “Context left until /compact: 22%.” I think this means it will automatically compact your session for you when exhausted.)

(Steve also mentioned in a conversation that this means the entirety of this context is likely being sent to the Anthropic API each interaction, which drives up your costs. So there may be real benefits to compacting more frequently: faster inference times and cheaper.)

One time, I made the terrible mistake of typing /clear instead of /compact, which was absolutely awful. Maybe I was too tired after working on trying to deobfuscate the Twitter DOM. But when I realized what I had done, I had a “OMG, rm -rf /” level of horror.  And indeed, I had to explain what I was trying to do again, what methods we’ve already tried and failed, etc.  It started going down rabbit holes from hours ago.  After a long day, it was just too difficult to reestablish all the context again.  I quit for the day.)

(Note to Claude Code team: because context is so important, can “/clear” require explicit confirmation, and maybe even be renamed “/newsession”.  And how do you “save game”?  I’d love to have a “/savecontext” command, that outputs the entire context to a .txt file.)

Ah, from my notes that first day: after I accidentally cleared the context, it it started creating new endpoints on the web server that it shouldn’t even be touching, brought in a whole bunch of libraries that I didn’t want, and then wanted to commit it into git. 

I was like, “No, no, no.”  I called it quits for the day.

End of day cost: $12.  Happily spent!

Second Day with Claude Code

After a good night’s sleep, I started another coding session —to much delight, I got enough of a Twitter to Trello card pipeline going, and managed to get 1,200 Trello cards created from my liked tweets into MySQL.  

It was time to switch to Trello card processing production mode — I needed to start reading each one of these cards, and disposition them: i.e., move them to the most relevant list, or create a new list.  To make life a little easier, I managed to create a quick categorizer, using Google Gemini to look at the tweet text, and categorize it, based on the existing board lists.

After processing several hundred cards, I was very irked to run into an annoying bug that has been aggravating me for four years — every once in awhile, when I move a card, it would go to the wrong list.  And when I made a new list, the new list wouldn’t show up in the dropdown list right away.  And when I clicked on a list in the move history, the card would get moved to the wrong place.

I hadn’t touched this code in two years, and I know that I’ve tried to fix this bug off and on several times, and gave up each time.  (I knew that it had to do with inconsistently using Clojure key names in maps — I alway run into this type of problem in larger programs, which typically tempts me to consider more strongly typed languages.  More on this later.)

I had mentioned that I had a session that felt like being a detective in a murder mystery, with a helpful companion at my side every step of the way. Below, I walk through about 90 minutes of Claude Code logs, where I’m trying to fix this problem while using the program. Every time I see something work, I document it — when something goes wrap, I capture the logs in the browser console and ask Claude Code what happened and why and how, and to add more logging.

By doing this, I progress from a situation where I literally have no clue what is going on to being on the verge of a fix. Here are some of the prompts

  • “when I move a card, I’m seeing: mutation: move-card: card-id: nil mutation: move-card: list-id: nil; how is that happening?”
  •  “i’m doing it from the move modal box. here are my logs” [lots of logs]
  • “put more logging when the ‘m’ key is selected and the MoveModal becomes visible; at that point, if the values are nil, do an js/alert; and then explain how we got there”
  • “alert hit; logs…” [lots of logs]
  •  “movemodal: esc key not working”

Eventually, I got to this point where I could write a long prompt that enumerates all the cases that are working, and the cases that are broken, as well as all of the relevant log messages.

  • “- These are a bunch of usage scenarios in the MoveModal dialog box — I’ve labeled them “works” and “wrong”.
    • – WORKS: Click a list in the dropdown, Click Move
    • – WORKS: select list in dropdown. (manually clicking it)
    • – WRONG: type list name (e.g. “to watch”), tab, enter
    • – WRONG: type list name: hit ENTER (closes window)
    • – WRONG:
      • – weird: in display history of moves, clicking the list goes to correct list, but name is wrong!
    • UNKNOWN: list name, down arrow, enter works?
  • Here are the relevant logs

Less than 30 minutes later, I managed to get this modal dialog box running correctly.  I think all the edge failure cases have now been hammered out.  The dropdown box works, tab, enter, and escape keys finally work as expected, and the history of moves above the dropdown box works!

Claude Code made it easier to debug this — I felt that I was working at a higher level, documenting the usage paths, with the AI improving logging and making sense of what the logs were saying.

The smoking gun? As Claude explained: “There was namespace mismatch between code (:idList) and data (:trello-card/idList)” — as I suspected, I had misnamed keys littered around my code, but Claude Code tracked down the incorrect usages and fixed them for me.

It was such an exhilarating feeling, using my Trello list manager, fixing problems one-by-one as I found them, making it easier and easier to do what I needed to get done.  Here are some of the other prompts I wrote that day:

  • When making new list, make it so that it’s available in Move Card modal dialog box right away
  • Add new menu items: Trello > Reload Starred Lists, Trello > Reload List” (so that they’re accessible via menu, not just keyboard accelerators, which I can’t remember after two years of not using the tool)
  • Display at bottom of the screen the active Trello board-id, list-id, card-id, last move destination (giving myself more debug information without having to open up the browser console)
  • Make it so that Enter in dropdown selection text area automatically selects the matching list, and triggers the Move operation

By the end of that day, I had for Steve a bunch of cards that he could integrate into this sections!

One More Debugging Story

One problem I discovered stands out in my memory as remarkable.  When selecting a Trello list in the dropdown box, sometimes the card would get sent to the wrong list.  Claude Code convinced me that it was due to a delay between two stateful managed React components.

I don’t have very much experience with front-end programming, so I barely know what this means.  But I know I had similar issues with managed React elements.  I remember having a problem a decade ago of keeping the cursor in the right place in text input boxes, which apparently continues to be a problem that people face in React — here’s a React issue someone filed in 2020!

Claude recommended changing the Semantic UI React controls, to which my response was, “Whoa, whoa.  Not sure if I’m up for that.  I just want to fix my one little problem.”  I was delighted when I suggested using a global variable instead to work around this issue, it actually worked!

When You Wake Up To An AI-Generate Room Of Horrors

Several times, I was reminded why vigilance is so important while using Claude Code (and other “agentic” coding assistants): earlier, when trying to troubleshoot this issue, Claude Code was convinced that the move target list was being corrupted somehow.  It then started reloading this list from the server.

I was willing to entertain that concept (despite being deeply skeptical).  But I started getting 3-5 second keyboard latency when typing in the search box.  Claude Code then started adding debouncing and caching.  And then tried to debug debouncing.

I pulled the plug on this, and reverted back to my last git commit, and asked Claude Code to go down a different line of problem solving.

Someone described this situation as “waking up to an AI-generated room of horrors” — this is definitely something I can now relate to.  As the engineer, sometimes you go where the LLM suggests.  Other times, you use your experience and judgement to say, “Nope.”

One last story:  I had mentioned that I could no longer deploy this code to Google Cloud Run.  It was running on my laptop just fine, but it was failing with this error in Google Cloud Run: “”Received RST_STREAM: Protocol error” when fetching secrets from Google Cloud Secrets Manager.

Claude Code wasn’t able to fix this — I resorted to using OpenAI Deep Research to figure this one out.  It turns out that this error was because I converted my Google Secrets Manager from the Google Java client library to using REST calls, and for some reason, I was getting this error because I was using HTTP/2 by default.

(Why does this HTTP call work in some of my programs, not not others? I have no idea.)

But on the way to fixing the issue, I asked Claude Code to comment all my calls to my Secrets Manager library — which it did… very thoroughly.

I was happily copying and pasting the new logging messages into Claude Code to isolate what was generating the error.  But when I looked into the source file of my callers, I was shocked to find the code now had deeply nested try/catches — like six or seven levels deep, when they used to be two or three.  

It was “fine,” but I would really like to clean this up.  Someday.  But for now, I have other fish to fry.  (Some might say I just added to my technical debt — but it’s just a bunch of overly nested error handling.  Big deal.)

But it was definitely had shades of those “waking up to AI generated horror” feelings.

End of day cost: $30.  Happily spent!

Conclusions

Many people associate “vibe coding” for turning your brain off, and doing what the LLM says.  I’m hoping that this experience report shows that what I did on those two days was the opposite of that — I was using AI as another engineering tool to achieve what I wanted.

That’s the point of the book that Steve and I are writing: The Vibe Coding Handbook: How To Engineer Production-Grade Software With GenAI, Chat, Agents, and Beyond — there are times you want to prototype something and throw away, there are times you want to solve a problem for yourself (and only you have the consequences when something goes wrong), and there are times when you are supporting mission-critical services support many, many people.

There is a way to use vibe coding and engineering tactics for each scenario. So, happy vibe coding!

PS: For those of you interested in Claude Code, here’s a 1.25 hour video that Steve Yegge and I recorded last Friday — Steve used it to convert a 20 year old, 2500 line Ruby admin script to Kotlin/Gradle.

It was super impressive — this was something we tried two months ago using more traditional CHOP/vibe coding methods, but we gave up after 90 minutes. In a little over an hour, Claude Code converted over some of the most challenging tasks: the MySQL and Redis admin commands, logging into the sandbox environment. Wow! (Link: https://www.youtube.com/watch?v=HtqxI53h7zM)

My writeup on that experience coming soon!

- About The Authors
Avatar photo

Gene Kim

Gene Kim has been studying high-performing technology organizations since 1999. He was the founder and CTO of Tripwire, Inc., an enterprise security software company, where he served for 13 years. His books have sold over 1 million copies—he is the WSJ bestselling author of Wiring the Winning Organization, The Unicorn Project, and co-author of The Phoenix Project, The DevOps Handbook, and the Shingo Publication Award-winning Accelerate. Since 2014, he has been the organizer of DevOps Enterprise Summit (now Enterprise Technology Leadership Summit), studying the technology transformations of large, complex organizations.

Follow Gene on Social Media

No comments found

Leave a Comment

Your email address will not be published.



Jump to Section

    More Like This

    Resurrecting My Trello Management Tool and Data Pipeline with Claude Code using Vibe Coding (Part 1)
    By Gene Kim

    Introduction What do you do when you have a critical book deadline and need…

    Becoming a Better Leader Part 3: Enabling Flow and Removing Obstacles
    By Leah Brown

    In today's fast-paced organizations, a leader's key role is enabling teams to deliver value…

    How I Built a Google Docs Add-On in Three Hours (Using Vibe Engineering)
    By Gene Kim

    So, I'm writing a book with Steve Yegge (famous for his 20 years at…

    How I Broke My 20-Year SPSS Habit To Vibe Code Something in a Python Colab Notebook
    By Gene Kim

    So, I'm writing a book with Steve Yegge (famous for his 20 years at…