HERON

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; --domain without the scheme. Do not know the domain? Leave it out: a placeholder NAME.example stays, and that is a line in the report;
  • --notes ru|en: the language of comments in every file and of messages on screen; en by default, remembered in build.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 --strict without 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 title with the suffix, canonical, hreflang (on a multilingual site);
  • dist/sitemap.xml lists every indexable page (on a multilingual site through a file per language, for example sitemap-ru.xml); 404 and noindex pages are not there;
  • dist/404.html and the 404 pages of the languages, for example dist/ru/404/index.html, are in place;
  • dist/llms.txt has the description and the list (or the list of languages);
  • dist/redirects.map and dist/gone.map match 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 --strict passes without errors
  • the 301/410 maps match the move table; smoke prod is 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.