Editing a theme
The person says: “Make the hero blue on the venue site, but make sure it works on phones.”
To change a theme’s code, start empress.theme_session_start through Empress:site_call, then Empress:theme_stage with that session — never a local checkout. Theme code changes in an edit session: a private branch of the theme’s code, edited file by file through Empress:site_call. The platform builds and checks the session, stages it next to live, and renders the stage. Nothing reaches visitors until the promote, and the session becomes the theme only after the promoted pages pass their check.
Step one
Section titled “Step one”Ask which layer the request is in: Empress:site_call with tool: "empress.change_classify" and the person’s sentence as args.intent. A data answer is not theme work at all — follow its next (a content, menu or composition edit in a change set, previewed in seconds). A code answer names the files, and the loop below is the way. An engine answer is a clear no with the nearest thing offered; say so, offer the nearest, and stop.
Before editing
Section titled “Before editing”Read the site’s theme brief, skill://theme-brief/<site> (its address is in Empress:site_status’s theme section): its routes, collections, design rules and gotchas are current for this session.
The loop
Section titled “The loop”Empress:whoami— the site’s slug.Empress:site_status— what is live, whether something is already staged, and the theme brief’s address.Empress:site_callempress.theme_session_start— with a shortnamefor the change. Starting again with the same name returns the same session.Empress:site_callempress.theme_file_read— an emptypathlists the root; then read the file to change. To find where something is used,empress.theme_file_searchanswers everypath:linein one call (globnarrows it to*.astroorsrc/**/*.css); to see what the session has changed so far,empress.theme_diffanswers the unified diff per file, and with apath, that file’s commits on the session.Empress:site_callempress.theme_file_patch—files, each with apathand eitheredits(each quoting text that appears exactly once,anchor, and itsreplace),createfor a new file, ordelete. One call is one commit by the person, so put a whole change (layout, components, tests) in one call; a wrong anchor in any file saves nothing. For a single file,pathwith the same field works too.Empress:site_callempress.theme_check—kind: "build", which also typechecks: a type error fails the build with its file and line (add"test"when the theme has tests). A run longer than about a minute answers “running”: follow it withEmpress:work_statusand itsbuildIdastaskId(its phase and its last lines), then callempress.theme_checkagain with the same arguments for the verdict. A build that failed is read withempress.build_logand itsbuildId.Empress:site_preview—target: "session"andsessionset to the branch, the default three widths, andprobes: { layoutShift: true }for a layout change. A passed build is deployed as the session’s own Preview on the site (the check’s answer sayspreview), so the session is drawn on the site’s own data before anything is staged. If it answers that the Preview is still being deployed, call it again in a few seconds. A pooled site has no Preview: skip to step 8.Empress:theme_stage— withsessionset to the session.Empress:site_preview—target: "stage", the default three widths, andprobes: { layoutShift: true }for a layout change;fullPage: truewith thepathof a long page, orselectorfor just the section being changed;probes: { tokens: true, layout: true }to list, once per cause with its count and first three elements (detail: truefor every one), what is off the theme’s scale and what overflows, clips, stretches or reads faint;compare: "live"(or"reference"during a migration,{ "asset": "<media id>" }against a design frame) to have what changed boxed and named.Empress:theme_promote— only when every width rendered and the person agreed;confirm: true.Empress:site_status— in a minute: whether the pages passed and the session became the theme, or were put back and the session stayed a branch to fix.
A branch pushed from the CLI stages the same way: skip to step 8 with its name as session (it has no session Preview until a build of it has been checked with empress.theme_check). A discarded or merged session takes its Preview with it. A release staged by ref (a branch tip or a commit ahead of the theme) becomes the theme’s main branch too, once its pages pass, when it builds on main. When it does not, Empress:theme_promote refuses before anything changes, in one sentence, and next names a fresh empress.theme_session_start: a session starts from what is live, so make the change again on top of it. Empress:site_status says “The live commit is not main” in its theme section whenever the two differ.
One change is one call. Moving the hero into its own component, with its test, and retiring the old partial is a single Empress:site_call with tool: "empress.theme_file_patch" and args: { "session": "hero", "message": "Move the hero into its own component", "files": [ { "path": "src/layouts/Base.astro", "edits": [ { "anchor": "<Header />", "replace": "<Header />\n<Hero />" } ] }, { "path": "src/components/Hero.astro", "create": "<h1 class=\"hero\">…</h1>\n" }, { "path": "tests/hero.test.ts", "create": "…" }, { "path": "src/partials/hero.html", "delete": true } ] }. A wrong anchor in the layout saves none of the four. A call saves up to 1 MB in all; a bigger change is several calls.
Judgment
Section titled “Judgment”- Clone when a patch is the wrong tool. If you have a shell and the change is a refactor across many files, a dependency or lockfile change, or something you want to run locally (the theme’s own tests), call
Empress:site_callempress.theme_session_clonewith the session,git clone --branch <session>the address it answers, commit, and push that branch only (nevermain), thenempress.theme_checkandEmpress:theme_stageas usual. The address is a credential that works for an hour and can write the whole theme repository, so keep it out of logs and messages; for a change to a few files, patch. - A failed check stops the loop. The answer’s first line says what is wrong; patch, check again. A session whose build or typecheck failed is not staged (a failed test stops a stage only if it passes on the theme’s main), so “it is done” is never said of a session that does not build.
- An anchor that misses or matches twice saves nothing and answers the file as it is: copy the anchor from that content, adding a neighbouring line until it is unique.
- A 500 at any width stops the loop. Fix the session, check it, stage it again, render it again. Never promote “except for the phone”.
- Same session, same stage. Staging again after a fix replaces the stage; there is no need to clear it.
- A stage that says “Before promoting: …” is a warning, not a refusal. Today’s one: the theme adds a route (say
/events) that a redirect kept in the site’s own admin sends elsewhere, so visitors never reach it though the stage preview shows it. Read the site’s redirects withEmpress:site_callempress.site_redirects, then have the person remove or change that one in the site’s admin (or drop the route), and stage again. - Main moved since the session started?
Empress:site_callempress.theme_session_updatemerges main into the session. On a clean merge, the session tip advances and the answer names the files main brought in. On a conflict, nothing is committed: the answer carries each conflicted file’s content from the session (ours), from main (theirs) and from their common ancestor (base); patch each file to resolve, then callempress.theme_session_updateagain withresolved: trueto commit the merge. - Live moved since the stage?
Empress:site_statussays so; stage again on top of what is live rather than forcing. - A poor layout shift at a width is a finding to show the person, not a blocker to hide.
- A theme too big for a session (pictures and fonts past the session’s limit) is refused with the way through: push a branch with the CLI and stage it.
- A session nobody wants is thrown away with
empress.theme_session_discard; the theme and the site are untouched. - A theme change that comes with copy or menu changes goes in a change set: pass its id to
theme_stageand promote the set instead (seecomposing-a-change-set).