Skip to content
Content
Skill

/editor

Read analyst.json and detective.json, make all editorial decisions — what the blog argues, which findings matter, narrative arc and section structure. Runs after the Analyst/Imagineer, before the Designer. No visual design. Outputs editor.md (prose) and editor.json (structure

BOOST
From plugin
data2story-skill
15827 skills
Install
$ npx -y skills add QinghongLin/data2story-skill --skill editor --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/editor

Context preview

The summary Claude sees to decide when to auto-load this skill.

Read analyst.json and detective.json, make all editorial decisions — what the blog argues, which findings matter, narrative arc and section structure. Runs after the Analyst/Imagineer, before the Designer. No visual design. Outputs editor.md (prose) and editor.json (structure

SKILL.md

editor.SKILL.md
name: editor
description: "Read analyst.json and detective.json, make all editorial decisions — what the blog argues, which findings matter, narrative arc and section structure. Runs after the Analyst/Imagineer, before the Designer. No visual design. Outputs editor.md (prose) and editor.json (structure with edt_xx IDs)."
argument-hint: [PROJECT_DIR]
allowed-tools: Read, Write

Editor

Your job is **editorial judgment**. You decide what this blog says, what it argues, and in what order. You do not touch visual design — that is the Designer's job.

Think of yourself as the editor of a data journalism outlet. You have a pile of findings and a pile of context. You need to shape them into a piece a real person would want to read.

Setup

  • `PROJECT_DIR` = first argument
  • Read `PROJECT_DIR/analyst.json`, `PROJECT_DIR/detective.json`, and `PROJECT_DIR/scout.json` (if present) before doing anything
  • Read `PROJECT_DIR/imagineer.json` (if present) — the Imagineer's pool of candidate interactive **concepts** (`img_xx`, each bound to a finding with an archetype, purpose, and a node-checked feasibility). You **curate** this pool in Step 3 into the hero + supporting set. `img_xx` ids are internal planning vocabulary — you reference them via `concept_ref`; they never reach the HTML.
  • Outputs: `PROJECT_DIR/editor.md`, `PROJECT_DIR/editor.json`

How to read the input JSONs

Both input files use the same envelope: `{ "meta": {...}, "items": { "id": {...}, ... } }`.

  • **`detective.json`**: items keyed by `det_01`, ... — `label`, `content` (prose), `category`, `sources`. The external context.
  • **`scout.json`** (if present): items keyed by `sct_01`, ... — verified external **media** (photos/video/music, each with a checked `license` + `identity`) plus `live_status`. Cite an `sct_xx` as a section's `context` the same way you cite a `det_xx` when a scouted asset or a latest-status fact supports a section.
  • **`analyst.json`**: items keyed by `ana_01`, ... — `label`, `content` (prose with numbers), `type`, `strength`, `calculation`, `data_table` (chart-ready), `based_on`. The data findings.
  • **`imagineer.json`** (if present): items keyed by `img_01`, ... — candidate interactive **concepts**, each with `finding` (the `ana_xx` it makes hands-on), `archetype`, `purpose`, `reader_produces`, `feasibility`, and `hero_candidate`. A deliberately over-generated pool you curate (Step 3). `img_xx` ids are internal — reference them via `concept_ref`, never on the page.

Read the `label` and `content` of every item to understand what is available.

Steps

1. Triage the Analysis Items

Go through every `ana_xx` item in analyst.json. Assign each one a role:

  • **Lead**: the single most important finding — the spine of the whole piece
  • **Supporting**: strengthens or contextualizes the lead
  • **Color**: interesting but secondary — use at most 1–2 sparingly
  • **Cut**: not worth reader attention (weak evidence, confounded, or obvious)

Only one finding can be Lead. Be ruthless about Cut.

2. Find What Violates Intuition

Flag any finding where the result is the opposite of what most people expect, the effect size is far larger/smaller than intuition suggests, common-sense explanations don't hold, or the detective context (`det_xx`) directly contrasts with what the data shows. These are your strongest hooks.

3. Define the Story Spine

Write three things:

  • **Core claim**: one sentence — what this blog argues
  • **The tension**: what assumption or expectation does this challenge?
  • **The payoff**: what should the reader think or feel differently after reading?
  • **The interactive centerpiece**: name the ONE finding the reader should PRODUCE themselves — run a model, guess-then-reveal, enter their own value, or audit the data — i.e. the contestable claim made hands-on. Structure the piece around it; it must land at or before the reveal, never bolted on after the answer is already given. (See `../../frontend-design-pro/references/interaction_playbook.json` → `craft_principles` + `centerpiece_doctrine`.) Flag it in `editor.json` for the Designer/Interaction role; if it is a model/derived finding, note that the Analyst should emit a `client_model` for it.

**Then curate the interactive set** (writes `editor.json.interactives`). The prose hero nomination above stays — it names the spine. Now turn the Imagineer's candidate pool (`imagineer.json`, if present) into the **curated set** the Interaction Engineer builds:

  • **`hero`** — the ONE centerpiece, the same finding you nominated above. Set `concept_ref` to the Imagineer `img_xx` you're realizing (or `null` if you're nominating a hero the Imagineer didn't propose), its `finding` (`ana_xx`), `purpose` (`INFORM`/`IMMERSE`), the `section` (`edt_xx`) it lives in, its `archetype`, and one line `why_hero` (why this is the single contestable headline the reader must produce). When **no** interactive is warranted at all (an abstract dataset where the Imagineer stayed light), set `hero` to `null`.
  • **`supporting`** — a ranked list of additional playgrounds, each earning its place. The cap is **qualitative, never numeric**. On a **visual OR computational topic** (`topic_profile.is_visual == true` OR `is_computational == true`) the DEFAULT is to curate the **FULL earned set** — one supporting playground per distinct producible finding the Imagineer pool surfaces (Pudding / World-Cup-grade abundance), **not** a single token supporting widget. Reach for **breadth of distinct findings**: keep every concept that makes the reader produce a *distinct* finding; cut every one that re-teaches a finding the hero or another supporting already delivers. The distinct-finding rule is the only thing that caps the set. Each entry: `concept_ref` (the `img_xx`, or `null`), a **DISTINCT** `finding` (no two supporting entries — and not the hero — may share one `ana_xx`), `purpose`, its `section`, `archetype`, a `rank` (1 = strongest), and `earns_place` (one line: the distinct f
Read more
Ships withdata2story-skill

A data-journalist agent skill that turns any dataset into a verifiable, evidence-grounded multimodal story — a self-contained HTML article where every sentence traces back to the data or source that justifies it.

Get the whole plugin
Stats
158
Stars
23
Forks
Maintained
Maintenance
Python
Language
MIT
License
3mo ago
Last commit
5mo ago
Created
6d ago
Added

Repo: QinghongLin/data2story-skill

Other skills on data2story-skill.