# AGENTS.md — chart-dashboard

Instructions for any AI coding agent working in or with this repository.
Vendor-neutral: no Claude-specific tools, formats, or APIs are required.

## What this repo provides

A reusable capability: **turn supplied data into a single self-contained HTML
dashboard, report, slide deck, printable one-pager, email-safe chart snapshot,
Teams post or social media post with SVG charts.** No CDN, no npm install, no build step, no runtime dependencies.

The canonical instructions live in
[`plugins/chart-dashboard/skills/chart-dashboard/SKILL.md`](plugins/chart-dashboard/skills/chart-dashboard/SKILL.md). That file
is the source of truth — this one only routes you to it.

## When to use it

Any request to build a dashboard, analytics page, KPI view, chart deck,
illustrated data report, one-page printable brief or handout, charts to paste
into an email, an insights post to share in Microsoft Teams, or a chart to post
on LinkedIn, X, Bluesky, Threads, Mastodon or Instagram, from data the user
provides or describes — a table, CSV, pasted numbers, metrics, notes, or a
topic with figures in it.

## How to use it

1. Read [`plugins/chart-dashboard/skills/chart-dashboard/SKILL.md`](plugins/chart-dashboard/skills/chart-dashboard/SKILL.md) and
   follow its workflow.
2. Read these before writing chart code — do not guess option names:
   - [`references/chart-api.md`](plugins/chart-dashboard/skills/chart-dashboard/references/chart-api.md) — the core API (factories, shared options, sizing); then `references/charts/<type>.md` for only the chart types you use
   - [`references/chart-selection.md`](plugins/chart-dashboard/skills/chart-dashboard/references/chart-selection.md) — data shape → chart type
   - [`references/layout.md`](plugins/chart-dashboard/skills/chart-dashboard/references/layout.md) — rules shared by every format; routes to `layout-dashboard.md`, `layout-report.md`, `layout-deck.md`, `layout-onepager.md`, `layout-email.md`, `layout-teams.md` or `layout-social.md` (read only the one for your format)
   - [`references/annotation.md`](plugins/chart-dashboard/skills/chart-dashboard/references/annotation.md) — callouts, plot bands, forecast vs. measured notation
   - [`references/narrative.md`](plugins/chart-dashboard/skills/chart-dashboard/references/narrative.md) — action titles; where a finding goes (title, insight column, or card)
   - [`references/design-rules.md`](plugins/chart-dashboard/skills/chart-dashboard/references/design-rules.md) — emphasis, legends, chart count, the one design system: the full form of SKILL.md's rules
   - [`references/verify-and-ship.md`](plugins/chart-dashboard/skills/chart-dashboard/references/verify-and-ship.md) — the static check, the browser audit and `finalize.js` (SKILL.md steps 7–8)
   - [`references/controls.md`](plugins/chart-dashboard/skills/chart-dashboard/references/controls.md) — read before adding a filter or dropdown
   - [`references/theming.md`](plugins/chart-dashboard/skills/chart-dashboard/references/theming.md) — brand recolour, and the two scripts under `scripts/` that generate it
   - [`references/editable.md`](plugins/chart-dashboard/skills/chart-dashboard/references/editable.md) — only when the user asked for an editable page
   - [`assets/charts-lib/charts.manifest.json`](plugins/chart-dashboard/skills/chart-dashboard/assets/charts-lib/charts.manifest.json) — quick per-engine facts (data shape, refusals, sizing)
3. Start from a template in `plugins/chart-dashboard/skills/chart-dashboard/templates/`: `dashboard.html`,
   `report.html`, `slides.html` (a deck), `onepager.html` (one printed sheet),
   `email.html` (a chart block to paste into Outlook or Gmail), `teams.html`
   (rich text and chart pictures to paste into a Teams chat or channel),
   `social.html` (chart cards painted at each platform's picture size, with
   the words to post), or
   `dashboard-editable.html` / `report-editable.html` /
   `slides-editable.html` / `email-editable.html` / `social-editable.html` (only when an editable page
   was asked for; a one-pager has no editable template and isn't offered one).
4. When you want a worked reference, read one of the finished pages in
   `examples/` — `logistics-network-dashboard/` (dashboard, most chart types),
   `coffee-pricing-deck/` (deck with the full spine), `ev-retrospective/`
   (report). Read the templates and references first; the examples show how one
   finished page turned out, not what every page should look like.
5. Stage the library beside your output while you build and verify it, then
   fold it in and ship one file:
   ```bash
   node plugins/chart-dashboard/skills/chart-dashboard/scripts/finalize.js index.html --stage   # verify against this: run charts-lib/audit.js in the page (SKILL.md step 7)
   node plugins/chart-dashboard/skills/chart-dashboard/scripts/finalize.js index.html           # inline, clean up, gate
   ```

## Non-negotiables

- `theme.js` must load **before** `charts.js`. Reversed, `charts.js` starts on
  its built-in defaults and logs a missing-theme warning; keep the order so the
  page's theme is in place before any chart code runs.
- Donut and pie options (`centerText`, `valueSuffix`, `variableRadius`,
  `startAngle`/`endAngle`, `showPercentages`) live under `plotOptions.pie`, not
  at the top level. At the top level they are silently ignored.
- Never invent numbers that read as real measurements. If the user gave a topic
  with no data, say so and label the figures illustrative on the page itself.
- Do not add a CDN link, npm dependency, or build step. The output must open
  offline by double-click.
- Build static pages unless the user asked for an editable one. An editable page
  ships as two files: `<name>.html` (final) and `<name> (working copy).html`.
- In a deck, lay the fixed spine first — cover, agenda, section dividers,
  closing statement — then choose a layout per claim (`references/layout-deck.md`).
- A one-pager is a **report set in columns**, not a dashboard on paper: a fixed
  730x990 sheet (990x730 landscape) whose body is columns of headings,
  paragraphs, lists and figures. Prose carries the argument and the charts are
  evidence. Never build a KPI tile row there. Nothing about the page's shape is
  fixed except the sheet — pick the column tracks (`--cols`) and each figure's
  height (`--fig-h`) from the content, and the template ships no arrangement on
  purpose. Charts go **in** the columns: at the format's reduced type scale a
  357px column holds a line, column or bar chart, and the manifest's minWidth is
  the size a chart wants on a screen, not one it refuses below. Pack the page —
  1660px of column run is about five figures and eight text blocks, and
  under-filling it is the commonest failure. No controls and nothing hover-only,
  because paper has no pointer. Budget and measured figure heights in
  `references/layout-onepager.md`; `scripts/check-page.js` reports how full each
  column is.
- An email snapshot is a 600px **table** block with every style inline, its
  titles as text, and its charts frozen into PNGs when the page opens, because
  Gmail and Outlook delete SVG, strip style sheets and run no script. Draw each
  chart through `EmailSnapshot.draw(Charts.x, 'id', config)` so it freezes,
  give it `data-alt` text that states the finding with its numbers, and keep
  it to one to three findings. No controls and nothing hover-only. Rules and
  budget are in `references/layout-email.md`, and `scripts/check-page.js`
  lints the block.
- A Teams post is the email snapshot's freeze with the opposite markup:
  Teams keeps headings, paragraphs, lists and pictures and drops every style,
  so its block is plain semantic HTML with no class, style or colour, and its
  charts are drawn through `TeamsSnapshot.draw` so they freeze to PNG. Never
  reuse the email block for Teams, or the reverse. Rules are in
  `references/layout-teams.md`.
- A social post is the same freeze painted whole: each finding is one card,
  laid out at phone size and exported at 2.5x (1080x1350, 1080x1080 or
  1200x675), with its headline, units, source and date **in the picture**,
  because a feed picture travels without its words. Draw charts through
  `SocialSnapshot.draw`. Write one post per platform the user named; every
  figure in a post must also be on a card, and `scripts/check-page.js` fails
  one that isn't. Never post, schedule or invent a handle or link. Rules are
  in `references/layout-social.md`.
- Derive the grid from the shape of the analysis; the dashboard template ships
  without a starter arrangement on purpose. A wide hero cell goes to a finding
  that genuinely leads, not to whatever panel was written first.
- A line chart needs an ordered x. Named categories — and a shuffled or partial
  run like `['Jan', 'Mar', 'Feb']` — render an error panel. Write dates
  (`'Jan 2025'`), a complete rising run (`'Jan'…'Jun'`, `'Q1'…'Q4'`), or use a
  column chart (`references/charts/line.md`).
- `assets/charts-lib/` is a **vendored copy** of a library that lives in another
  repo (`svg-charts`). Never fix a library bug here — a future sync would wipe
  it, and the two copies would disagree in the meantime. Write the fix up in
  [`CHARTS-LIB-UPSTREAM.md`](CHARTS-LIB-UPSTREAM.md) instead, as a diff against
  the upstream engine file, and leave the copy alone; see *Recording a new
  change* there. Patch the copy only when the skill cannot work without it, and
  then say so in the same note. `node --test
  plugins/chart-dashboard/skills/chart-dashboard/tests/upstream-notes.test.js` checks the copy against
  what the note claims. Docs under `references/` are the skill's own — when the
  library behaves surprisingly, saying so there is the fix to make here.
- `plugins/social-post/` makes social posts on their own, so it carries its
  **own copy** of `charts-lib`, the freeze runtime (`assets/email-snapshot.js`),
  the editable-page runtime, `scripts/` and the two social templates. Those
  files must stay identical to chart-dashboard's: a change to one goes into
  both in the same commit, and `node --test
  plugins/social-post/skills/social-post/tests/shared-files.test.js` fails
  on any drift. A library sync copies into both (`CHARTS-LIB-UPSTREAM.md`
  § Syncing the copy). Its `references/` are its own.
- If the page has a control, wire it completely: filter the data, redraw every
  dependent panel and KPI, and recompute any title that states a finding. A
  static page is fine; a half-wired dropdown is not.

## Using this skill in a different project

Copy the skill folder into the target project and point your agent at it:

```bash
cp -r plugins/chart-dashboard/skills/chart-dashboard /path/to/your-project/.agent-skills/chart-dashboard
```

Then add this block to whichever file that project's agent reads at startup:

```markdown
## Dashboards, reports and decks
When asked to build a dashboard, analytics page, data report or slide deck,
follow `.agent-skills/chart-dashboard/SKILL.md`.
```

| Tool | File |
|:--|:--|
| OpenAI Codex, Cursor, Zed, Aider, Jules, opencode | `AGENTS.md` |
| Gemini CLI, Gemini Code Assist | `GEMINI.md` |
| GitHub Copilot | `.github/copilot-instructions.md` |
| Windsurf | `.windsurf/rules/chart-dashboard.md` |
| Cline / Roo Code | `.clinerules/chart-dashboard.md` |
| Claude Code / Desktop / claude.ai | install as a skill, or `CLAUDE.md` |

Agents that discover skills from a manifest can read `.agents/skills.json`
instead, which points at `skills/` and needs no instruction file.

## Repo layout

This repo is a **marketplace of independent plugins**, one directory each. Every plugin
owns its own `.claude-plugin/plugin.json`, its own version, and its own `skills/`, so a
plugin can be installed on its own without dragging the others along.

```
plugins/chart-dashboard/
  .claude-plugin/plugin.json
  skills/chart-dashboard/   the skill: SKILL.md, references/, templates/, assets/, scripts/
plugins/decisions-only/
  .claude-plugin/plugin.json
  skills/decisions-only/    SKILL.md, references/, evals/
plugins/whats-changed/      same shape as decisions-only
plugins/sanity-check/       same shape as decisions-only
plugins/exec-brief/         same shape as decisions-only
plugins/social-post/
  .claude-plugin/plugin.json
  skills/social-post/       SKILL.md, references/, templates/, assets/, scripts/, tests/, evals/
                            (assets/, scripts/ and the templates are copies of chart-dashboard's)
examples/                   six finished outputs (two dashboards, deck, report, one-pager, email snapshot)
docs/                       GitHub Pages landing page
.claude-plugin/             the marketplace manifest listing every plugin
```

`examples/` and `docs/` sit **outside** every plugin on purpose: they are browsable on
GitHub but are not shipped to anyone who installs a plugin.

## Contributing

New chart types need an entry in `references/chart-selection.md` — when to use
it and when not to — alongside the engine code. The selection guidance is what
makes the output good, not the renderer.
