--- name: board description: "Open and keep a board: the live HTML status page the Web UI shows beside a long task. Use whenever this session carries a [Board] block or is bound to a board, before editing any board.html, when you are about to dispatch several workers or start work that will run for many turns or hours, or when the user asks for a board, status page, dashboard or 看板 for a task. Covers board_open, the preset component classes, and when to update." allowed-tools: Read, Edit, Write, Bash, mcp__cortex-core__board_open, mcp__cortex-core__send_decision, mcp__cortex-core__current_time, mcp__cortex-core__cortex_context metadata: author: "Cortex" version: "1.2.0" --- # Board A board is one HTML page per long task, shown in the Web UI beside the conversation and on the phone. The app draws a live strip above the page by itself: title, every bound session's status, questions waiting for the user, and the decision stream from `send_decision`. You write the page body: what the task is, where it stands, what comes next, and what needs the user. Someone glancing at it for five seconds should know whether things are on track. ## When to open one Open a board when: - you are about to dispatch several workers, or - the task will clearly span many turns or hours (multi-stage experiments, a refactor in areas, a survey), or - the user asks for one. Skip it for a question, a single change, or anything you finish within the turn; the conversation already covers those. - `board_open({title})` creates a board, writes a scaffold into `board.html`, and binds this session plus your active workers. Workers spawned later inherit the binding. The conversation shows a card for the new board, and on desktop the board opens beside the chat. - `board_open({board: ""})` attaches to an existing board. A session is bound to at most one board. The tool returns the board directory; later, `cortex_context` reports which board this session is bound to (`board`: id, title, dir, or null). ## Files ``` /boards// board.html # the page body you edit: body content only, no / assets/ # images and other files the page shows or links decisions.jsonl # written by the server from send_decision; never edit ``` ## Writing the page - **Open with the head card**: title, an overall state chip, and a one-line `.lead` saying where things stand. Keep the lead current; it is what the user reads first. - **Replace the scaffold's examples** with real content on the first fill, and delete sections that do not apply. - **Use the preset classes** below. They follow the user's theme (light/dark, palette, accent) without any work from you. When they do not fit, write your own HTML, inline SVG charts, or a little inline `style`, and take colours from theme variables (`var(--proto-accent)`, `var(--proto-muted)`, …) rather than fixed values so the page still reads in dark mode. - **Images** go in `assets/` and are referenced relatively: `loss curve`. The app inlines them (up to 2 MB each). - **Outputs**: put a file the user should open into the board's `assets/` and link it with `report.md`; a click opens it in the app. `data-open` only reaches files inside the board directory, so name anything elsewhere as path text without a link: `experiments/run-12/metrics.json`. Ordinary `https://` links open in the browser. - **Keep it static.** The page runs in a sandbox; scripts are not needed for anything the presets do. - **Decisions**: record them with `send_decision`; the strip shows them. On the page, keep at most a short "key decisions" row list. - Write in the user's language. - The user may restyle every board with `~/.cortex/config/board.css`; leave that file alone unless they ask. ### States One vocabulary across `chip`, `step`, `meter i`, `legend .sw` and `ic`: | modifier | meaning | look | |---|---|---| | `ok` | done | success green | | `run` | in progress | accent | | `ask` | waiting on the user (a question, a review, a go/no-go) | light amber; nothing else on the page is amber | | `wait` | blocked on a machine or someone else: queue, GPU, rate limit, external review | hollow, dashed | | `bad` | failed, unexpected, risk | danger red | | none | not started | gray | Use `ask` only for things truly waiting on the user, so the amber stays meaningful. ### Components | class | use | shape | |---|---|---| | `stack` | vertical spacing between blocks | `
…cards…
` | | `card` | a glass panel; one topic each | `
…
` | | `grid`, `grid wide-left` | cards side by side (auto columns; `wide-left` is 1.3 : 1) | `
…
…
` | | `h`, `.n` | small section heading, optional count | `
Acceptance 3 / 11
` | | `head`, `.meta` | title line | `

Title

in progressupdated MM-DD HH:MM
` | | `lead` | the one-line status under the head; `` for the key fact | `
Stage B merged. C waits for a GPU.
` | | `chip` + state | a state label | `waiting` | | `meter`, `legend .sw` | progress, one `` per unit | `
` and `
done 1
` | | `steps` > `step` + state | stage cards: `.top` (`.k` name + chip), `.t` what it delivers, `.m` a fact | `
Crunning
…
2 / 5
` | | `rows` > `row` | lists of acceptance criteria, checkpoints, decisions, risks, outputs: `.id`, `.body` (with `.sub` second line), `.end` | `
✓A-2……4a85587c
` | | `ic` + state, `ic risk`, `ic todo` | the icon at the start of a row; you choose the glyph (✓ ◐ ● ◌ ▲ ○) | `▲` | | `tl` | a timeline card: each row starts with `.when` | `
MM-DD HH:MMdone…
` | | `mono`, `muted`, `faint`, `code` | text tones and inline code | `…`, `path` | Plain `p`, `ul`, `table` and `img` are styled to match. The scaffold written by `board_open` has a working example of each component. ## When to update - At milestones: a stage finishes, a result comes in, something merges. - On state changes: work starts, blocks, fails, needs the user, unblocks, or finishes. - With each update, refresh the head chip, the `.lead` line and the `updated` time. - **Read the clock for every time you write**: the `updated` stamp and each timeline `.when`. Call `current_time` (or run `date`) right then; never estimate a time or reuse one from earlier in the conversation. The timeline is ordered by these times, so a guessed time puts rows from different sessions out of order. The board is a summary, not a log. Skip small steps, keep the timeline to notable events (newest first), and trim it when it grows long. The app re-renders an open board within a few seconds of a save.