What a build run is
Every change to your app is one build run — a single conversation between the builder and your project's files, with a beginning, an end and a record.
A build run is one attempt by the builder to change your app. You start one every time you send a message in the project chat. Everything the builder does — reading a file, writing a file, running a command, giving up — happens inside a run.
Understanding runs is the key to understanding the whole product. The chat, the step list, version history, credits and the audit are all organised around them.
What starts a run
Four things start a run, and nothing else does:
- Creating a project with a prompt. The first run begins immediately, before you reach the project page.
- Sending a message in the project chat. One message, one run.
- Pressing "Fix these issues" in the security check. The findings become the prompt.
- Pressing "Get me unstuck" after a failed run.
A restore from version history also appears in the run list, but it is not a real run: no model is called and nothing is charged. See Restoring a version.
One run at a time
A project can only have one run in flight. If a run is already running or queued and you try to start another, the server refuses with:
A build is already running on this project.
The chat composer disables itself while a run is live and its placeholder changes to Building…, so in normal use you cannot hit this.
An archived project refuses too:
This project is archived — restore it first.
An empty message is refused with:
Say what you want built.
The six statuses
Each run carries a status. These are the exact values stored:
| Status | What it means |
|---|---|
queued |
The run has been recorded but the builder has not picked it up. In practice this lasts milliseconds. |
running |
The builder is working. |
done |
The run finished. This covers the ordinary case — the builder called finish — and also a run that stopped at the step ceiling or ran out of credits partway. Work already written to your app is kept. |
failed |
Something threw an error. The reason is stored on the run and shown in the chat. |
cancelled |
You pressed the stop button. |
A run that was in flight when the server restarted is marked failed on the next start-up with the message:
The server restarted while this run was in flight.
What the builder can actually do
The builder is not free to do anything it likes. It is given exactly nine tools and can do nothing outside them:
| Tool | What it does |
|---|---|
list_files |
Lists every file in the project. node_modules, .next and .git are excluded. |
read_file |
Reads one file. |
write_file |
Creates a file, or replaces one completely. Parent folders are created as needed. |
edit_file |
Replaces an exact piece of text inside a file. |
delete_file |
Deletes one file. |
run_command |
Runs a shell command in the project folder — npm install react-icons, next build, ls. Output is capped and the command is killed after 3 minutes. |
dev_server_log |
Reads the tail of the development server's log. This is where compile errors show up. |
restart_dev_server |
Restarts the development server. Only needed after a config change. |
finish |
Ends the run with a short summary, which is the message you see in the chat. |
Some commands are refused outright. Anything matching next dev, npm run dev, yarn dev, pnpm dev, nohup, shutdown or reboot comes back as:
run_command refused: the dev server is managed for you (use restart_dev_server), and long-lived/background processes are not allowed.
That is deliberate. Bookbag runs the development server for you and keeps it healthy; a second one started by the builder would fight it.
What the builder is told
Before the first message of a run, the builder is given:
- Its working rules — how to write files, when to verify, what never to do.
- The design you chose, if you chose one. The design's instructions are injected as a block headed
## Design direction — <name>and the builder is told to follow it over its own defaults. See Designs. - The active skills an administrator has published. These are playbooks for recurring jobs. You never see them and cannot change them. See Skills.
- Your prompt, followed by a full list of the files that currently exist in your project. This is included so the builder does not have to spend its first move asking what is there.
Everything the builder and you have said on this project before is replayed as well, so a run always has the project's full history. When that history gets very long it is summarised first to stay inside the model's context window.
The limits on a run
| Limit | Value |
|---|---|
| Steps in one run | 60 |
| Shell command timeout | 3 minutes |
| Longest file the builder can read | 60,000 characters, then truncated |
| Files listed | 500 |
| Model output per turn | 8,000 tokens |
| Wall-clock limit on a whole run | none |
A "step" is one turn of the conversation: the model thinks, calls some tools, gets the results back. Sixty is generous for an ordinary change and is there to stop a confused run from spending your credits forever. If a run uses all sixty it ends as done with:
The run used all 60 steps. Send a follow-up message to continue.
Sending a follow-up picks up where it left off, because the history carries over.
Going in circles
A run that calls the same tool with the same arguments three turns in a row is treated as stuck. The first time, the builder gets a nudge inserted into the conversation telling it to step back and try something different. If it happens again, the run ends:
The run stopped after repeating the same actions without progress.
You will see a step reading Stopped: repeated actions without progress.
Watching a run happen
The project page keeps a live connection open to the server for the duration of the run. Text appears in the chat as the builder writes it, and each action appears in the step list underneath. See Build steps.
If you close the tab or lose your connection, the run keeps going — it is running on the server, not in your browser. Reopen the project and the finished result is there. The page does not reconnect to a run in progress, so you may see a stale view until the run ends and you reload.
Stopping a run
The send button becomes a square stop button while a run is live. Pressing it shows:
Cancelling after the current step…
That wording is exact. The cancel is checked at the start of each step, so the model turn already in flight finishes first, along with any tool calls it made. The run then ends with status cancelled and the summary "The run was cancelled."
Nothing is rolled back. Files the builder had already written stay written. If you want them gone, restore from version history.
If the run had already finished, cancelling returns:
That run already finished.
What a run records
When a run ends, these are written to it permanently:
- The prompt you sent.
- The summary the builder wrote, or the error that stopped it.
- Every step, in order.
- Tokens in, tokens out, cached tokens, and the credits charged.
- Whether it was metered — that is, whether it spent platform credits or ran on your own provider key.
- Every file it created, edited or deleted, with the content before and after.
That last one is what makes version history possible.
Next
- Build steps — what each line in the activity list means.
- The sandbox — where your app actually runs.
- When a build fails — every failure message, and what to do about each.