console-visual ยท diff
git:20261001.2d27e94 to git:20261019.b1f9dd6
16 added, 5 removed. Audit A to A.
---
name: console-visual
description: Use when the owner console's doorbell carries a `visual` request (the owner pressed "Request a visual" on an item) - draw it as a Mermaid diagram or a static, self-contained HTML mock with a short doc, store it with `agent.py visual`, and land it by PR from your own worktree with `agent.py visual-export`. Called by console-process for every waiting visual request.
---
# Draw a visual the owner asked for
The owner pressed **Request a visual** on an item and said what it should
show. You answer with **one picture and a short doc**. The console server
stores them in its own state directory (never in the project) and shows them
on the item: a Mermaid diagram as its source text, an HTML mock inside a
sandboxed frame. To put them in the repository, you export them into **your
own worktree** and open a pull request (step 5).
Set up `KIT`, `STATE` and `A` as in the console-process skill: from the
user's registry only, and stop if this project is not registered there.
## 1. Find the request
A todo
`todo.visuals` lists every waiting request as its `id` and `item`. A visual
request is an owner message with `"intent": "visual"`; one is waiting when
nothing in `view.visuals[ITEM]` names it as its `request`. Read its item:
A view --item ITEM
The request is the message with that id in `view.threads[ITEM]`, and its
`text` says what to draw. If a read exits 4, run the narrower command named on stderr; do not retry the same command and do not add --full.
## 2. Choose the form
- **Mermaid** (`--format mermaid`, a `.mmd` file) for structure: a flow, a
state machine, a sequence, a dependency map. The console shows its
**source as text**; no diagram library runs on the owner's page. So write it
to read well as text too: short node labels, one edge per line.
- **HTML mock** (`--format html`, one `.html` file) for layout: what a screen
looks like at a width. It must be **self-contained and static**:
- inline `<style>` only; images as `data:` URIs; no external URL of any
kind (fonts, scripts, images, stylesheets): the server's policy lets it
load nothing else, so an external asset simply does not appear;
- **no JavaScript**. The frame is sandboxed with no scripts, and so is the
file when it is opened on its own. A mock that needs script to show its
states should show them side by side instead;
- no forms that go anywhere (they are blocked), and no text pretending to
be a login or a real product page.
- Either way, at most **256 KiB**. A larger one is refused by name, never
cut: split it into two visuals (a request takes up to three).
Write the drawing and the doc in a scratch folder, never inside the server's
checkout.
## 3. Write the doc
A few sentences to at most 4000 characters, plain text: what the visual
shows, what it leaves out, which spec lines or files it rests on
(`path:line`), and any decision it implies that the owner has not made. A
decision it implies goes to the console as a question (console-ask), never
decided in the doc.
## 4. Store it
A visual REQUEST_ID --format html --file grid.html --doc grid.md --title "Grid at 375 px"
`REQUEST_ID` is the request message's record id. The server:
- checks the request is an owner visual request, and the store's rules,
**before** writing anything;
- writes `<state>/visuals/<item>/<request[:8]>-<sha256[:12]>.html` (or `.mmd`)
byte for byte, and a `.md` doc beside it that links to it and quotes the
owner's request. **Nothing is written into the project**;
- appends one `visual` record holding the path, size and sha256. If the file
is later edited or swapped for a symlink, the console refuses to show it
and says why.
A refusal names what is wrong: fix it and run the command again. A retry of
the same content is stored once. The owner can see the visual now.
## 5. Land it from your own worktree, and reply
If `view.config.visuals_dir` is null, the project has nowhere to land
visuals: skip to the reply, and say it is in the console only.
Otherwise export into **your own worktree on a branch**. **Never run it
against the server's checkout** (the directory the console server runs
from): that checkout follows main with `git merge --ff-only`, and a file
written there blocks the next fast-forward. The command refuses it anyway,
naming why.
# from the repository YOU work in (your clone), not the server's checkout
- git fetch origin
- git worktree add <scratch>/visuals-<item> -b visuals/<item> origin/main
- A visual-export --project <scratch>/visuals-<item> --visual VISUAL_RECORD_ID
+ WT=$(A worktree new --kind visual --item ITEM)
+ A visual-export --project "$WT" --visual VISUAL_RECORD_ID
+ `A worktree new` (1.50.0) fetches origin, makes your own worktree under
+ `~/.overture/worktrees/<project>/` on the branch `overture/visual/<item>`
+ (cut from `origin/main`), marks the item worked on with that branch, and
+ prints its path. Run it again for the same item and it gives the same
+ worktree back (a fresh one once its PR merged or closed). It needs your agent
+ name, as `working` does. If it names another agent on the item (an overlap),
+ go on, and say so in your reply. If it prints a suggested setup step, Overture
+ has not run it: run it yourself, as its own Bash call, only if you need it.
+ Never make a worktree by hand.
+
`--project` must be the TOP of that worktree, never a folder inside it.
`--visual` may repeat; without it every stored visual is exported, and one
already in the worktree with the same bytes is skipped. It exits 0 when every
chosen visual was exported, **3 when files were written but a visual was
refused** (each refusal is named on stderr: land what was written and say in
the reply which one was not), and 1 when nothing was written. It writes
`<visuals_dir>/<item>/<name>.*` and regenerates `<visuals_dir>/INDEX.md` from
what is in that folder. It refuses, writing nothing, a different file already
at a target path, or an `INDEX.md` it did not generate: look, move the file
- aside if it is stale, and run it again. Then commit those paths only and open
- a pull request; never commit to the main branch. A decision-log or digest
+ aside if it is stale, and run it again. Then, in `$WT`, commit those paths
+ only, push the branch (`git -C "$WT" push -u origin HEAD`) and open a pull
+ request from it; never commit to the main branch. Leave the worktree: the
+ steward removes it once the PR merges or closes. A decision-log or digest
line about the visual, if the project keeps one, is added at merge time.
Reply once on the item:
A reply ITEM "Drew <title>: <one line>. PR <url>." --reply-to REQUEST_ID
and return to console-process.