dashboard · diff

git:20260731.d8f9819 to git:20260731.c335985

22 added, 1 removed. Audit B to B.

---
name: dashboard
description: Update the agent's Home dashboard. Use when the user says "update my dashboard", "redesign my home", "put X on the dashboard", or "/dashboard".
---
# Dashboard Skill
The agent's Home is a single file, `.co/dashboard.html`, beside `.co/skills/`. (Older agents keep theirs in the project root — if `dashboard.html` is there, that is the one being served: edit it where it is, don't create a second one.) OChat renders it in a sandboxed iframe beside the chat and re-reads it after every run. You edit it with your normal file tools (Read, Edit, Write, Bash) — there is no special API.
## Instructions
1. **Read the file first** — `.co/dashboard.html`, or the root `dashboard.html` if that is where this agent's already is — so you preserve its structure and styles before changing anything.
2. **Make the smallest edit that satisfies the request** — change the data or add a section; don't rewrite the whole file unless the user asks for a redesign.
3. **Keep it visual, not textual.** Lead with big numbers, generous whitespace, and clear action buttons. A dashboard is a glanceable Home, not a document.
4. **Write the file** and stop. OChat picks up the change automatically after the run.
## Action buttons — the one contract
A button that runs something MUST be a real, user-invocable skill, wired like this:
```html
<button data-ochat-skill="daily-brief">Build today's brief</button>
```
- The `data-ochat-skill` value is the exact skill name; OChat validates it and runs `/daily-brief` as a visible chat turn.
- Optional arguments: `data-ochat-skill="meeting-prep" data-ochat-args="2pm sync"` → runs `/meeting-prep 2pm sync`.
- Use an **outcome-oriented label** ("Prepare my next meeting"), not the raw skill name.
- Only reference skills that actually exist. Never invent skill names, and don't add buttons for internal/bootstrap skills.
- **Only project skills work as buttons** — the ones in `.co/skills/` or `.claude/skills/`. Your personal skills (`~/.co/skills/`) and builtin skills aren't published to clients, so a button for one renders but silently refuses to run. Check the skill's location before wiring it up.
+ ## Filtering a long list
+
+ A Home pane that lists thirty skills is a wall. Declare the list filterable and
+ the client renders the box and does the filtering:
+
+ ```html
+ <co-filter target="#skills" placeholder="Filter skills"></co-filter>
+ <div id="skills">
+ <button data-ochat-skill="daily-brief">Build today's brief</button>
+ <button data-ochat-skill="meeting-prep">Prepare my next meeting</button>
+ </div>
+ ```
+
+ - `target` is a CSS selector for the container. Its **direct children** are what
+ get shown and hidden, so wrap each row in one element.
+ - Matching is case-insensitive and anywhere in the row's text.
+ - You write the tag; you never write the behaviour. There is no script to add,
+ and adding one would not run.
+ - If `target` matches nothing, no box is rendered — a filter that filters
+ nothing looks like a working control and is not one.
+
## Rules
- One file: `.co/dashboard.html`. No sidecar JSON, no build step.
- Keep it under 2MB — the host won't send a larger file, and the Home pane goes blank. Inline images are base64, which is ~33% bigger than the source file, so compress screenshots before embedding them.
- Keep the responsive layout and `prefers-color-scheme` dark mode intact.
- **A media query here measures the Home pane, not the browser window.** The page renders inside its own iframe, so `@media (max-width: 560px)` means "when the pane is narrower than 560px" — the question you wanted to ask. No container queries needed. The pane is resizable, roughly 320–900px, so design for the narrow end: a four-column table needs about 500px, and below that the column the table exists for ends up off the right edge behind a scrollbar. Give wide tables a stacked form for narrow panes.
- - Do not add `<script>` tags or inline `onclick` handlers — OChat strips all scripting; only the `data-ochat-skill` button contract works.
+ - Do not add `<script>` tags or inline `onclick` handlers — OChat strips all scripting. Interactivity comes from the declared tags (`data-ochat-skill`, `<co-filter>`), which the client renders for you.
- Keep styles inline in the file (external URLs are blocked in the sandbox).
- **No links out.** A Home page is one self-contained page. Don't add `<a href="https://…">` — the client cancels those clicks, so the link renders as dead text. Same-page anchors (`href="#section"`) work fine. If you want the user to *do* something, that's what a `data-ochat-skill` button is for.