@hegemonart/get-design-done 1.45.0 → 1.46.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,14 +5,14 @@
5
5
  },
6
6
  "metadata": {
7
7
  "description": "Get Design Done — 5-stage agent-orchestrated design pipeline with 9 connections, handoff-first workflow, bidirectional Figma write-back, 22+ specialized agents, queryable knowledge layer (intel store, dependency analysis, learnings extraction), and a self-improvement loop (reflector, frontmatter + budget feedback, global-skills layer). v1.20.0 ships the SDK foundation: gdd-state MCP server (11 typed tools), lockfile-safe STATE.md mutations, event stream, and resilience primitives (jittered-backoff, rate-guard, error-classifier, iteration-budget) for rate-limit + 429 + context-overflow recovery. Full CI/CD pipeline (Node 22/24 × Linux/macOS/Windows) and release automation (auto-tag + GitHub Release + release-time smoke test).",
8
- "version": "1.45.0"
8
+ "version": "1.46.0"
9
9
  },
10
10
  "plugins": [
11
11
  {
12
12
  "name": "get-design-done",
13
13
  "source": "./",
14
14
  "description": "Agent-orchestrated 5-stage design pipeline: Brief → Explore → Plan → Design → Verify. 22+ specialized agents, 9 connections (Figma, Refero, Preview, Storybook, Chromatic, Figma Writer, Graphify, Pinterest, Claude Design), Claude Design handoff, bidirectional Figma write-back, and a queryable intel store (.design/intel/) for dependency and learnings queries. Standalone commands: style, darkmode, compare, figma-write, graphify, handoff, analyze-dependencies, skill-manifest, extract-learnings. Embeds NNG heuristics, WCAG thresholds, typographic systems, motion framework, and anti-pattern catalog. Ships with a full CI/CD pipeline (Node 22/24 × Linux/macOS/Windows) and release automation. Optimization layer (v1.0.4.1, retroactive): gdd-router + gdd-cache-manager skills, PreToolUse budget-enforcer hook, tier-aware agent frontmatter, lazy checker gates, streaming synthesizer, /gdd:warm-cache + /gdd:optimize commands, and cost telemetry at .design/telemetry/costs.jsonl — targeting 50-70% per-task token-cost reduction with no quality-floor regression. v1.20.0 SDK foundation: gdd-state MCP server (11 typed tools), lockfile-safe STATE.md mutations, event stream at .design/telemetry/events.jsonl, resilience primitives (jittered-backoff, rate-guard, error-classifier, iteration-budget) with rate-limit + 429 + context-overflow recovery, and TypeScript toolchain.",
15
- "version": "1.45.0",
15
+ "version": "1.46.0",
16
16
  "author": {
17
17
  "name": "hegemonart"
18
18
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "get-design-done",
3
3
  "short_name": "gdd",
4
- "version": "1.45.0",
4
+ "version": "1.46.0",
5
5
  "description": "Agent-orchestrated 5-stage design pipeline: Brief → Explore → Plan → Design → Verify. 22+ specialized agents, 9 connections (Figma, Refero, Preview, Storybook, Chromatic, Figma Writer, Graphify, Pinterest, Claude Design), handoff-first workflow via Claude Design bundles, bidirectional Figma write-back (annotations, Code Connect), queryable intel store (`.design/intel/`) for O(1) design surface lookups, and self-improvement loop (reflector agent, frontmatter + budget feedback, global-skills layer at `~/.claude/gdd/global-skills/`). Standalone commands: style, darkmode, compare, figma-write, graphify, handoff, analyze-dependencies, skill-manifest, extract-learnings, reflect, apply-reflections. Embeds NNG heuristics, WCAG thresholds, typographic systems, motion framework, and anti-pattern catalog. Ships with a full CI/CD pipeline (Node 22/24 × Linux/macOS/Windows, lint + schema + frontmatter + stale-ref + shellcheck + gitleaks + injection-scan + blocking size-budget) and release automation (auto-tag + GitHub Release + release-time smoke test). Optimization layer (v1.0.4.1, retroactive): gdd-router + gdd-cache-manager skills, PreToolUse budget-enforcer hook, tier-aware agent frontmatter, lazy checker gates, streaming synthesizer, /gdd:warm-cache + /gdd:optimize commands, and cost telemetry at .design/telemetry/costs.jsonl — targeting 50-70% per-task token-cost reduction with no quality-floor regression. v1.20.0 SDK foundation: gdd-state MCP server (11 typed tools), lockfile-safe STATE.md mutations, event stream at .design/telemetry/events.jsonl, resilience primitives (jittered-backoff, rate-guard, error-classifier, iteration-budget) with rate-limit + 429 + context-overflow recovery, and TypeScript toolchain. v1.27.7 ships gdd-mcp (Phase 27.7): 12 read-only MCP tools for sub-3s priming. v1.28.0 (Phase 28): Foundational References Tier 2 — 5 new reference files (color-theory, composition, proportion-systems, i18n, contrast-advanced), 2 verifier i18n probes + 1 explore i18n-readiness probe, 12 additive cross-link insertions across 10 existing references, 2 orthogonal audit-scoring lens-tags (composition_alignment + i18n_readiness).",
6
6
  "author": {
7
7
  "name": "hegemonart",
package/CHANGELOG.md CHANGED
@@ -4,6 +4,56 @@ All notable changes to get-design-done are documented here. Versions follow [sem
4
4
 
5
5
  ---
6
6
 
7
+ ## [1.46.0] - 2026-06-03
8
+
9
+ ### Phase 46 - Skill UX Polish
10
+
11
+ 70+ skills under one `/gdd:` namespace had three friction points at one surface (skill frontmatter): no
12
+ shortcut for power users, 83 frontmatter blocks as 83 places to edit a description, and a description budget
13
+ that was enforced but not gated explicitly. Phase 46 ships a metadata single source of truth, an
14
+ order-preserving frontmatter generator, three pin shortcut skills, and an explicit budget gate. Planned and
15
+ executed via the GSD pipeline (parallel research + three parallel executor subagents). No new runtime dependency,
16
+ no new egress.
17
+
18
+ ### Breaking changes
19
+
20
+ - **A new CI drift gate guards skill frontmatter.** `npm run generate:skill-frontmatter:check` fails if any
21
+ `source/skills/<id>/SKILL.md` frontmatter no longer matches `scripts/lib/manifest/skills.json`. Edit the
22
+ description, argument hint, or tools allow-list in `skills.json`, then run `npm run generate:skill-frontmatter`
23
+ and `npm run build:skills` to regenerate. Hand-editing the managed frontmatter keys directly now fails CI.
24
+ - **The skill description budget is now an explicit blocking gate.** `npm run lint:agentskills` runs in CI and
25
+ fails (R4) on any description over 1024 characters. The cap existed since Phase 28.5; it is now a first-class
26
+ gate rather than an in-process check.
27
+
28
+ ### Added
29
+
30
+ - **`scripts/lib/manifest/skills.json` as the skill-metadata single source of truth.** All 86 skills carry
31
+ `{description, argument_hint?, tools?, user_invocable?, disable_model_invocation?, ...}`; the JSON Schema
32
+ (`scripts/lib/manifest/schemas/skills.schema.json`) documents the enriched fields and is validated by
33
+ `npm run validate:manifest`.
34
+ - **`scripts/generate-skill-frontmatter.cjs`** (maintainer-only): forward mode regenerates each skill's
35
+ frontmatter from `skills.json`; `--extract` reseeds the manifest from current frontmatter; `--check` is the CI
36
+ drift gate. It is **order-preserving** (each skill keeps its own frontmatter key order; only `name` leads and
37
+ non-managed lines like `quality-gate`'s `writes:` block are carried verbatim), so the committed tree is a
38
+ byte-for-byte fixed point and existing frontmatter-snapshot baselines never churn.
39
+ - **`/gdd:pin <skill>`, `/gdd:unpin <skill>`, `/gdd:list-pins`** power-user shortcut skills. `pin` writes
40
+ standalone alias stubs across every installed harness skills dir (so `/audit` resolves alongside
41
+ `/gdd:audit`), each carrying a `<!-- gdd-pinned-skill source=<id> -->` marker; descriptions and tools come
42
+ from the `skills.json` catalogue, never a live frontmatter scrape. `unpin` removes only marked stubs.
43
+ `list-pins` shows pinned aliases per harness with source and timestamp. Backed by `scripts/lib/pin/`
44
+ (harness discovery via `scripts/lib/manifest/harnesses.cjs`, atomic `.tmp`+rename writes, cross-platform).
45
+ - **`reference/skill-metadata.md`** documents the SoT, the generator, the build chain, and the budget.
46
+
47
+ ### Notes
48
+
49
+ - 6-manifest lockstep at **v1.46.0**, `OFF_CADENCE_VERSIONS.add('1.46.0')`, 37 `manifests-version.txt`
50
+ baselines, tarball golden 874 -> 884 (the 3 pin skills land in `skills/` and `dist/claude-code/`, plus 3
51
+ `scripts/lib/pin/*.cjs` and `reference/skill-metadata.md`). The maintainer-only generator is correctly not shipped.
52
+ - Description budget (SC#5): already enforced since Phase 28.5 (`validate-skill-length.cjs` + `lint-agentskills-spec.cjs`,
53
+ both cap at 1024); Phase 46 hardens it into an explicit CI gate and a SoT-layer regression test. No skill needed trimming.
54
+
55
+ ---
56
+
7
57
  ## [1.45.0] - 2026-06-02
8
58
 
9
59
  ### Phase 45 - Canonical Domain Reference Index
package/README.md CHANGED
@@ -251,6 +251,8 @@ All 14 runtimes receive their native artifact layout (`skills/`, `command/`, `ag
251
251
 
252
252
  **Domain reference index (v1.45.0).** The 38+ reference docs are now navigated through 7 canonical entry-points - `reference/{typography,color,spatial,motion,interaction,responsive,ux-writing}.md` - each indexing its subordinate fragments with a "use this when" pointer plus a handful of rules-of-thumb. Design skills load the relevant domain index first and drill into a fragment only when needed (motion-mapper dropped roughly 89% of its up-front reference tokens this way). The indexes link, never copy: `check:domain-links` fails CI on a broken cross-link and `check:no-duplication` fails on large copy-paste. The detailed fragments stay in place as the drill-in targets. **No new runtime dependency.**
253
253
 
254
+ **Skill UX polish (v1.46.0).** Skill frontmatter now has a single source of truth at `scripts/lib/manifest/skills.json` (description, argument hint, tools allow-list per skill); `scripts/generate-skill-frontmatter.cjs` regenerates each `source/skills/<id>/SKILL.md` from it, and `generate:skill-frontmatter:check` drift-gates the two in CI. The generator is order-preserving, so the committed tree stays a byte-for-byte fixed point and existing snapshots never churn. Power users get `/gdd:pin <skill>`, which writes standalone shortcut aliases (for example `/audit` alongside `/gdd:audit`) across every installed harness dir, each carrying a `gdd-pinned-skill` marker, plus `/gdd:unpin` and `/gdd:list-pins`. The 1024-character description budget (in place since the skill-authoring contract) is now an explicit `lint:agentskills` CI gate. **No new runtime dependency.**
255
+
254
256
  Verify with:
255
257
 
256
258
  ```
package/SKILL.md CHANGED
@@ -2,7 +2,7 @@
2
2
  name: get-design-done
3
3
  short_name: gdd
4
4
  description: "Master design pipeline for Claude Code. 5-stage workflow: Brief → Explore → Plan → Design → Verify. Run 'brief' first in any new project to capture the design problem, then 'explore' to inventory the codebase and interview for context. Invoke without arguments for status and auto-routing."
5
- argument-hint: "[brief|explore|plan|design|verify|handoff|map|next|help|status|style|darkmode|compare|figma-write|graphify|discuss|list-assumptions|progress|health|todo|stats|note|plant-seed|add-backlog|review-backlog|scan|discover|settings|update|reapply-patches|audit|pause|resume|new-cycle|debug|quick|new-project|complete-cycle|fast|do|ship|undo|pr-branch|sketch|sketch-wrap-up|spike|spike-wrap-up|reflect|apply-reflections|analyze-dependencies|extract-learnings|skill-manifest|warm-cache|optimize|cache-manager|watch-authorities|check-update|benchmark|recall|timeline|continue|zoom-out]"
5
+ argument-hint: "[brief|explore|plan|design|verify|handoff|map|next|help|status|style|darkmode|compare|figma-write|graphify|discuss|list-assumptions|progress|health|todo|stats|note|plant-seed|add-backlog|review-backlog|scan|discover|settings|update|reapply-patches|audit|pause|resume|new-cycle|debug|quick|new-project|complete-cycle|fast|do|ship|undo|pr-branch|sketch|sketch-wrap-up|spike|spike-wrap-up|reflect|apply-reflections|analyze-dependencies|extract-learnings|skill-manifest|pin|unpin|list-pins|warm-cache|optimize|cache-manager|watch-authorities|check-update|benchmark|recall|timeline|continue|zoom-out]"
6
6
  user-invocable: true
7
7
  ---
8
8
 
@@ -89,6 +89,9 @@ Each stage produces artifacts in `.design/` inside the current project.
89
89
  | `analyze-dependencies [--slice <name>]` | `get-design-done:analyze-dependencies` | Query the `.design/intel/` store - dependency slices, graph queries, phase-scoped reads |
90
90
  | `extract-learnings [--cycle <slug>]` | `get-design-done:extract-learnings` | Extract decisions, lessons, patterns, and surprises from a completed cycle → `.design/cycles/<slug>/LEARNINGS.md` |
91
91
  | `skill-manifest [--refresh]` | `get-design-done:skill-manifest` | List or refresh the local skill manifest used by the router for discovery |
92
+ | `pin <skill>` | `get-design-done:gdd-pin` | Phase 46 - write standalone shortcut aliases for a gdd skill across every installed harness dir (so `/audit` resolves alongside `/gdd:audit`); metadata comes from the skills.json catalogue |
93
+ | `unpin <skill>` | `get-design-done:gdd-unpin` | Phase 46 - remove pinned aliases for a skill (only files carrying the gdd-pinned-skill marker) |
94
+ | `list-pins` | `get-design-done:gdd-list-pins` | Phase 46 - show pinned aliases per harness with their source skill and last-pinned timestamp |
92
95
  | `quality-gate` | `get-design-done:quality-gate` | Phase 25 - parallel lint/type/test/visual command runner; classifies failures via quality-gate-runner agent |
93
96
  | `turn-closeout` | `get-design-done:turn-closeout` | Phase 25 - Stop-hook mirror skill; finalizes per-turn STATE blocks and emits closeout events |
94
97
  | `bandit-status` | `get-design-done:bandit-status` | Phase 27.5 - read-only diagnostic surface for the bandit posterior; per-(agent, bin, delegate, tier) snapshots (alpha, beta, mean, stddev, count, last-used). Use `/gdd:bandit-reset` to mutate. |
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: gdd-figma-extract
3
- description: Off-context Figma design-system extraction into a compact local digest (DESIGN.md + tokens.json + components.json). Pulls the file via the Figma REST API and digests it without the raw JSON ever entering the model context.
3
+ description: "Off-context Figma design-system extraction into a compact local digest (DESIGN.md + tokens.json + components.json). Pulls the file via the Figma REST API and digests it without the raw JSON ever entering the model context."
4
4
  ---
5
5
 
6
6
  # gdd-figma-extract
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: gdd-graphify
3
- description: Manage the Graphify knowledge graph for the current project. Build, query, status, diff. When available, design-planner and design-integration-checker use the graph for pre-search consultation.
3
+ description: "Manage the Graphify knowledge graph for the current project. Build, query, status, diff. When available, design-planner and design-integration-checker use the graph for pre-search consultation."
4
4
  ---
5
5
 
6
6
  # gdd-graphify
@@ -0,0 +1,27 @@
1
+ ---
2
+ name: gdd-list-pins
3
+ description: "Lists pinned skill aliases per harness with their source skill and pin timestamp. Use when you want to see which gdd skills have been pinned as standalone shortcuts and where."
4
+ tools: Read, Bash
5
+ ---
6
+
7
+ # /gdd:list-pins
8
+
9
+ **Role:** Show every pinned skill alias across the installed harness `skills/` directories. For each one, report the harness it lives in, the on-disk alias directory name, the source skill it points at (from the `<!-- gdd-pinned-skill source=<skill> -->` marker), and when it was pinned (the file modification time).
10
+
11
+ ## Steps
12
+
13
+ 1. **Run the list CLI.** Invoke the shipped script (it takes no arguments). The plugin root resolves via `CLAUDE_PLUGIN_ROOT` (falling back to the current directory when that variable is absent):
14
+
15
+ ```bash
16
+ node "${CLAUDE_PLUGIN_ROOT:-$(pwd)}/scripts/lib/pin/cli.cjs" list
17
+ ```
18
+
19
+ The CLI scans each harness `skills/` directory under the current project, finds the stubs carrying the gdd pin marker, and prints one line per pinned alias in the form `[<config-dir>] <alias> -> source=<skill> (pinned <timestamp>)`.
20
+
21
+ 2. **Report the result.** Relay the CLI output verbatim. Exit codes: 0 means one or more pinned aliases were found, 1 means none were found (nothing has been pinned yet), 2 means an error.
22
+
23
+ ## Do Not
24
+
25
+ - Do not scan the harness directories by hand. The CLI already enforces the marker check, so only genuine gdd pins are listed.
26
+
27
+ ## LIST-PINS COMPLETE
@@ -0,0 +1,37 @@
1
+ ---
2
+ name: gdd-pin
3
+ description: "Writes standalone shortcut aliases for a gdd skill across installed harness skill dirs. Use when you want a skill directly discoverable as its own command in every installed runtime."
4
+ argument-hint: "<skill-name>"
5
+ tools: Read, Bash
6
+ ---
7
+
8
+ # /gdd:pin
9
+
10
+ **Role:** Write a standalone shortcut alias (a small SKILL.md stub) for one gdd skill into every installed harness `skills/` directory, so that skill is directly discoverable as its own command in each runtime (Claude Code, Codex, Cursor, Gemini, and the rest).
11
+
12
+ Each pinned stub starts with the marker line `<!-- gdd-pinned-skill source=<skill> -->`, then carries frontmatter (name, description, argument-hint, tools) pulled from the manifest source of truth, then a one-line body pointing back at the canonical skill. Stubs are written atomically (temp file plus rename), so a failed write never leaves a half-written file.
13
+
14
+ ## Steps
15
+
16
+ 1. **Read the argument.** The skill name to pin comes from `$ARGUMENTS` (for example `darkmode`). If it is empty, ask the user which skill to pin and stop.
17
+
18
+ 2. **Run the pin CLI.** Invoke the shipped script, passing the skill name. The plugin root resolves via `CLAUDE_PLUGIN_ROOT` (falling back to the current directory when that variable is absent):
19
+
20
+ ```bash
21
+ node "${CLAUDE_PLUGIN_ROOT:-$(pwd)}/scripts/lib/pin/cli.cjs" pin "<skill-name>"
22
+ ```
23
+
24
+ The CLI detects every harness `skills/` directory that exists under the current project (`.claude/skills`, `.cursor/skills`, and so on) and writes the stub into each. Pass `--user` to also create the harness directories that do not exist yet:
25
+
26
+ ```bash
27
+ node "${CLAUDE_PLUGIN_ROOT:-$(pwd)}/scripts/lib/pin/cli.cjs" pin "<skill-name>" --user
28
+ ```
29
+
30
+ 3. **Report the result.** The CLI prints one line per harness it wrote to, plus any skips. Relay that summary verbatim. Exit codes: 0 means at least one stub was written, 1 means nothing was written (no harness dirs found, suggest `--user`), 2 means an error (for example an unknown skill name).
31
+
32
+ ## Do Not
33
+
34
+ - Do not hand-write the stub files. Always go through the CLI so the marker, the manifest-sourced frontmatter, and the atomic write stay consistent.
35
+ - Do not pin a skill that is not in the manifest. The CLI rejects unknown skill names with exit code 2; surface that error rather than inventing a stub.
36
+
37
+ ## PIN COMPLETE
@@ -0,0 +1,31 @@
1
+ ---
2
+ name: gdd-unpin
3
+ description: "Removes pinned skill aliases across harness dirs, deleting only stubs that carry the gdd pin marker. Use when you no longer want a pinned shortcut and want hand-written skills left untouched."
4
+ argument-hint: "<skill-name>"
5
+ tools: Read, Bash
6
+ ---
7
+
8
+ # /gdd:unpin
9
+
10
+ **Role:** Remove the pinned shortcut aliases for one gdd skill from every installed harness `skills/` directory. Only stubs that carry the marker line `<!-- gdd-pinned-skill source=<skill> -->` as their first non-empty line are deleted, so a hand-authored or unrelated SKILL.md is never touched.
11
+
12
+ ## Steps
13
+
14
+ 1. **Read the argument.** The skill name to unpin comes from `$ARGUMENTS` (for example `darkmode`). If it is empty, ask the user which skill to unpin and stop.
15
+
16
+ 2. **Run the unpin CLI.** Invoke the shipped script, passing the skill name. The plugin root resolves via `CLAUDE_PLUGIN_ROOT` (falling back to the current directory when that variable is absent):
17
+
18
+ ```bash
19
+ node "${CLAUDE_PLUGIN_ROOT:-$(pwd)}/scripts/lib/pin/cli.cjs" unpin "<skill-name>"
20
+ ```
21
+
22
+ The CLI scans every harness `skills/` directory under the current project, checks each candidate stub for the gdd pin marker, deletes the ones that carry it, and refuses (skips with a warning) any file that does not.
23
+
24
+ 3. **Report the result.** The CLI prints one line per harness it removed a stub from, plus a warning for any file it refused to delete. Relay that summary verbatim. Exit codes: 0 means at least one stub was removed, 1 means nothing was removed (no matching pinned stubs found), 2 means an error.
25
+
26
+ ## Do Not
27
+
28
+ - Do not delete skill files by hand. Always go through the CLI so the marker check protects hand-written skills.
29
+ - Do not force-remove a file the CLI refused. A refusal means the file lacks the gdd pin marker and is not a pinned alias; leave it in place.
30
+
31
+ ## UNPIN COMPLETE
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hegemonart/get-design-done",
3
- "version": "1.45.0",
3
+ "version": "1.46.0",
4
4
  "description": "A design-quality pipeline for AI coding agents: brief, plan, implement, and verify UI work against your design system.",
5
5
  "author": "Hegemon",
6
6
  "homepage": "https://github.com/hegemonart/get-design-done",
@@ -50,6 +50,8 @@
50
50
  "build:bundles": "node scripts/build-distribution-bundles.cjs",
51
51
  "build:skills": "node scripts/build-skills.cjs",
52
52
  "build:skills:check": "node scripts/build-skills.cjs --check",
53
+ "generate:skill-frontmatter": "node scripts/generate-skill-frontmatter.cjs",
54
+ "generate:skill-frontmatter:check": "node scripts/generate-skill-frontmatter.cjs --check",
53
55
  "build:sdk": "node scripts/build-sdk-bins.cjs",
54
56
  "prepack": "npm run build:sdk",
55
57
  "postpack": "node scripts/build-sdk-bins.cjs --clean",
@@ -849,6 +849,13 @@
849
849
  "phase": 28.5,
850
850
  "description": "Phase 28.5 skill-authoring contract — adapted from mattpocock/skills (MIT). SKILL.md <=100-line cap (warn >=100, block >=250 in CI), 1024-char description cap, <what>. Use when <triggers>. form (lax-mode default per Phase 33 A/B pending), frontmatter required fields, progressive-disclosure one-level-deep rule. Validator at scripts/validate-skill-length.cjs."
851
851
  },
852
+ {
853
+ "name": "skill-metadata",
854
+ "path": "reference/skill-metadata.md",
855
+ "type": "meta-rules",
856
+ "phase": 46,
857
+ "description": "Phase 46 skill-metadata single source of truth: scripts/lib/manifest/skills.json record shape, the generate-skill-frontmatter.cjs forward/extract/check modes, the skills.json to generator to build:skills to skills/+dist build chain, the six managed frontmatter keys (canonical order, always-quoted strings) vs extra_frontmatter passthrough, the 20..1024 description budget (validate-skill-length.cjs + lint-agentskills-spec.cjs R4, lint:agentskills CI gate), and the pin metadata catalogue consumer."
858
+ },
852
859
  {
853
860
  "name": "capability-gap-stage-gate",
854
861
  "path": "reference/capability-gap-stage-gate.md",
@@ -0,0 +1,117 @@
1
+ ---
2
+ name: skill-metadata
3
+ type: meta-rules
4
+ version: 1.0.0
5
+ phase: 46
6
+ tags: [skill, metadata, frontmatter, single-source-of-truth, generator, description-budget]
7
+ last_updated: 2026-06-02
8
+ ---
9
+
10
+ # Skill Metadata Single Source of Truth
11
+
12
+ `scripts/lib/manifest/skills.json` is the one place skill frontmatter is authored. A
13
+ generator projects it onto every `source/skills/<id>/SKILL.md`, the build step compiles
14
+ those into the shipped trees, and CI gates keep the three copies identical. This doc
15
+ explains the file, the generator, and the description budget. For the structural rules a
16
+ SKILL.md body must follow (line cap, progressive disclosure, frontmatter required fields),
17
+ see `./skill-authoring-contract.md`.
18
+
19
+ ## What skills.json is
20
+
21
+ The file is a JSON object: a `schema_version` integer and a `skills` array. Each array
22
+ element is one skill record. Only `name` is required (it must equal the
23
+ `source/skills/<id>/` directory name); every other field is optional and omitted when it
24
+ has no value.
25
+
26
+ ```json
27
+ {
28
+ "schema_version": 1,
29
+ "skills": [
30
+ {
31
+ "name": "health",
32
+ "description": "Reports .design/ artifact health - staleness, missing files, token drift, broken state transitions.",
33
+ "tools": "Read, Bash, Glob, Grep, mcp__gdd_state__get",
34
+ "disable_model_invocation": true
35
+ }
36
+ ]
37
+ }
38
+ ```
39
+
40
+ Recognized record fields: `name`, `description`, `argument_hint`, `tools`,
41
+ `user_invocable`, `disable_model_invocation`, `frontmatter_name` (the `name:` value when it
42
+ is not the default `gdd-<id>`), `extra_frontmatter` (see below), plus `registered_in_phase`
43
+ and `aliases`, which live only in the manifest and never round-trip to frontmatter. The
44
+ schema at `scripts/lib/manifest/schemas/skills.schema.json` validates the shape.
45
+
46
+ ## The build chain
47
+
48
+ Metadata flows in one direction, and a `*:check` gate guards each hop:
49
+
50
+ ```text
51
+ skills.json
52
+ -> generate-skill-frontmatter (npm run generate:skill-frontmatter)
53
+ -> source/skills/<id>/SKILL.md
54
+ -> build:skills (npm run build:skills)
55
+ -> skills/ + dist/claude-code/
56
+ ```
57
+
58
+ `scripts/generate-skill-frontmatter.cjs` rewrites only the frontmatter block of each
59
+ `SKILL.md`, never the markdown body. It has three modes:
60
+
61
+ - forward (no flag): manifest to frontmatter. The default.
62
+ - `--extract`: the reverse direction, reading current frontmatter back into `skills.json`
63
+ to seed or refresh the source of truth. Idempotent with forward.
64
+ - `--check`: the CI drift gate. It writes nothing and exits non-zero when any committed
65
+ frontmatter differs from what the manifest would generate.
66
+
67
+ `scripts/build-skills.cjs` then propagates `source/skills/` into the committed `skills/`
68
+ tree and `dist/claude-code/`; its own check mode asserts that the built output equals the
69
+ committed output. So the contract is: edit `skills.json`, regenerate, build. Never
70
+ hand-edit a managed frontmatter line in `SKILL.md`, because the drift gate will fail.
71
+
72
+ ## Managed vs preserved fields
73
+
74
+ The generator owns six frontmatter keys and emits them in this canonical order whenever the
75
+ record carries a value:
76
+
77
+ 1. `name`
78
+ 2. `description`
79
+ 3. `argument-hint`
80
+ 4. `tools`
81
+ 5. `user-invocable`
82
+ 6. `disable-model-invocation`
83
+
84
+ String values for `description` and `argument-hint` are always double-quoted on emit, so
85
+ quoting stays uniform across every skill. Anything outside these six keys is not managed.
86
+ The generator carries it verbatim in the record's `extra_frontmatter` array and re-emits it
87
+ after the managed block. The `quality-gate` skill is the working example: its `color`,
88
+ `model`, `default-tier`, `size_budget`, `parallel-safe`, `typical-duration-seconds`,
89
+ `reads-only`, and multi-line `writes:` block all live in `extra_frontmatter` and survive
90
+ every regeneration untouched.
91
+
92
+ ## Description budget
93
+
94
+ Every `description` must be at least 20 and at most 1024 characters. Two validators enforce
95
+ the ceiling in CI:
96
+
97
+ - `scripts/validate-skill-length.cjs` treats `DESC_MAX = 1024` as a blocker (it also blocks
98
+ under 20 characters as under-specification) and is the Phase 28.5 authoring-contract gate.
99
+ - `scripts/lint-agentskills-spec.cjs` rule R4 applies the same 1024-character hard cap from
100
+ the agentskills.io spec angle, and warns past 200 characters.
101
+
102
+ Phase 46 keeps that contract intact and wires `npm run lint:agentskills` in as its own
103
+ explicit CI gate, so the spec lint runs on every change rather than only in-process via the
104
+ doctor aggregator.
105
+
106
+ ## How pin consumes it
107
+
108
+ The `pin`, `unpin`, and `list-pins` skills shipping in this phase read `description`,
109
+ `argument_hint`, and `tools` straight from `skills.json`. That manifest is the pin metadata
110
+ catalogue: the pin surface never live-scrapes a `SKILL.md` or re-derives a description at
111
+ runtime. Reading one structured file keeps pin output consistent with what the generator
112
+ emits, and the `aliases` array is reserved for the pin shortcuts those skills honor.
113
+
114
+ ## See also
115
+
116
+ - `./skill-authoring-contract.md` for the SKILL.md line cap, description-format guidance,
117
+ required frontmatter fields, and progressive-disclosure rule.
@@ -24,7 +24,48 @@
24
24
  "properties": {
25
25
  "name": {
26
26
  "type": "string",
27
- "minLength": 1
27
+ "minLength": 1,
28
+ "description": "Skill id = source/skills/<name>/ directory name."
29
+ },
30
+ "frontmatter_name": {
31
+ "type": "string",
32
+ "description": "Frontmatter name: value when it is not the default gdd-<name>."
33
+ },
34
+ "description": {
35
+ "type": "string",
36
+ "minLength": 20,
37
+ "maxLength": 1024,
38
+ "description": "Skill description (Phase 28.5 budget: 20..1024 chars)."
39
+ },
40
+ "argument_hint": {
41
+ "type": "string"
42
+ },
43
+ "tools": {
44
+ "type": "string",
45
+ "description": "Comma-separated allow-list emitted as the frontmatter tools: line."
46
+ },
47
+ "user_invocable": {
48
+ "type": "boolean"
49
+ },
50
+ "disable_model_invocation": {
51
+ "type": "boolean"
52
+ },
53
+ "registered_in_phase": {
54
+ "type": "string"
55
+ },
56
+ "aliases": {
57
+ "type": "array",
58
+ "items": {
59
+ "type": "string"
60
+ },
61
+ "description": "Reserved for pin shortcuts; honored by the pin metadata catalogue."
62
+ },
63
+ "extra_frontmatter": {
64
+ "type": "array",
65
+ "items": {
66
+ "type": "string"
67
+ },
68
+ "description": "Non-managed frontmatter lines preserved verbatim (color, model, writes:, ...)."
28
69
  }
29
70
  }
30
71
  }