/ds-plan
Classify a feature's UI against the design system before it is built — coverage map, build sequence, and DS work items.
Claude Code
$ npx -y skills add igloude/ds-skills --skill ds-plan --agent claude-code
Codex
$ npx skills add igloude/ds-skills --skill ds-plan -a codex -y
Cursor
$ npx skills add igloude/ds-skills --skill ds-plan -a cursor -y
Gemini CLI
$ npx skills add igloude/ds-skills --skill ds-plan -a gemini-cli -y
GitHub Copilot
$ npx skills add igloude/ds-skills --skill ds-plan -a github-copilot -y
OpenCode
$ npx skills add igloude/ds-skills --skill ds-plan -a opencode -y
Windsurf
$ npx skills add igloude/ds-skills --skill ds-plan -a windsurf -y
SKILL.md
ds-plan.SKILL.mdname: ds-plan
description: Classify a feature's UI against the design system before it is built — coverage map, build sequence, and DS work items.
disable-model-invocation: true
license: MIT
metadata:
author: Ian Gloude
version: "0.5.0"
ds-plan
Decide what gets built, from what, before anything is built. Every violation a gate catches was really a decision made seconds earlier, when someone — increasingly a generating agent — picked a component and guessed at its props. This skill moves that decision upstream, makes it with the actual API in hand, and writes it down. The byproduct is free: the extensions and gaps a feature exposes are exactly the design system's next backlog, discovered by demand instead of by committee.
The output is falsifiable, which is the point: run `/ds-drift` on the branch that implements this map, and every element you marked **Covered** should pass. If it doesn't, either the map was wrong or the generator ignored it — both worth knowing.
This skill is **report-only** and every output must survive a **cold read** — both terms, the family rules they summarize, and the `plans/` directory conventions are defined in [../ds-drift/references/conventions.md](../ds-drift/references/conventions.md). Read it now; it is short and load-bearing.
Skill rules
1. **Family rule 5 is this skill's center of gravity**: every Covered and Composable classification cites the manifest inventory row or the component's actual types at `file:line`, and names every prop it claims. Unverified means not Covered — classify it down the ladder and say why. 2. **A Don't-build verdict quotes its policy source** — the manifest's policy zone, a documented guideline, or a deprecation record. No citation, no verdict: classify the element on the ladder and record the concern as advisory. Pushing back on a designer is authority you spend, not authority you assume. 3. **Coverage maps carry a `-map-` slug** (`plans/NNN-map-<slug>.md`) so maps, reviews, and plans read apart in the shared directory.
Done means
A run is done when: the map file exists and survives a cold read; every inventoried element appears exactly once, in exactly one bucket, marked `drawn` or `implied`; every Covered and Composable row cites `file:line` in real types; every Extension and Net-new item names what it blocks and an interim strategy; and "Not classified" and the confidence line are filled in — even when the answers are "none" and "HIGH". Phase 6 checks exactly this before you finish.
Workflow
Phase 1 — Recon
**Manifest first.** Same discovery as ds-drift: `--manifest <path>` → `ds/MANIFEST.md` + `ds/tokens.json` in the repo root → `node_modules/<ds-package>/ds/` (glob `node_modules/{*,@*/*}/ds/MANIFEST.md`). Manifests are per-package; multiple hits mean a monorepo consuming several DS packages — load each and classify every element against the inventory of the package that owns the candidate component, noting the package in the map. Read the component inventory, variants, synonym map, policy zone, deprecations, and waiver ledger — this is the entire basis for classification.
- **Stamp check**: compare the manifest's schema number, package version, and API hash against the installed package (the manifest spec defines all three; ds-drift's recon describes the same check). On any mismatch, say so in the map header — planning against a stale inventory produces extensions for variants that already shipped.
- **No manifest**: derive a working inventory from the DS package's public entry point and types, mark the map's confidence degraded, and recommend `/ds-doctor`. Every classification here is a guess proportional to the rulebook's quality.
Then read the input artifact in full — a file path, a pasted spec, `gh issue view <n>`, or an image (the Read tool renders designs; state plainly what you *saw* versus what you *inferred*). Finally the app repo: which DS version is installed, an exemplar feature directory showing how UI is composed here, and the local composites that already exist — a local component that already solves an element is a real answer, and missing it means the team builds it twice.
Phase 2 — Element inventory
**Read [references/coverage-map-template.md](references/coverage-map-template.md) before inventorying, not before writing** — knowing the shape the map must land in changes what you collect. The skeleton you are filling:
> Self-enforcing header for generating agents → header facts (Input · Manifest status · Planned-at · Confidence) → **Summary** (bucket counts + the one-line "Blocking DS work" answer) → **Build sequence** (Wave 0 DS-repo blocking · Wave 1 app-repo now · Wave 2 app-repo blocked, each with an interim strategy · Not built) → **Elements**, one section per surface, every element in exactly one bucket → Work items → Token and manifest requests → Not classified → Assumptions and open questions → Verification.
Decompose the feature into UI elements, using the inventory checklist in [references/classification-playbook.md](references/classification-playbook.md) — read it now. This phase decides whether the map is worth anything: a design shows the happy path, at one breakpoint, in one theme, with three rows of realistic data. The extensions hide in everything it doesn't show — empty, loading, error, permission-denied, long content, dark theme, small viewport, keyboard-only. Enumerate those before classifying anything, and mark each element `drawn` or `implied` so the designer can see what you added on their behalf.
Phase 3 — Classify
Apply the **policy screen first**, then the ladder — the order is load-bearing and explained in the playbook: an element the system deliberately rejects would otherwise classify as a perfectly reasonable Extension, and generate DS work for something the DS already said no to.
1. **Don't build** — the system rejects this pattern; name the sanctioned equivalent. 2. **Covered** — one component + variant + the exact props t
Read more
name: ds-plan description: Classify a feature's UI against the design system before it is built — coverage map, build sequence, and DS work items. disable-model-invocation: true license: MIT metadata: author: Ian Gloude version: "0.5.0"
ds-plan
Decide what gets built, from what, before anything is built. Every violation a gate catches was really a decision made seconds earlier, when someone — increasingly a generating agent — picked a component and guessed at its props. This skill moves that decision upstream, makes it with the actual API in hand, and writes it down. The byproduct is free: the extensions and gaps a feature exposes are exactly the design system's next backlog, discovered by demand instead of by committee.
The output is falsifiable, which is the point: run `/ds-drift` on the branch that implements this map, and every element you marked **Covered** should pass. If it doesn't, either the map was wrong or the generator ignored it — both worth knowing.
This skill is **report-only** and every output must survive a **cold read** — both terms, the family rules they summarize, and the `plans/` directory conventions are defined in [../ds-drift/references/conventions.md](../ds-drift/references/conventions.md). Read it now; it is short and load-bearing.
Skill rules
1. **Family rule 5 is this skill's center of gravity**: every Covered and Composable classification cites the manifest inventory row or the component's actual types at `file:line`, and names every prop it claims. Unverified means not Covered — classify it down the ladder and say why. 2. **A Don't-build verdict quotes its policy source** — the manifest's policy zone, a documented guideline, or a deprecation record. No citation, no verdict: classify the element on the ladder and record the concern as advisory. Pushing back on a designer is authority you spend, not authority you assume. 3. **Coverage maps carry a `-map-` slug** (`plans/NNN-map-<slug>.md`) so maps, reviews, and plans read apart in the shared directory.
Done means
A run is done when: the map file exists and survives a cold read; every inventoried element appears exactly once, in exactly one bucket, marked `drawn` or `implied`; every Covered and Composable row cites `file:line` in real types; every Extension and Net-new item names what it blocks and an interim strategy; and "Not classified" and the confidence line are filled in — even when the answers are "none" and "HIGH". Phase 6 checks exactly this before you finish.
Workflow
Phase 1 — Recon
**Manifest first.** Same discovery as ds-drift: `--manifest <path>` → `ds/MANIFEST.md` + `ds/tokens.json` in the repo root → `node_modules/<ds-package>/ds/` (glob `node_modules/{*,@*/*}/ds/MANIFEST.md`). Manifests are per-package; multiple hits mean a monorepo consuming several DS packages — load each and classify every element against the inventory of the package that owns the candidate component, noting the package in the map. Read the component inventory, variants, synonym map, policy zone, deprecations, and waiver ledger — this is the entire basis for classification.
- **Stamp check**: compare the manifest's schema number, package version, and API hash against the installed package (the manifest spec defines all three; ds-drift's recon describes the same check). On any mismatch, say so in the map header — planning against a stale inventory produces extensions for variants that already shipped.
- **No manifest**: derive a working inventory from the DS package's public entry point and types, mark the map's confidence degraded, and recommend `/ds-doctor`. Every classification here is a guess proportional to the rulebook's quality.
Then read the input artifact in full — a file path, a pasted spec, `gh issue view <n>`, or an image (the Read tool renders designs; state plainly what you *saw* versus what you *inferred*). Finally the app repo: which DS version is installed, an exemplar feature directory showing how UI is composed here, and the local composites that already exist — a local component that already solves an element is a real answer, and missing it means the team builds it twice.
Phase 2 — Element inventory
**Read [references/coverage-map-template.md](references/coverage-map-template.md) before inventorying, not before writing** — knowing the shape the map must land in changes what you collect. The skeleton you are filling:
> Self-enforcing header for generating agents → header facts (Input · Manifest status · Planned-at · Confidence) → **Summary** (bucket counts + the one-line "Blocking DS work" answer) → **Build sequence** (Wave 0 DS-repo blocking · Wave 1 app-repo now · Wave 2 app-repo blocked, each with an interim strategy · Not built) → **Elements**, one section per surface, every element in exactly one bucket → Work items → Token and manifest requests → Not classified → Assumptions and open questions → Verification.
Decompose the feature into UI elements, using the inventory checklist in [references/classification-playbook.md](references/classification-playbook.md) — read it now. This phase decides whether the map is worth anything: a design shows the happy path, at one breakpoint, in one theme, with three rows of realistic data. The extensions hide in everything it doesn't show — empty, loading, error, permission-denied, long content, dark theme, small viewport, keyboard-only. Enumerate those before classifying anything, and mark each element `drawn` or `implied` so the designer can see what you added on their behalf.
Phase 3 — Classify
Apply the **policy screen first**, then the ladder — the order is load-bearing and explained in the playbook: an element the system deliberately rejects would otherwise classify as a perfectly reasonable Extension, and generate DS work for something the DS already said no to.
1. **Don't build** — the system rejects this pattern; name the sanctioned equivalent. 2. **Covered** — one component + variant + the exact props t
Police large volumes of AI-generated frontend work for design-system adherence, plan features against the system before they're built, and audit the design system itself so it can be policed. The idea: generation is cheap, the bottleneck is judgment.
More skills from other plugins.
brainstorming
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…
ask-matt
Ask which skill or flow fits your situation. A router over the skills in this repo.
Questions about ds-plan.
- Which coding agents can use ds-plan?
- ds-plan installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.

