Role for AI agents
Role: Builder
Build the site from the content structure, check it and publish it. If the theme and the pages are not ready yet, the builder does the work of the designer and content roles too, following their checklists. Shared rules are on the page Instructions for AI agents.
Commands run through the image. Without Docker, the pip package's heron command does the same with the same arguments.
In plain words
The builder is the foreman on the building site. It takes the plan, the theme and the pages, runs the build again and again until it is clean, packs the site, checks that it opens and writes a short report of what is done and what is still missing.
Example. The strict build stops: «E005 content/en/Roof Repair.md: invalid file name». The builder renames the file to roof-repair.md, runs the build again, and repeats until the build is clean. Then it makes the image, runs the smoke check and publishes.
You need this page when an agent (or you) has to turn a ready structure into a site that is online. If you only change texts, the content role is enough.
Input and output
Input: a document with the site structure (following templates/structure.md), sometimes texts and images.
Output: a site folder that builds with build --env prod --strict without errors; an image if needed; a report.
H="docker run --rm -v $PWD:/site -w /site --user $(id -u):$(id -g) ghcr.io/fmstm/heron:prod"
The path to the site is relative to the current folder: the container sees only that folder. Use . if you are inside the site folder.
The documentation of this HERON version: $H docs (table of contents), $H docs TOPIC, $H docs --search TEXT.
1. Create the folder
An agent has no interactive terminal, so new asks no questions: everything goes in flags:
$H new my-site --notes en --name "Site name" --domain example.com --lang en,ru -y
--lang: languages separated by commas, the first is the main one;--domainwithout the scheme. Do not know the domain? Leave it out: a placeholderNAME.examplestays, and that is a line in the report;--notes ru|en: the language of comments in every file and of messages on screen;enby default, remembered inbuild.notes;- a folder already under git (
.git,.gitignore,README) is fine:$H new . …; - the result:
site.yaml, a theme, a home page and a 404 in every language with an SEO block, notes in the folders. The starter site builds with--env prod --strictwithout warnings.
A folder with content already exists? Use $H init my-site instead of new: it adds what is missing and overwrites nothing.
2. Fill in site.yaml
A sample with every key: templates/site.yaml. The minimum:
heron: ">=0.1,<0.2"
site:
domain: example.com
theme: main
default_lang: en # served from the root: /about/
languages: [en, ru] # Russian lives under /ru/
name: Daybreak
name_ru: Рассвет # if it differs
seo:
title_suffix: " — Daybreak"
title_suffix_ru: " — Рассвет"
nav:
main: ["/", about, services, contacts] # page keys
Then add the language folders:
$H init my-site # content/LANG/index.md and 404.md, theme/i18n/LANG.yaml
What not to do: do not write an "approximate" domain, phone or counters: empty is better than invented. Do not put a Dockerfile, compose file or .env into the folder.
3. Theme
types and links in theme/theme.yaml come from the structure; one template per type, one module per form. How: the Designer page.
4. Content
One file per page of the structure; the file name is the key, the same in every language. A new page: $H page TYPE NAME my-site. How to write the SEO block and sections: the Content and SEO page.
5. The check cycle
$H check my-site # report without a build
$H build my-site # dev build into my-site/dist
$H build my-site --env prod --strict # like production: warnings are errors
Read the whole report. Errors (E0xx) stop the build: fix them. Warnings are grouped: images, links between pages, links in text, menu, translations, languages, content, other; the full list is in .heron-cache/warnings.txt next to the build. The "Not filled in" summary lists content debts: they go into the report.
Common errors:
| Code | What it means | What to do |
|---|---|---|
E002 |
no title/h1/description, or a field of the wrong type |
add it; dates as YYYY-MM-DD |
E004 |
two files give the same address | different slug |
E005 |
file name or slug is not Latin letters, digits and hyphens |
rename |
E006 |
a link field points to a page that does not exist | the file name without extension, not the address |
E007 |
a file from media/ is not on disk |
path from the site root |
E008 |
a type has no template | theme/templates/TYPE.html |
E009 |
redirect_from equals the page address or leads to two places |
remove the duplicate |
E011 |
site.yaml failed the check, or the theme requires an empty key |
read the message |
E012 |
the HERON version is outside the heron: range in site.yaml |
another image tag or range |
E020 |
structured data: a declared type is missing, an empty address in the site-wide node, prices | schema in site.yaml; prices via seo.allow_prices |
E021 |
production, but the main language is empty | fill it in or change default_lang |
E022 |
gone closes a page or overlaps with redirect_from |
choose one |
The full list: build, §11.
6. What to check in the built site
- the home page of every language opens; the page head has a
titlewith the suffix,canonical, hreflang (on a multilingual site); dist/sitemap.xmllists every indexable page (on a multilingual site through a file per language, for examplesitemap-ru.xml); 404 andnoindexpages are not there;dist/404.htmland the 404 pages of the languages, for exampledist/ru/404/index.html, are in place;dist/llms.txthas the description and the list (or the list of languages);dist/redirects.mapanddist/gone.mapmatch the move table;- the structured data (the script block of type
application/ld+json) has the types you need; the report counts pages per type.
7. Deploy
The dist/ folder goes to any static hosting, with .heron-nginx.conf for your own nginx. The image and the check of server answers come from a clone of the HERON repository:
./scripts/site.sh SITE build prod
./scripts/site.sh SITE image prod
./scripts/site.sh SITE smoke prod # 200, 404, every 301 and every 410
./scripts/site.sh SITE push prod
A site in its own repository without a HERON clone uses the reusable workflow FMSTM/HERON/.github/workflows/site-image.yml: it builds, packs, checks and pushes the image, no Dockerfile of your own needed.
In detail: the guide Build and deploy.
8. Report
What was done; which pages were created; which sections are not filled in (the debts summary); which facts are unconfirmed (questions for the client); which warnings were left and why; any differences between the documentation and how HERON behaves.
Checklist
site.yaml:heron:, domain, languages, name, menu; no invented facts- every type in the structure has a template; every page has a file
build --env prod --strictpasses without errors- the 301/410 maps match the move table;
smoke prodis green - the report: debts, questions, warnings left
Source
This page mirrors docs/agents/builder.md from the prod branch. The repository is updated first: builder.md on GitHub. The original is written in Russian.