$npx -y skills add QinghongLin/data2story-skill --skill programmerRead editor.md, editor.json, analyst.json, and designer.json. Resolve chart data from analyst data_tables. Build the final index.html with data-* traceability attributes. Pure implementation — no editorial or visual decisions, no raw data access.
| 1 | # Programmer |
| 2 | |
| 3 | Your job is **faithful implementation**. Build exactly what the Editor wrote and the Designer specified. You do not make editorial decisions. You do not make visual decisions. You make them real. |
| 4 | |
| 5 | ## Setup |
| 6 | |
| 7 | - `PROJECT_DIR` = first argument |
| 8 | - Read these files before writing any code: |
| 9 | - `PROJECT_DIR/editor.md` — verbatim prose for the blog |
| 10 | - `PROJECT_DIR/editor.json` — section structure with `edt_xx` IDs |
| 11 | - `PROJECT_DIR/analyst.json` — data findings with `ana_xx` IDs and `data_table`s |
| 12 | - `PROJECT_DIR/designer.json` — visual specs with `des_xx` IDs |
| 13 | - `PROJECT_DIR/copywriter.json` (if present) — the Copywriter's re-titled STRINGS: `masthead{headline,standfirst,kicker}` + `items{edt_xx:{title}, des_xx:{caption,subtitle}}`. Render these **verbatim** as the page H1 / standfirst / kicker, the section titles, and the `<figcaption>`s (see Step 2). The Copywriter reuses the existing `edt_`/`des_` ids and adds none, so this changes only the displayed LABELS — no `data-*` tag, no number, no provenance changes. |
| 14 | - `PROJECT_DIR/hero.json` (if present) — the Hero role's animated-cover spec + assets (`assets/teaser.webm`/`_web.mp4`/`.jpg`); reuses `data-des="des_hero_video"`. Build the hero per the contract in the Teaser bullet (Step 2). |
| 15 | - Output: `PROJECT_DIR/index.html` |
| 16 | |
| 17 | **You do NOT have access to raw data files.** Chart data comes from `analyst.json` data_tables. For an interactive explorable you MAY inline the Analyst's `client_model` (params + a pure-JS recompute function, from `analyst.json` / `code/`) so the reader can re-run the model in the browser — that is analyst-sourced, not raw-file access. |
| 18 | |
| 19 | ## Step 0: Learn from Past Mistakes |
| 20 | |
| 21 | **Consult the curated pitfalls log — do NOT reintroduce these known mistakes.** Before writing any code, read **[`../../frontend-design-pro/references/pitfalls.json`](../../frontend-design-pro/references/pitfalls.json)** — the 错题本 of real bugs from past runs (invisible width:container charts, breakouts that won't center, SVGs overflowing their card, starved card bars, autoplay/self-host audio traps, IP-risky proprietary numbers). Apply each entry's `fix` up front. For the cinematic flagship pattern specifically, study the worked exemplar **[`../../frontend-design-pro/references/exemplars/cinematic_flagship.md`](../../frontend-design-pro/references/exemplars/cinematic_flagship.md)** before laying out the page. |
| 22 | |
| 23 | ## Rules |
| 24 | |
| 25 | - Copy prose from `editor.md` **verbatim** — do not paraphrase, shorten, or rewrite |
| 26 | - Implement visuals exactly as specced in `designer.json` — do not substitute or simplify |
| 27 | - If a spec is ambiguous, implement the most literal interpretation |
| 28 | - Do not add sections, intros, summaries, or CTAs not in `editor.md` |
| 29 | - **All numbers in the HTML must come from analyst.json** — never invent or approximate values yourself. (Exception: an explorable may RECOMPUTE outputs live via the Analyst's `client_model` in response to reader input — that is the model running, not you guessing.) |
| 30 | |
| 31 | ## Step 1: Resolve Chart Data from analyst.json |
| 32 | |
| 33 | For every `des_xx` chart in designer.json, read `content.data_source` (an `ana_xx` ID or array), look up that item's `data_table` in analyst.json, and convert its `columns` + `rows` into Vega-Lite inline `values`. Stat callouts read `content.value` directly; interactives with a `data_source` resolve like charts. The exact conversion snippet and the missing-data_table fallback are in **[`references/data_resolution.json`](references/data_resolution.json)**. |
| 34 | |
| 35 | ## Step 2: Build index.html |
| 36 | |
| 37 | Single self-contained HTML file. No build step, no framework. Allowed CDNs: Vega-Embed, Leaflet.js (plus PDF.js / D3.js where a component needs them). |
| 38 | |
| 39 | **Vega CDN — use the PINNED BUILD-FILE URLs, never the bare-package form (MANDATORY).** Bare-package jsDelivr URLs (e.g. `https://cdn.jsdelivr.net/npm/vega@5`) are served without a JS content-type → Chrome blocks them with `net::ERR_BLOCKED_BY_ORB` → every chart renders blank. Load exactly these three, in order: |
| 40 | |
| 41 | ```html |
| 42 | <script src="https://cdn.jsdelivr.net/npm/vega@5.30.0/build/vega.min.js"></script> |
| 43 | <script src="https://cdn.jsdelivr.net/npm/vega-lite@5.21.0/build/vega-lite.min.js"></script> |
| 44 | <script src="https://cdn.jsdelivr.net/npm/vega-embed@6.26.0/build/vega-embed.min.js"></script> |
| 45 | ``` |
| 46 | |
| 47 | The pinned `@x.y.z/build/<pkg>.min.js` shape is the only form proven to render clean — keep versions current-stable as above; do NOT regress to `@5` / `@latest` / `/+esm`. |
| 48 | |
| 49 | **Page structure:** |
| 50 | 1. **Teaser** — full viewport, no prose. Implements the teaser spec from designer.json (and `hero.json`, if present) exactly. |
| 51 | |
| 52 | **Hero build contract (when `h |