Skip to the content.

Usage

Day-to-day commands and recipes. See WORKFLOW.md for the gate-by-gate walkthrough and CONFIG.md for every project.yml option.

The command

./bin/design <command> [--project <slug>]

--project works before or after the command. If you omit it, the tool uses the only project present, or the slug in config/current.

Command Does
init <slug> [--from room\|kitchen] Scaffold a new job
status Where the job is: room, directions, views rendered, spend, gates
gates Every gate, what it guards, whether it is approved
check Validate config, geometry and layouts. Run this constantly
drawings [NN\|--shell] Measured drawings for one direction, or the empty room
pack <NN> ONE direction, end to end, then stop. The unit of review
render [NN] [--backend B] [--wait] [--force] Photoreal views
report [--no-pdf] Build the client report
approve <gate> [--note "..."] [--revoke] Record or withdraw an approval

Recipes

Start a job

./bin/design init drawing-room
cp ~/client-photos/*.jpg projects/drawing-room/refs/
./bin/design status

Then /interior-design in Claude Code, or drive the agents yourself.

See the empty room before designing anything

./bin/design drawings --shell
open projects/drawing-room/drawings/_shell-plan.png

Do this early and actually look at it. Drawings expose errors prose hides.

Review one direction properly

./bin/design pack 03

Builds its drawings and every camera view, then stops and prints a QA checklist. Run the design-critic agent on the result.

Test the whole pipeline without spending anything

./bin/design render --dry            # every view
./bin/design render 03 --dry         # one direction

Builds every prompt, resolves every reference image and checks it exists — but calls no image model and writes nothing. Free, instant, and works while a quota is exhausted. Use it before any real run: it catches a missing drawing, a photo named in the config but absent from refs/, a view with no camera, or a spec with no scene, all of which would otherwise waste quota to discover.

  ✓ 03-heritage-vitrine-gallery-hero-in  ~2730 prompt tokens, refs: …-plan.png, …-iso.png, …-photo.jpg
  ! 03-heritage-vitrine-gallery-alcove   …
      warn   'elev-w4' falls back to the empty-room drawing - this direction's furniture
             will not appear on it. Run: design drawings 03-heritage-vitrine-gallery

Render everything

./bin/design render                       # free backend, stops on quota
./bin/design render --wait                # free backend, rides out the quota reset
./bin/design render --backend openrouter  # paid, needs the `spend` gate

Resumable in every case: finished views are skipped, so re-running costs nothing.

Re-do one direction after changing its spec

./bin/design check
./bin/design drawings 07
./bin/design render 07 --force

Fix a wrong dimension

Change project.yml, then regenerate. Never edit a drawing or retouch an image — the whole point is that one file is the source of truth.

$EDITOR projects/drawing-room/project.yml
./bin/design check
./bin/design drawings --shell

Work on several jobs

./bin/design status --project kitchen-refit
echo kitchen-refit > config/current      # make it the default

Check what a render will actually be told

python3 -c "
import sys; sys.path.insert(0,'.')
from engine.project import resolve
from engine import prompts
import json, pathlib
p = resolve(None)
spec = json.loads(pathlib.Path('projects/study-terrace/directions/01-make-good.json').read_text())
print(prompts.build(p, spec, 'hero-in'))"

Worth doing when a render keeps coming out wrong — the answer is usually visible in the prompt.

What gets committed

Committed Not committed
project.yml — the brief and room model refs/ — the client’s photographs
brief/*.md — the survey drawings/ — generated
directions/*.json — the authored specs renders/ — generated
STATE.json — the approval record report/ — generated

Everything on the right is reproducible from everything on the left. Photographs of someone’s home are their property and stay out of version control.

To rebuild a job from a fresh clone: restore refs/, then

./bin/design drawings --shell
for d in projects/<slug>/directions/[0-9][0-9]-*.json; do
  ./bin/design drawings "$(basename "$d" .json)"
done
./bin/design render
./bin/design report

Cost control

render:
  backend: openrouter
  max_spend_usd: 15

The ceiling is enforced against the real per-image cost the API returns, not an estimate. The run stops rather than overspending. Spend to date is in ./bin/design status and itemised in projects/<slug>/renders/_cost.jsonl.

Measured at $0.183 per image on openai/gpt-image-2 over 29 billed renders.

The free codex backend yields roughly 45–50 images per quota window, resetting in about 4–5 hours. Both shipped templates fit in one window:

Job Images Codex OpenRouter
room default, 6 × 3 18 one session ~$3.30
kitchen default, 5 × 4 20 one session ~$3.66
One direction, 6 views 6 one session ~$1.10
20 × 6 120 ~3 sessions ~$22

design render and design status both print the forecast before you commit to anything.

The real cost trap is re-rendering. Getting the room model wrong and redoing 120 images is another $22, which is exactly why the pilot gate makes you review one 6-image direction first.