agentleFS
MicrosoftKnown publishermicrosoft/awesome-rayfin/templates/universal-app/.agents/skills/headless-preview/SKILL.md

headless-preview

Skill108 starsChanged 5 months agoMITView on GitHub

Use to check how a Graphein chart spec looks against REAL data. `npm run preview` renders one spec headlessly to a PNG plus a machine-readable report — pull a live DAX result with fabric-app-data, render it themed exactly like the shipped app, then view the PNG and read the report (clipping / overlap / contrast / mark counts) and iterate. This is the agent validation loop for every visual. Covers the query→render→critique loop, the CLI flags, reading the report, and the validate→repair workflow.

We split this skill into the rules it gives an agent

2 rules. About 0 are common, 0 are distinctive, and 2 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈0

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 2

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Use headless preview when checking any visual against live data, choosing a type or encoding, catching clipping/overlap/contrast/wrong …

    line 27
  2. Very specific:

    Before rendering, the script runs validateSpec(spec).

    line 123

≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Headless preview — render a spec against live data

You can render a single Graphein ChartSpec to a PNG and a JSON report on this machine, with no browser, using @graphein/node. Pair it with a live fabric-app-data query result and you can check a visual's real presentation — does the data shape suit this chart, do labels clip, do colors read, is the trend what you expected — in seconds, before it ships.

This is the loop. Headless preview is the agent's validation for every visual: presentation, data fit, clipping, overlap, and contrast. Deploy with rayfin up to ship the app once you've preview-validated.

When to use it

Use headless preview when checking any visual against live data, choosing a type or encoding, catching clipping/overlap/contrast/wrong grain, and tuning formatting, labels, series, sort, or transforms. KPI/table/matrix/slicers/ dashboard rasterize to PNG too, so preview-validate them before shipping.

Graphein renders headlessly by design (the same engine draws in the browser and in Node via @graphein/node), so this works with no data connection: the bundled demo dashboard (src/demo/) is all Graphein specs over inlined rows — render any of them straight from spec.data (offline) to eyeball the starter, and use the same loop with --query/--data once you've swapped in the real model.

The loop

1. fabric-app-data query <alias> --file q.dax     → live rows (JSON)
2. author a ChartSpec (type + encoding)           → spec.json
3. npm run preview -- --spec spec.json --data rows → PNG + report JSON
4. VIEW the PNG (you have vision) + READ the report
5. not right? adjust the spec / DAX → back to 3
6. happy? drop the spec into a <ChartCard>, then deploy with `rayfin up`

Run it

# Spec with data already inlined (fully offline, the simplest check):
npm run preview -- --spec hero.json

# Author a spec WITHOUT data, fetch live rows in one shot:
npm run preview -- --spec hero.json --query sales --dax-file src/queries/hero.dax

# Or feed a pre-fetched query result you already have:
npx fabric-app-data query sales --file src/queries/hero.dax > rows.json
npm run preview -- --spec hero.json --data rows.json --theme dark

npm run preview -- forwards flags to node scripts/preview-visual.mjs. The spec is the same JSON you pass to <ChartCard spec={…} /> (a type + encoding, optionally with data). --spec - and --data - read stdin.

Flags

FlagPurpose
--spec <path|->Required. The ChartSpec JSON (file or stdin).
--query <alias>Run DAX against this fabric.yaml alias and inject the rows as spec.data.
--dax <DAX> / --dax-file <path>The DAX for --query (inline or a .dax file).
--data <path|->A pre-fetched fabric-app-data query JSON result to map into spec.data.
--columns <json>Optional toChartData-style alias map, e.g. '{"month":"Date[Month]","revenue":"Total Revenue"}'.
--out <path>PNG path (default: a temp file, echoed as out).
--width / --height / --dprPixel size (default 800 × 500, dpr 2).
--theme light|darkMatch src/global.css tokens (default light). --no-theme to skip.
--limit <n>Row cap for --query (default 1000).

Data precedence: --query (live) or --data (pre-fetched) overrides any inlined spec.data; with neither, the spec's own data is used. Rows are mapped exactly like toChartData — column short names (Sales[Month] → Month), numeric DAX types coerced to numbers — so the keys you reference in encoding match. Pass --columns to alias them (and to disambiguate two columns that share a short name), just like toChartData({ columns }).

Read the report

The script prints one JSON object. Treat it as a critique checklist:

{
  "ok": true,                 // false ⇒ the report found a presentation problem
  "rendered": true,
  "type": "line",
  "out": "…/line.png",        // VIEW this image
  "theme": "light",
  "fontParity": true,         // Inter registered → matches the deployed look
  "dataRows": 12,             // how many rows actually rendered (0 ⇒ empty tile!)
  "marks": 12, "series": 1, "colors": 1,
  "summary": "Revenue rose 92% from 120 to 230 between Jan and May.",
  "diagnostics": [            // clipping / overlap / contrast / axis issues
    { "code": "label-overlap", "severity": "warning", "message": "…", "axis": "x" }
  ],
  "lint": [ … ],              // validateSpec warnings (soft issues)
  "repaired": [ … ]           // JSON-Patch ops auto-applied to fix the spec
}
  • View the PNG at out — that is the real deployed-look render (app theme + Inter font). Judge it like a reviewer: legibility, clipping, color, grain.
  • ok: false or any diagnostics → fix before shipping. Common codes: label/axis overlap, clipped marks, low contrast, too many colors, empty plot.
  • dataRows: 0 (or marks: 0) → your encoding fields don't match the mapped row keys, or the query returned nothing. Fix the field names / --columns / the DAX — never ship an empty tile.
  • summary is Graphein's own read of the data — a quick sanity check that the chart says what you think (e.g. confirms the trend direction).

Validate → repair (built in)

Before rendering, the script runs validateSpec(spec); if it's invalid it tries repairSpec(spec) and re-validates. You get:

  • A clean render plus any repaired patch ops (apply the same fixes to your source spec) when repair succeeds.
  • Exit 1 with errors (path-pointed) when the spec can't be auto-repaired — read the path/message, fix the spec, re-run.

You can also call these directly while authoring (all re-exported from the kit): validateSpec(spec) → { valid, errors, warnings }, repairSpec(spec) → { spec, applied, remaining }, summarize(spec) → string.

Exit codes

CodeMeaning
0Rendered — PNG written, report printed.
1Error — invalid/unrepairable spec, bad data, or render failure (see error).
2Render failure for a visual type that should be fixed before shipping.

What renders headlessly

Supported: line, area, bar, scatter, box, pie, heatmap, sankey, choropleth, combo, histogram, funnel, treemap, gauge, bullet, calendarHeatmap, waterfall, slope, dumbbell — plus kpi, table, matrix, slicers (dropdown, list, search, range, dateRange), and dashboard. Chart specs also support transform, annotations, insights, trendline, and facet.

Notes

  • The PNG defaults to a temp path so nothing lands in the repo; pass --out only if you want it somewhere specific (don't commit it).
  • Theme/font parity is automatic: the script parses src/global.css tokens (the same --color-* bridge as lib/graphein-theme.ts) and registers the bundled Inter, so a preview looks like the deployed chart. Edit global.css to recolor — never hardcode hex in a spec.
  • This is the validation loop for every visual; preview-validate before you deploy with rayfin up.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

Reviews can't be read right now.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.