How I built Simple Budget in two evenings with an AI agent

ai-coding-agents simple-budget pi workflow

I built Simple Budget in two evenings using the Pi coding agent and Ollama Cloud running kimi-k2.7-code. The implementation was easy; the real work was alignment — getting the AI to think the way I think before it wrote any code.

Pi as a coding partner

I use the Pi coding agent as my harness, backed by Ollama Cloud running kimi-k2.7-code. That model has become my default: it is fast, cheap, and does exactly what I need for most coding work. For a project like Simple Budget, that combination means I can iterate quickly without worrying about context windows or per-token cost.

One of Pi’s most useful features is its tree-style conversation interface. A session is not a single linear chat. It branches. I can go back to any previous response, fork a new branch from there, and continue with a different angle or a cleaner summary. This changes how I manage context.

I have a growing set of skills and project requirements that I bring into every session, and for something small like Simple Budget I did not want to overthink the code itself. What mattered more was keeping the structure consistent with how I build things.

Baking preferences into the system

The way I work with Pi is iterative. After each session, I ask the model what I corrected it on most often. Then I ask it to summarize those corrections into concrete guidance. Over time, those summaries become direct prompts in my system setup. Things like:

  • Ask a question at a time.
  • Read existing code before editing.
  • Make the smallest correct change.
  • Prefer early returns over deep nesting.

These are not revolutionary rules, but they are mine. Getting them into the system prompt means I spend less energy steering the model and more energy thinking about the actual problem.

My workflow: explore, align, summarize, build

I use the same loop for every feature, not just the whole project:

  1. Explore. Walk the codebase and understand the current state.
  2. Grill. Stress-test the plan until the model and I share the same understanding.
  3. Summarize. Distill that understanding into a short, targeted prompt.
  4. Build. Implement the feature inside a branch, keeping the context focused.

The tree conversation interface is what makes this practical. After I explore and grill, I summarize what we agreed on. That summary becomes a new node in the conversation tree. When I start implementing, I branch from that clean summary, not from the noisy exploration that led to it. If I need to backtrack, I can return to any previous node rather than trying to correct a long, polluted chat.

Working in branches is important. Each feature gets its own isolated context. Once it is done, I summarize the changes before moving on. That summary becomes the starting point for the next branch. It keeps the model’s working memory small and prevents unrelated history from leaking into the next decision.

Before writing anything, I explore. I walk the codebase and understand what is already there: conventions, naming, where things live, and how features are wired together.

Then I grill. I keep grilling until the model and I share the same understanding of the problem, the constraints, and the smallest viable next step. This is the most important part of the process. An aligned model that has actually looked at the project and been stress-tested produces very different output than one that guesses.

Once we agree, I summarize that shared understanding into a short, targeted prompt. That summary becomes the context for implementation. The goal is to keep the working context small and focused — no unrelated history, no drift, no scope creep.

Only then do I start changing code.

The grill step

The most useful skill I have added to my workflow is Grill Me. I use it to stress-test my own plan until the model and I reach a shared understanding.

For Simple Budget, grilling clarified the real scope early: manual budgeting only, no bank import, no automation beyond totals. That constraint made the rest of the build trivial.

Structure: features and locality

The code itself follows a feature-based structure. Each domain — auth, budget — lives in its own folder with schema, queries, mutations, and routes close together. I try to keep things that move together, together. This is locality of behaviour as a design principle.

I also default to a grug mentality: simple code over abstract code. No premature generalisation, no layers for the sake of layers. If a function needs to do one thing, it does one thing. If a component is only used in one place, it stays there until it is not.

Why the build was fast

By the time I asked Pi to implement the app, it already knew:

  • My conventions
  • My tolerance for complexity
  • The scope I actually cared about
  • The questions I wanted asked before decisions

We had explored the project, grilled the plan into a shared understanding, and summarized it into a focused prompt. Then we repeated that loop for each feature, branch by branch. The result was not just faster code. It was code I did not have to rewrite.

© 2026 Tudor Jianu