ZeroStarter

Working with Agents

The loop an AI agent uses here: skills, a local login, agent-browser, and llms.txt.

An AI coding agent that opens most repositories has to guess: where routes live, what the response shape is, how to run the thing, how to log in and test. ZeroStarter hands it a playbook instead. Point Claude Code, Cursor, or your own agent at the repo and it can build a real feature (and check that it works) without you narrating every step.

Four things make that possible, and none of them are magic:

  • Skills: step-by-step recipes for this repo's real tasks.
  • A local sign-in: one request to an authenticated session, no OAuth.
  • agent-browser: the agent drives the running app like a user.
  • llms.txt: the whole codebase as context, generated.

Scope

This is about AI agents that build on the codebase: coding assistants. ZeroStarter does not (yet) ship primitives for end-user agents that operate your product in production; that is your app to design.

The loop

The full cycle an agent runs, start to finish:

# 1: scaffold a product (init sets AGENT_SIGNIN_ENABLED=true, enabling Login (agents)), then start the stack
bunx zerostarter init
bun run dev   # serves named .localhost URLs; `bunx portless get zerostarter` prints the web URL

# 2: sign in locally (drive the real UI, or the curl below)
agent-browser open "$(bunx portless get zerostarter)"
agent-browser snapshot                  # get refs for the page
agent-browser click "@e5"               # the "Login (agents)" button ref

# 3: build a feature by following a skill (api-endpoint, db-migration)
# 4: verify it in the running app, behind auth
agent-browser snapshot                  # read the page, then act

Scaffold, run, sign in, build, verify. Each step below is one of those pieces.

Skills

Skills live in .agents/skills/ (and .claude/skills/ is a symlink to it, so Claude Code, Cursor, and Codex read the same files). Each is a SKILL.md with a trigger and a literal procedure: not a vague prompt, but this repo's exact conventions and its known traps.

For example, the api-endpoint skill hands the agent the Hono router template, the mandatory validation hook, where to wire the route, the restart step, and the curl to test it. The dev skill documents the one trap that stalls agents most (bun --hot won't pick up newly-created files) and the exact restart that fixes it.

See AI Skills for the full catalog and how to write your own.

Local sign-in

Testing anything behind auth normally means an OAuth round-trip an agent can't complete. ZeroStarter ships a local-only sign-in that returns a real session in one request. bunx zerostarter init sets AGENT_SIGNIN_ENABLED=true for you, so the route is already live; if you cloned the repo instead, set AGENT_SIGNIN_ENABLED=true in .env first (it is off by default, so the route stays unmounted until you opt in):

WEB=$(bunx portless get zerostarter); API=$(bunx portless get api.zerostarter)
curl -sS -c cookies.txt -X POST -H "Origin: $WEB" "$API/api/agents/sign-in-as"
curl -sS -b cookies.txt "$API/api/v1/user"   # now authenticated

It signs in as LocalAgent and sets the session cookie. The sign-in that creates the account makes it an owner, so the whole console is reachable including the owner-only rules; after that its rung stands as it is, which is what lets you demote it to see what a lower rung sees. bun run console:roles grant agent@local.host owner puts it back. In the browser, the dev-only Login (agents) button does the same thing; in a dev build it appears once AGENT_SIGNIN_ENABLED is true, so a visible button always has a live route behind it.

Local only, by construction

The route mounts only when NODE_ENV is local and AGENT_SIGNIN_ENABLED is true. It ships off (blank) in .env.example, so a fresh clone and any deployed default env expose no session-minting route: it returns 404. bunx zerostarter init sets it only in your local (gitignored) .env, so agent login works in local dev without touching a deploy, where NODE_ENV is not local and the route stays down regardless. The Login (agents) button appears only in a dev build when the API advertises the route, so it never posts to a route that would 404. The trusted-Origin check still guards each request.

agent-browser

The bundled agent-browser skill is a fast, CDP-based browser CLI. An agent uses it to drive the actual running app (navigate, click, type, screenshot, read the accessibility tree) instead of mocking the UI. Combined with the local sign-in, it can operate the product end-to-end and confirm its own work.

agent-browser open "$(bunx portless get zerostarter)/dashboard"
agent-browser snapshot        # structured page state with element refs
agent-browser click "@e12"    # act on a referenced element

llms.txt

/llms.txt and /llms-full.txt are generated from the docs on every build. llms-full.txt opens with a preamble that hands an agent the monorepo layout, the workspace import map, the stack, and the conventions: enough to write correct code without crawling the tree. See llms.txt.

Docs that can't drift

AGENTS.md (symlinked to CLAUDE.md) makes one rule load-bearing: documentation is updated in the same change as the code. When a convention moves, its skill and doc move with it. Paired with the symlinked skill directory, what an agent reads is always what the code actually does: the single biggest cause of agent mistakes, designed out.

It is enforced, not just requested. Docs structure and page metadata live in one file, web/next/docs.config.ts, and the build derives every page's frontmatter and sidebar from it; docs.ts --strict fails the build when a page and the config disagree, so a doc can't silently fall out of sync. The doc-sync skill is the checklist an agent runs to keep code, docs, and skills aligned in the same change.

Next