Agent-First Applications: Building Software for the Person, Operated by the Agent


AI developmentagent-firstdeveloper experiencedeploymentAGENTS.mdopencode
5 min read
Table of Contents

I recently built a white-label construction ledger for someone who is brilliant at running a construction business and zero percent interested in running infrastructure. No Docker, no Supabase dashboard, no Vercel CLI. They wanted a product that says their name, in their colors, and just works when they open it.

That tension, a technical product paired with a non-technical owner, pushed me toward something I now think of as agent-first development. The idea is simple: the operator of your product is not a human clicking buttons, but an LLM agent following instructions you wrote (the same principle behind Feature MD, applied to operations instead of features).

The Problem Wasn’t the Code. It Was the Handoff.

The app itself is unremarkable from an architecture standpoint: React + Vite frontend, a FastAPI backend, Supabase for auth/database/storage, and a deployment target of Docker (local) or Vercel + Supabase (cloud). Standard stuff.

The hard part was everything around the app. Standing up an instance for a customer meant:

  1. Creating a new Supabase project and generating credentials.
  2. Pushing migrations.
  3. Seeding the first admin account.
  4. Creating a Vercel project.
  5. Setting a dozen environment variables.
  6. Configuring auth redirect URLs.
  7. Rebranding the product (name, logo, accent color) and toggling features.

That’s maybe forty steps, each with its own way to go wrong. I could write a README, but my customer isn’t going to read a README. And honestly, even I don’t want to walk through forty manual steps every time I onboard a customer.

So I stopped writing instructions for humans and started writing them for agents.

What Agent-First Actually Looks Like

An agent-first application has a single entry point that an LLM can read and act on. In my repo that’s an AGENTS.md playbook (OpenCode’s rules docs describe the same mechanism). It encodes the entire operational life of the product as a deterministic conversation:

  1. Ask the user for branding (name, logo, accent color).
  2. Ask which features to disable.
  3. Ask: local or cloud?
  4. Run the matching script.

That’s it. The playbook doesn’t describe how to deploy; it describes what to ask and which script to run. The how lives in scripts that are idempotent, secret-safe, and boring:

./scripts/rebrand.sh --name "Acme Builds" --accent "#1a73e8" --flags '{"notes": false}'
./scripts/deploy-local.sh   # Supabase + app in Docker -> localhost:8080
./scripts/deploy-cloud.sh   # new Supabase project + Vercel

rebrand.sh writes branding and feature flags into a gitignored .env. deploy-local.sh checks for Docker (and guides installation if it’s missing), starts a local Supabase stack, applies migrations, seeds the first builder account, and brings up the whole app with one docker compose up. deploy-cloud.sh handles the interactive supabase login and vercel login, creates fresh projects, wires environment variables, and deploys.

The key property isn’t cleverness. It’s that every step is expressible as a command an agent can run and verify. No tribal knowledge, no “well, it depends.”

Why This Matters for a Non-Technical Customer

My customer doesn’t know what a migration is. They shouldn’t have to. With an agent-first setup, the operational complexity collapses into a conversation:

“Brand it ‘Acme Builds’ with a blue accent, turn off notes, and put it on the web for me.”

The agent asks the two clarifying questions the playbook tells it to ask, runs the scripts, and reports back a URL and a login. The customer never sees a terminal.

This is the part I think is genuinely new. For years, “developer experience” meant making things nicer for developers. Agent-first inverts that: the developer experience becomes irrelevant to the end user, because the developer is now the agent. The customer gets a product. The agent gets the burden.

It Was Built That Way From Day One

I want to be honest about why this fell out naturally, because I didn’t sit down and design it. I built this thing with AI: opencode driving GLM and DeepSeek models through most of the implementation. When your own build loop is “describe the change, let the agent implement and test it,” a strange thing happens: you start writing code as if the next operator is also an agent.

The same instincts that made my dev workflow work (clear, specific instructions; small idempotent scripts; no secrets in source; everything verifiable by a command) turned out to be exactly what the product needed to be operated by someone who doesn’t code. The line between “how I build it” and “how it’s operated” just disappeared.

So the app was planned alongside an LLM from the start, in two senses: it was written by LLMs, and it was designed to be run by them. That’s the agent-first mindset in one sentence.

What I’d Tell Someone Starting This

A few hard-won notes:

  • Never commit secrets. Every credential lives in a gitignored .env or in the platform’s own state (Vercel/Supabase). If the agent ever has to paste a key into a source file, you’ve failed.
  • Prefer scripts over prose. An agent will follow a command reliably; it will paraphrase a paragraph. Move every repeated action into a script and make the playbook reference the script.
  • Make it idempotent. The seed step finds an existing user and sets the role instead of crashing. The rebrand script updates only the keys you pass. Agents retry; your scripts should tolerate that.
  • Detect the environment. My prerequisite checker handles “Docker isn’t installed” and “Docker is installed but the daemon isn’t running” as separate cases. Non-technical users will hit both.

Final Thought

The result is a product that’s easier to ship, easier to support, and genuinely accessible to the person it was built for, not in spite of the automation but because of it.

Agent-first isn’t a framework or a library. It’s a decision: treat the LLM as your first-class operator, and let the human be the customer again.