kit/plugins/skill-reviewer/skills/optimizing-skill-frontmatter/SKILL.md
Optimizes SKILL.md frontmatter fields. Rewrites descriptions to three-part format (≤200 chars) and tunes disable-model-invocation. Use when the user asks to optimize SKILL.md frontmatter.
npx skillsauth add shawn-sandy/agentics optimizing-skill-frontmatterInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Optimizes two frontmatter fields in SKILL.md files in a single pass: rewrites description: to the three-part format (≤200 chars total, short description ≤80 chars) and sets disable-model-invocation to the correct value based on whether the skill is a write-heavy workflow or a read-only advisory tool.
The description rewrite targets the three-part format: a short description (≤80 chars) capturing the essential function, followed by a capability sentence with richer detail, followed by the "Use when…" trigger phrase — aligning with Anthropic's authoring checklist requirement that descriptions include both what the skill does and when to use it (Pattern 1 in references/best-practices.md).
Why three-part format? Claude Code loads all skill descriptions into the context window each turn. The default skillListingBudgetFraction allocates 1% of the model’s context window — roughly 8,000 characters on a 200K-token model. The three-part format is designed around this budget:
The platform hard limit is 1,024 chars per description and 1,536 chars per skill listing entry; 200 is a practical target for surviving the default budget, not a platform constraint.
Why disable-model-invocation? This flag controls how a skill activates. true forces explicit invocation only (via /plugin:skill-name); omitting it lets the model auto-fire the skill when user intent matches. Workflow skills that write files, commit code, or run pipelines should require explicit invocation — auto-firing a deploy on a loose intent match causes unintended side effects. Advisory/read-only skills benefit from auto-activation. Negative-scope clauses (“Does NOT cover X”) are relocated to a ## When not to use body section rather than dropped.
Follow these steps exactly.
Does not review overall SKILL.md quality — use reviewing-skills for that. Does not change allowed-tools values — use auditing-allowed-tools for that. This skill only touches description: and disable-model-invocation.
ExitPlanMode is a deferred tool. Only call it if currently in plan mode — skip this step entirely when not in plan mode. When calling: use ToolSearch with select:ExitPlanMode first, then call ExitPlanMode silently.
Then enumerate all SKILL.md files in the current project:
find . -name "SKILL.md" | sort
If the command returns no results, fall back to Glob for kit/plugins/*/skills/*/SKILL.md. Store the full list as $PROJECT_SKILLS — it is used by Step 6's follow-up prompt.
Output one summary line: Found N SKILL.md files in this project.
Determine which SKILL.md files to optimize using this priority order:
Glob for **/plugins/<name>/skills/*/SKILL.md from the current project directory. If no results, fall back to kit/plugins/<name>/skills/*/SKILL.md.Glob for **/skills/*/SKILL.md from the current project directory. If no results, fall back to kit/plugins/*/skills/*/SKILL.md.Targeting the resolved file(s) for this pass. The full project list from Step 0 is held for the follow-up prompt in Step 6.
Extract the description value from each file’s YAML frontmatter and measure its length:
grep -n "^description:" <file> | head -1
Use only the first match — YAML frontmatter always appears before the body, so the first result is the frontmatter description:. Body lines (examples, worked output) may also contain description: and must be ignored.
Then count the value’s character length (excluding the description: prefix).
Skip rule: a file qualifies for SKIP only if it meets all three conditions: (1) total description ≤200 chars, (2) short description (first sentence) ≤80 chars, and (3) all three components present — a short description, a capability sentence, and a “Use when…” trigger phrase. A file is a REWRITE candidate if any condition fails: total >200, first sentence >80, missing short description, missing capability, or missing trigger. Do not exit silently. Instead:
{path} | {current chars} | {current description text}AskUserQuestion with three options:
Report a table of all files, current char count, and SKIP/REWRITE status before calling AskUserQuestion for each SKIP candidate.
Apply all five rules in order. Do not proceed to edits until rewrites are drafted.
The description value (not including description: or surrounding quotes) must be ≤200 chars total. The first sentence (short description, up to and including the first . ) must be ≤80 chars. Count carefully — both limits apply independently.
These are budget targets, not platform limits. The platform enforces ≤1,024 chars per description. The 200-char total target fits the full three-part description for ~40 skills installed (8,000 ÷ 200 = 40). The 80-char short description survives at ~100 skills. If the user explicitly wants a higher total target, use their stated limit — but keep the short description ≤80 chars regardless, since it must survive aggressive truncation.
Target descriptions with three components in this order:
## Overview. Example: ”Optimizes SKILL.md frontmatter fields.””Rewrites descriptions to three-part format (≤200 chars) and tunes disable-model-invocation.””Use when the user asks to [activation condition].” Example: ”Use when the user asks to optimize SKILL.md frontmatter.”Fixed order: short description first, capability second, trigger last. Third-person voice throughout. No first-person (“I will”, “I can”).
If any component is missing, see Rule 2b.
Handle each missing component independently:
Missing short description (most common after this format change): extract the first sentence of the ## Overview section and compress to ≤80 chars, third-person, present tense. Prepend as Sentence 1 before the existing capability and trigger.
Missing capability (description has only short description + trigger, or only trigger): extract the core action/output from ## Overview. Compress to ≤120 chars, third-person. Insert as Sentence 2 between the short description and the trigger.
Missing trigger (no "Use when…" phrase): draft "Use when the user asks to [condition]." from the skill name and Overview. Append as the final sentence.
Do not add a second short description, a second capability, or a second trigger if any is already present.
When all three components together exceed 200 chars: shorten the capability sentence first, then the short description (keeping it ≤80 chars), then shorten the trigger only if the capability is already minimal.
If the current description lists 4+ triggers that are near-synonyms (“create”, “generate”, “scaffold”, “build”), collapse to the 1–2 most distinctive. Keep the trigger that uniquely distinguishes this skill from sibling skills in the same plugin.
Example collapse: “create an agent, generate an agent plugin, scaffold an agent, add an agent to a plugin, build a new agent, or make a sub-agent” → “create, scaffold, or generate an agent or sub-agent in a plugin”
Any clause matching these patterns belongs in the body, not the description:
Remove the clause from the description. Add a ## When not to use section to the body with the same information. If the body already has a ## Scope, ## Limitations, or equivalent section, add the content there instead of creating a duplicate section.
Insertion point for new section: after ## Overview (if present), otherwise before ## Table of Contents, otherwise before the first ## Step N heading.
Remove:
”or says ‘…’” example lists that restate the trigger phrase in natural language (the runtime already does fuzzy matching)Do NOT remove:
Before (486 chars, trigger-only, no short description):
Use when the user asks to audit, recommend, fix, or generate the `allowed-tools`
frontmatter for a SKILL.md, or to review which tools/permissions Claude requested
during a Claude Code session. Triggers include "what allowed-tools should this skill
have", "fix skill permissions", "audit tool usage"... Does NOT score or audit general
SKILL.md quality — use reviewing-skills for that.
After (198 chars, three-part):
Audits allowed-tools frontmatter for SKILL.md files. Fixes, generates, or reviews tool permissions for a skill or Claude Code session. Use when the user asks to check, fix, or review tool permissions for a skill.
Body addition inserted before ## Mode 1: Static audit:
## When not to use
Does not score or audit general SKILL.md quality — use reviewing-skills for that.
What changed and why:
Triggers include "…" list: 7 near-synonyms with no selectivity gain (Rule 5)Before (136 chars, two-part — REWRITE because short description is missing):
Trims SKILL.md descriptions to ≤200 chars and tunes disable-model-invocation. Use when
the user asks to optimize SKILL.md frontmatter.
After (188 chars, three-part):
Optimizes SKILL.md frontmatter fields. Rewrites descriptions to three-part format (≤200 chars) and tunes disable-model-invocation. Use when the user asks to optimize SKILL.md frontmatter.
What changed and why:
For each file marked REWRITE, make edits in this order:
Edit A — Body insertion (if Rule 4 applies):
Read the file, identify the insertion point, then use Edit with sufficient surrounding context as old_string to make the match unique. Add the ## When not to use section.
Edit B — Description rewrite:
Use Edit with the full original description: … line as old_string. Preserve the original quoting style — if the original value was in double quotes, keep double quotes; if single-quoted, keep single quotes; if unquoted, keep unquoted.
Confirm each edit succeeded before moving to the next file. If the file has both edits, do body insertion first to avoid line-number drift.
For each SKILL.md resolved in Step 1 (not just files that were rewritten — files that were SKIP'd in Step 2 may still need invocation control tuned), classify it as workflow or advisory using two static signals:
| Signal | Strong workflow → true | Strong advisory → omit |
|---|---|---|
| allowed-tools: | Contains Edit, Write, or Bash with side-effect verbs | Only Read, Glob, Grep, WebFetch, WebSearch, AskUserQuestion |
| description: verbs | commit, push, PR, ship, branch, deploy, migrate, generate, scaffold, iterate, TDD-loop, "writes to" | review, audit, check, analyze, score, advise, report, recommend |
| Body signals | mentions ExitPlanMode Step 0; mentions writing/editing files | "report under N words"; no Edit/Write calls in any step |
Confidence rules:
Never write disable-model-invocation: false. The convention in this repo is: write true for workflow skills; omit the field entirely for advisory skills.
Print a compact table — one row per touched SKILL.md:
| Path | Current value | Recommendation | Confidence | Reason |
|------|---------------|----------------|------------|--------|
| kit/plugins/foo/skills/bar/SKILL.md | missing | omit (no change) | confident | read-only tools, advisory verbs |
| kit/plugins/foo/skills/baz/SKILL.md | missing | true | confident | Edit+Bash in allowed-tools, "generates" in description |
Show true / missing in the Current value column. Show omit (no change) when the current value already matches the recommendation.
Call AskUserQuestion with three options:
omit (no change) rows)To set true: first check for any existing disable-model-invocation: line (any value — including false). If one exists, delete it. Then insert disable-model-invocation: true on a new line immediately after the allowed-tools: line.
Step 1 — delete any existing disable-model-invocation line:
--- (line 1) and the closing --- (the next --- after line 1). Run Grep for ^disable-model-invocation: only within that extracted range — stop after the first frontmatter block so instruction examples in the body code blocks are not matched.Edit with that exact matched line as old_string and "" as new_string.# Example — if grep returned: disable-model-invocation: false
old_string: "disable-model-invocation: false\n"
new_string: ""
Step 2 — insert after the allowed-tools: line:
--- delimiters as above). Run Grep for ^allowed-tools: within that range to get the exact frontmatter line content.Edit with that exact line as old_string, appending disable-model-invocation: true on the next line.# Example — if grep returned: allowed-tools: AskUserQuestion, Read, Edit, Bash
old_string: "allowed-tools: AskUserQuestion, Read, Edit, Bash\n"
new_string: "allowed-tools: AskUserQuestion, Read, Edit, Bash\ndisable-model-invocation: true\n"
Never use placeholder values like <value> — always grep the file for the exact current content and use that as old_string.
To remove an existing true: delete the disable-model-invocation: true line entirely (do not replace with false). If an existing false is present, delete it too — never leave false in the file.
Never write disable-model-invocation: false — the omit-the-field convention must be preserved.
After all edits, re-measure both total length and short description length:
for f in <edited-files>; do
line=$(grep "^description:" "$f" | head -1)
val="${line#description: }"
val="${val%\"}"
val="${val#\"}"
val="${val%\'}"
val="${val#\'}"
# Total length
total=${#val}
# Short description: first sentence (up to and including the first ". ")
short="${val%%. *}"
short_len=${#short}
echo "total=${total} short=${short_len} $f"
done
Confirm every total ≤200 and every short ≤80. Report any violations for a second rewrite pass. Flag separately: total-only violations (capability too long) vs. short-only violations (first sentence needs trimming).
After the targeted file(s) from Step 1 have been handled, re-measure every file from the $PROJECT_SKILLS list captured in Step 0:
for f in $PROJECT_SKILLS; do
line=$(grep "^description:" "$f" | head -1)
val="${line#description: }"
val="${val%\"}"
val="${val#\"}"
val="${val%\'}"
val="${val#\'}"
echo "${#val} $f"
done
Print a table with columns path | chars | status where status is:
DONE — already processed this sessionREWRITE — >200 charsSKIP — ≤200 chars and compliant phrasingThen call AskUserQuestion with three options:
After verification, count the total number of installed skills:
find . -name "SKILL.md" | wc -l
Then output this advisory to the user, substituting the actual count:
Skill listing budget check You have N skills installed. Claude Code’s default
skillListingBudgetFractionallocates 1% of the context window (~8,000 chars on a 200K-token model) for all skill descriptions combined.| Installed skills | Safe avg description length | Format target | |---|---|---| | ≤40 | ~200 chars | Full three-part (short + capability + trigger) | | ~50 | ~160 chars | Two-part (capability + trigger) | | ~100 | ~80 chars | Short description only |
The three-part format is designed so the short description (≤80 chars, always Sentence 1) survives even at ~100 skills — truncation never removes the label entirely.
Run
/doctorto see whether any descriptions are currently being truncated or dropped.If
/doctorshows overflow, add this to your.claude/settings.json:{ "skillListingBudgetFraction": 0.02 }This doubles the budget to ~16,000 chars at a cost of ~2,000 tokens of context per turn.
Skip the advisory if the count is ≤40 and all descriptions are already ≤200 chars — no action is needed in that case.
References:
skillListingBudgetFraction, maxSkillDescriptionChars) — https://code.claude.com/docs/en/settings/doctor command — https://code.claude.com/docs/en/skillsdevelopment
Turns a React component into a social card with preview, code, and props table. Builds a static preview and screenshots react-card.html via Playwright. Use when asked to share a React component.
data-ai
Refine-prompt: interviews users and assembles a structured AI prompt using Anthropic best-practice techniques. Use when the user runs /plan-agent:refine-prompt or asks to refine a prompt.
development
Plan review Agent Team. Reviews HTML implementation plans in parallel, synthesizes findings, and applies improvements in place. Use when the user asks to review or improve an implementation plan.
data-ai
Craft-prompt: interviews users and assembles a structured AI prompt using Anthropic best-practice techniques. Use when the user runs /plan-agent:craft-prompt or asks to craft a prompt.