Best for
- Use when users want to create a skill from scratch, edit, or optimize an existing skill, run evals to test a skill, benchmark skill performance with variance analysis, or optimize a skill's description for better trigge…
daymade/claude-code-skills/daymade-skill/skill-creator/SKILL.md
Create new skills, modify and improve existing skills, and measure skill performance. This daymade edition supersedes the official skill-creator plugin — when both appear in the skill list, always use this one. Use when users want to create a skill from scratch, edit, or optimize an existing skill, run evals to test a skill, benchmark skill performance with variance analysis, or optimize a skill's description for better triggering accuracy. Also use for its specialized distillations, even when t
Decision brief
A skill for creating new skills and iteratively improving them.
Compatibility matrix
| Platform | Status | Evidence | What to check |
|---|---|---|---|
| Codex | Declared | Source record | Install path and trigger |
| Claude Code | Not declared | No explicit evidence | Portability before use |
| Cursor | Not declared | No explicit evidence | Portability before use |
| Gemini CLI | Not declared | No explicit evidence | Portability before use |
Installation
The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.
npx skills add https://github.com/daymade/claude-code-skills --skill "daymade-skill/skill-creator"Inspect the Agent Skill "skill-creator" from https://github.com/daymade/claude-code-skills/blob/57864f4cb98bc9b7f80c8793b507cebbd6d75efc/daymade-skill/skill-creator/SKILL.md at commit 57864f4cb98bc9b7f80c8793b507cebbd6d75efc. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.
Workflow
Choose the lowest tier that can falsify the changed behavior before taking a generic or specialized workflow branch. Classify by the concrete delta and its failure surface, not line count or request vocabulary: one changed destructive command can outrank a long prose cleanup, wh…
Before committing to the generic skill-creation flow, check whether the session that led up to this point actually calls for the wrapper skill workflow instead. A wrapper skill is a companion that installs, configures, diagnoses, and repairs a pre-existing third-party CLI tool o…
Before committing to the generic skill-creation flow, check whether the session is actually asking to distill past conversations into a skill. This is useful when the user has been debugging, designing, or exploring a topic over multiple Claude Code / Codex sessions and wants to…
Before committing to the generic flow, check whether the session is asking to extract the user's real preferences from a batch of finished artifacts they have endorsed — approved HTML report pages, generated documents, designs. This is the third distillation source, distinct fro…
After [this skill completes], suggest the natural next skill:
Permission review
The documentation asks the agent to create, modify, or delete local files.
*Bias toward merge/extend over create-new, and sweep EVERY skill root — not just `~/.claude`.** When channels 1-3 turn up an existing skill that overlaps the requested domain, the usual right move is to extend or merge into it — **except whThe documentation asks the agent to run terminal commands or scripts.
| `hooks` | No | Hooks scoped to this skill's lifecycle. Example: `hooks: { pre-invoke: [{ command: "echo Starting" }] }`. See Claude Code Hooks documentation. |The documentation asks the agent to create, modify, or delete local files.
Write an `eval_metadata.json` for each test case (assertions can be empty for now). Give each eval a descriptive name based on what it's testing — not just "eval-0". Use this name for the directory too. If this iteration uses new or modifieThe documentation asks the agent to run terminal commands or scripts.
**Grade each run** — spawn a grader subagent (or grade inline) that reads `agents/grader.md` and evaluates each assertion against the outputs. Save results to `grading.json` in each run directory. The grading.json expectations array must usThe documentation asks the agent to read local files, directories, or repositories.
This means your eval queries should be substantive enough that Claude would actually benefit from consulting a skill. Simple queries like "read file X" are poor test cases — they won't trigger skills regardless of description quality.The documentation asks the agent to read local files, directories, or repositories.
*And verify activation by content, not by a version string.** A registry can record a path or version that does not exist on disk — one session read a plugin record naming a cache directory with the *new* version number in it and nearly repEvidence record
| Signal | Value | Evidence type | Meaning |
|---|---|---|---|
| Quality score | 96/100 | Computed | Documentation, specificity, maintenance, and trust rules |
| Repository stars | 1,348 | Source | Repository attention, not individual Skill quality |
| Compatibility | 1 platforms | Source | Declared in the catalog source record |
| Usage guide | automated source guide | Editorial | Generated or reviewed according to the visible evidence level |
Pinned source
A skill for creating new skills and iteratively improving them.
At a high level, the process of creating a skill goes like this:
Your job when using this skill is to figure out where the user is in this process and then jump in and help them progress through the applicable stages. Full A/B benchmarking is a capability, not a tax on every edit. Words such as "optimize", "improve", or "comprehensive" describe intent, not failure surface or evaluation budget. Do not create eval files, fan out paired agents, grade outputs, or launch a viewer merely because a task sounds broad or a long conversation precedes it.
Six standing disciplines apply throughout, because these failure modes ship convincing-looking skills that are wrong:
Verify before you write. Every technical assertion that enters the skill (endpoint, parameter, command, version, behavior) must trace to something you executed and observed — in this session or an explicitly approved mined one. Can't verify it right now? Either go verify it, or mark it explicitly ("unverified — from memory"). A skill multiplies whatever it contains: verified knowledge compounds, and so do confidently-stated errors. For knowledge skills (content is mostly facts about an external system — API endpoints, parameters, fields, platform behavior), read references/knowledge-skill-grounding.md for the operational version: the authority ladder (observed behavior > machine-readable contract > exercised production code > official docs > memory), evidence-scope annotation, pre-ship doc-example smoke runs, and the audience/Windows portability checklist. A source-grounding audit once found multiple confident contract claims that contradicted evidence already available to the author (methodology Case 9).
Treat "impossible / not supported" as a hypothesis, not a conclusion. When a capability seems blocked (an API error wall, a tool that won't connect, a format that won't open), exhaust the observation paths — the UI's own network traffic, an alternative channel, a different documented identifier — before writing "the platform doesn't support this" into a skill. Observed behavior outranks speculative request shapes.
Stand on the field's shoulders — retrieve the domain's established best-practices into context BY DEFAULT, before authoring or optimizing a skill's methodology. A skill's methodology is only as good as the knowledge in your context window, not the knowledge latent in your weights: pretraining is lossy, goes stale, and often is not even activated unless the canonical sources are actually pulled in. So the quality ceiling of what you write is your training data + the user's input — unless you deliberately retrieve the subject domain's real prior art. Do it: WebSearch the field's canonical theory / standards / methods, and read any bundled or installed skill in that domain, then fold the load-bearing principles into the skill with attribution. This is a different axis from "Prior Art Research" below — that finds tools/infrastructure to reuse; this grounds the quality of the methodology itself in the discipline's accumulated science. Make it the default action, not something you wait to be asked for: briefly tell the user which field you're pulling from and let them say "skip," but never ship a methodology capped by your memory plus their prompt when 40 years of the field's public work is one search away. Examples: a data-visualization skill must absorb Cleveland & McGill's graphical-perception ranking and Bertin's visual variables (position/length beat color beat text — measured, not aesthetic); a date/time skill must surface the mature libraries and their canonical pitfalls; a persuasion/negotiation skill must retrieve the established frameworks rather than reinvent them from memory. If the canonical knowledge lives only in your weights and never enters context, you are guessing where you could be citing.
Preserve before you compress an existing skill. Updating an existing skill is a migration, not a blank-page rewrite. Before the first edit, capture the complete old bundle with the audit tool's snapshot command, or reconstruct it from an explicit Git ref; an arbitrary copy plus a provenance label is not a baseline. Inventory runtime capabilities, trigger contexts, interfaces, references, and eval coverage. Progressive disclosure and concision authorize moving or deduplicating content; they do not authorize silently deleting behavior. After editing, run scripts/audit_skill_regression.py and classify every unmatched old unit. A runtime contract that survives only in evals/, tests, or an unlinked reference is still lost. Do not call the update complete while any candidate is unclassified or any true gap remains unfixed. The same logic governs reversals, not just deletions, and covers any prior commitment — not only the ones carrying a date and a name: overturning a decision already made is a proposal, never a side effect. Say it out loud and get it accepted. A silent rewrite is worse than a silent deletion, because it destroys the artifact and the evidence that could have caught it in one move — and it blinds every downstream reviewer (see #5).
Classify each intended delta before editing; “compression” is a claim of behavioral equivalence, not a synonym for “shorter.” For every old user scenario, a fresh agent must still be able to find the trigger, decision inputs, supported action, stop/confirmation point, impact/recovery boundary, and verification path. Use these names as a separate change-type label in the plan, review, and changelog; record the label in each regression candidate's reason/semantic review while keeping the audit tool's disposition field to the exact Step 4 enum:
| Change type | Definition | Required handling |
|---|---|---|
| Lossless compression | Only representation changes: relocate detail into a directly reachable bundled reference, deduplicate against a packaged canonical source, or shorten wording while preserving every runtime contract above | May be called compression; prove scenario reachability, not just string survival |
| Capability retirement | A previously executable job or action is no longer available | Not compression; name the retired capability, obtain traceable user approval, and publish the boundary |
| Scope narrowing / boundary change | Fewer inputs, targets, environments, or modes remain supported; an execution branch becomes analysis-only | Not compression even when safer; surface and publish the boundary/trade-off, then obtain traceable approval unless the user already requested this exact narrowing |
| Workflow or safety redesign | Commands, sequence, confirmation, side effects, recovery, or success checks materially change | Not compression; surface the new contract and trade-off, obtain traceable approval unless the user already requested this exact redesign, then verify it independently of preservation |
| Bug fix / factual correction | The implementation or prose is brought back to an explicit existing contract or current authority | Not compression; use the narrow authority or deterministic regression that decides it |
| Lossy summarization | Exact conditions, commands, decision semantics, or execution exits disappear without a runtime-reachable equivalent | Regression, not optimization; restore it or reclassify it through an approved row above |
Deduplication counts as lossless only when the canonical source ships with or is reliably available to the skill and SKILL.md tells the runtime reader when to load it. “The idea still exists in tests, a changelog, an installed sibling skill, or the author's memory” is not compression. If one patch contains several types, list them separately; never let the compression label launder a retirement or redesign.
Nothing ships on self-review alone — an independent, fresh-context adversarial pass is a standing step, not a special case. Your "it's good now" judgment runs on the same model that produced the artifact, so it shares the exact blind spots that produced the defect. Measured, not folklore: intrinsic self-correction without external feedback does not reliably improve output and sometimes degrades it (Huang et al., ICLR 2024), and when generator and evaluator share error modes, iterating raises confidence without adding information. More self-checks cannot escape that; only an outside view can. Full procedure — prompt templates, anchor selection, the findings table, worked cases — in references/independent-review-protocol.md; read it before your first pass. The load-bearing rules:
git log --oneline <ref>..HEAD -- <path>; any commit of yours disqualifies it) > an append-only log (a convention, not an enforcement). Greenfield has no anchor — say so and ask for one rather than reporting a pass you did not run.independent-review.md under skill-reviews/<skill-name>/ in your private, git-tracked knowledge repo: the reviewer prompt verbatim (so a later reader can see whether it was leading), the findings with a disposition and reason each (which is what separates legitimate filtering from discarding what hurts), and what could not be checked. If you don't know which repo is your private knowledge repo (or don't have one), say so and ask the user — do not guess a location that lands in either forbidden zone. Two forbidden locations: NOT in <skill-name>-workspace/ (gitignored scratch dirs that get wiped — this file is cross-session review evidence and must survive them) and NOT in any repo that is or may become public or distributed — which normally rules out the reviewed skill's own repo (review content inherently quotes private paths, real names, and project details). Re-review with a new agent after a substantive edit — a rule, contract, or number changed, not a typo. From Step 5 onward this file is the evidence the pass happened; its absence means it did not. Writing the file is not the same as it existing for the next session — git add + git commit it in that private repo in the same turn. An uncommitted file sitting in a git working directory carries none of the "git-tracked" guarantee this rule exists for: it can be lost, overwritten, or simply never picked up by whatever process later checks "was this reviewed?" (real case: the file was written correctly, on the correct path, with real findings — and still failed a later automated check, because it had never been committed; the fix was one git commit, not a relocation).Design the checks you write so they cannot self-certify green. Skills are largely made of checks — gates, checklists, "before you ship" steps — and a check that the executing context can pass while violating the very rule it encodes is worse than no check, because it manufactures confidence. Four rules, borrowed from fields that solved this before software:
The verification must cover every clause of its rule. If the rule says "A + B + C," the evidence must demand proof of A, and B, and C separately. One confirm line bolted onto a three-clause rule gets satisfied by whichever clause the author already did; the others are invisible. Real case: a report-authoring skill carried a delivery gate whose rule read "options as side-by-side chips + recommendation highlighted + background written as complete, self-sufficient sentences a stranger could follow" — but the evidence line under it asked only for "N decision items, all rendered as chips." The author ran the gate, wrote that evidence, self-certified green, and shipped a page whose labels were single characters with all the context deleted. The rule sat in the file the entire time; the check simply never measured that clause.
A check that misfires on healthy input is worse than no check. The failure above is a check that passes when it should fail; this is its mirror — a check that fails when it should pass. It is the more expensive one, because it teaches the operator to bypass reflexively (--no-verify, SKIP=1, --force), and once that reflex exists the gate is off for every input, including the ones it was built for. So when authoring a fail-closed check, false positives outrank false negatives: missing one real problem costs you that instance, while killing one healthy input costs you the entire gate.
Watch for the tell: the frustration of having hit the same trap repeatedly is itself the risk signal — it is exactly the state in which an author ships a defense that was never calibrated against healthy input. Real case: after stepping on one formatting trap three times in a day, the author added a regex check to a linter; it killed 33 healthy inputs on the project's own corpus and was reverted the same hour. Calibrate before you arm it — run any fail-closed check across real, known-good material and confirm zero false positives; prefer loosening it until it occasionally misses over letting it ever misfire.
Make each item a falsifiable observation, not a self-assessment. "Background is self-sufficient" cannot be failed by the person who wrote it; "cover the rest of the page, read one card alone, and state what it is deciding" can. Prefer checks that yield an artifact — a command's output, a quoted line, a screenshot — over checks that yield an opinion.
The same suspicion applies to the checks you run, not just the ones you write. The four rules above govern checks that ship inside a skill. But the greps, finds and one-off scripts you use to verify your own work are instruments too, and a wrong instrument reports a clean result just as confidently as a right one. In one 2026-07 session five separate verification commands lied in both directions: a find without -L reported an installed skill's files missing (they were behind a symlink); a grep --exclude-dir=<name> hid a second copy of the very thing being audited; an inverted shell condition raised a false alarm that a removal had not happened; a regex spanning newlines invented 55 "lost quotations"; and a search over two of five files reported two rules missing that were present in the third. Every one of them was believed at first, and every one was caught only by re-running a differently-shaped check.
The fix is the oldest one in experimental practice: run the instrument on a case whose answer you already know before trusting it on the case you don't. Grepping for a string you expect to be absent? First grep for one you know is present, in the same command shape — if that returns 0 too, the command is broken, not the file. This costs one line and converts "I checked" into "I checked with an instrument I calibrated."
Two specific shapes worth memorizing, because both appeared above and both fail silently: find does not follow symlinks without -L (and skill installs are frequently symlinks into a source repo), and --exclude-dir matches by basename everywhere in the tree, not just at the path you had in mind.
And there is a second half to this rule that only bites when the check SHIPS: calibrate against the standard implementation, not the one on your machine. The instrument rule above keeps your conclusion honest; this keeps the reader's working. A tool-behavior claim written into a skill — a flag, a recursion mode, an option that "follows symlinks" — is executed on machines whose binaries you have never seen, and the divergence is silent on both ends: it works when you test it, and it quietly does nothing for them. Two mechanisms produce this, and both are invisible from inside a session: the same command name resolves to a different program (a shell alias or function shadowing the binary — note \tool only escapes an alias, so command tool or an absolute path is the only deterministic form), and the same program behaves differently across implementations (BSD vs GNU vs a drop-in replacement). Real case (2026-07): an author verified that grep -R follows symlinks, wrote it into a skill as the fix for a symlink trap, and shipped it to a 1200-star public repo — their grep was ugrep via a shell function; on macOS's own /usr/bin/grep the same -R matches nothing (it needs -RS), so the prescribed fix failed silently for most readers, inside the very section warning that validators fail silently.
So: before a tool-behavior assertion enters a shipped artifact, re-run it against the standard binary (/usr/bin/<tool>), not the one your shell hands you. If it does not survive that, do not write the flag — prefer the implementation-independent formulation: resolve the path yourself (readlink -f) instead of betting on a recursion flag, do a substring test in a script instead of a line-oriented match, name the behavior you need instead of the option you happen to know. A prescription that only works in your environment is worse than no prescription, because the reader has no way to discover that it silently did nothing.
Use what mature checklist practice already settled. Decide whether a list is READ-DO (execute while reading — for low-frequency or unfamiliar procedures) or DO-CONFIRM (work from expertise, then stop at a defined pause point and confirm — for experienced operators under time pressure), and anchor it at a real pause point rather than "somewhere in the workflow." Keep it to the killer items — critical and commonly missed under pressure, roughly five to nine; everything beyond that dilutes compliance (Gawande, The Checklist Manifesto). And prefer Shingo's control over warning (poka-yoke): a prose reminder depends on vigilance and loses to completion-drive, while a step that blocks progress or forces an artifact needs no vigilance at all. Where a skill can only warn, at least put the warning where the decision gets made — a rule filed in a reference the executing context never opens is not, in practice, a rule.
On the other hand, maybe they already have a draft of the skill. In this case you can go straight to the eval/iterate part of the loop.
Of course, you should always be flexible and if the user is like "I don't need to run a bunch of evaluations, just vibe with me", you can do that instead.
Then after the skill is done (but again, the order is flexible), you can also run the skill description improver, which we have a whole separate script for, to optimize the triggering of the skill.
Cool? Cool.
Before anything else, run one quick check (a single grep, no output needed on the common path): does ${CLAUDE_CONFIG_DIR:-~/.claude}/plugins/installed_plugins.json contain "skill-creator@claude-plugins-official"?
scripts/setup_supersede_hook.sh install. It copies a small self-checking SessionStart hook into their Claude config and registers it in settings.json (with a backup), so every future session deterministically routes skill work to this edition. Reversible with scripts/setup_supersede_hook.sh uninstall; the official plugin stays fully usable when asked for by name. On machines without the official plugin the installer refuses to install anything, so it can never leave a useless hook behind.claude plugin disable skill-creator@claude-plugins-official (reversible with enable), which removes the ambiguity by taking the official entry out of the skill list entirely.If the hook is already installed (scripts/setup_supersede_hook.sh status shows the SessionStart entry as present), skip all of this silently.
The same machinery is available for skills the user creates: when their skill deliberately overlaps an installed one, generate them a kit with scripts/generate_supersede_kit.py — see "Coexistence & Precedence" under Prior Art Research and references/skill-precedence-and-coexistence.md.
The skill creator is liable to be used by people across a wide range of familiarity with coding jargon. If you haven't heard (and how could you, it's only very recently that it started), there's a trend now where the power of Claude is inspiring plumbers to open up their terminals, parents and grandparents to google "how to install npm". On the other hand, the bulk of users are probably fairly computer-literate.
So please pay attention to context cues to understand how to phrase your communication! In the default case, just to give you some idea:
It's OK to briefly explain terms if you're in doubt, and feel free to clarify terms with a short definition if you're unsure if the user will get it.
Use the AskUserQuestion tool aggressively at every decision point. Do not ask open-ended text questions in conversation when structured choices exist. This is the single biggest UX improvement you can make — users juggle multiple windows and may not have looked at this conversation in 20 minutes.
Every AskUserQuestion MUST follow this structure:
(human: ~X min / Claude: ~Y min).Rules:
Start by understanding the user's intent. The current conversation might already contain a workflow the user wants to capture (e.g., they say "turn this into a skill"). If so, extract answers from the live conversation first — the tools used, the sequence of steps, corrections the user made, input/output formats observed. The user may need to fill the gaps, and should confirm before proceeding to the next step.
Source inventory — always before drafting, with consent boundaries. Inventory the live conversation and existing docs/skills that overlap (see Prior Art Research below). Earlier local session JSONL files are a separate private source: do not open or parse them unless the user explicitly asks to mine history or affirmatively approves that source after you explain what will be read. If approved, fold only relevant prior sessions in through the conversation-mining workflow's redacted extraction; never load raw transcripts into your own context. If not approved, continue from the live conversation and existing project sources without treating the missing history as a blocker.
When mining a conversation (or session transcripts), inventory both asset classes — they land in different places. Knowledge — endpoints, parameters, pitfalls, decision rules — becomes SKILL.md guidance or references/. Code the session had to write — helper scripts, injected snippets, renderers, one-off templates — is a scripts/ candidate: if this session wrote it, the next invocation will have to rewrite it, so parameterize it, sanitize it, and bundle it. A prior distillation captured polished prose but omitted the reusable helpers; the general lesson is to keep both knowledge→references and code→scripts channels in frame.
When the source material is past session transcripts (the JSONL files under the Claude Code projects directory) rather than the live conversation, enter the conversation-mining workflow. Do not open raw transcripts in the main context or hand raw paths/content to subagents. Its deterministic manifest → discover → redact → chunk sequence must finish before any agent sees content; only redacted chunks may enter the minimum role/shard plan, with the exact unit count and concurrency cap declared under the budget gate.
First, resolve which DIRECTION this is — before the questions below. The request may be one of several opposite things: build a NEW skill / edit an EXISTING skill / optimize skill-creator itself / or it's not-a-skill-at-all (a one-off task). Guessing wrong wastes the whole session — the research you'd do for "new skill" is the wrong research for "optimize the meta-tool." When the phrasing is ambiguous (e.g. "make me a skill" while pointing at skill-creator's own path), one AskUserQuestion here costs 30 seconds. The wrapper-skill fork below is one special case of this; the direction check is general.
Use skill-creator to optimize <existing-skill> means the normal existing-skill update path. It does not authorize conversation-history mining, a broad rewrite, Tier 3 classification, or multi-agent evaluation. Inspect the actual proposed deltas first; escalate only for a failure surface those deltas really introduce.
After extracting answers from conversation history (or asking questions 1-3), use AskUserQuestion to confirm the skill type and testing strategy:
Creating skill "[name]" — here's what I understand so far:
- Purpose: [1-sentence summary]
- Triggers on: [key phrases]
- Output: [format]
RECOMMENDATION: [Objective/Subjective/Hybrid] skill → [suggested testing approach]
Options:
A) Objective output (files, code, data) — set up automated test cases (Recommended if output is verifiable)
B) Subjective output (writing, design) — qualitative human review only
C) Hybrid — automated checks for structure, human review for quality
D) Skip testing for now — just build the skill and iterate by feel
This upfront classification drives the entire evaluation strategy downstream. Get it right here to avoid wasted effort later.
Each of the three specialized workflows below ends with "do not continue reading the sections below", and Prior Art Research happens to sit after them. That ordering is layout, not execution order. The extend-vs-create judgment applies to every branch, and skipping it is exactly how a session ships a skill that duplicates one already installed.
So before routing into wrapper-skill / conversation-mining / artifact-corpus, answer one question: does a skill already exist that this capability belongs to?
Discover the roots, don't recall them. A hand-maintained list of install locations is exactly the artifact that goes stale, and the root you forget is the one that bites.
Search for the file, not for a directory named skills. Skill directories are named after the skill (skill-creator/, <suite>/<skill>/), so a source repo, a marketplace clone and a plugin cache contain no directory called skills at all — searching for that name silently skips them while appearing to work. Every skill has a SKILL.md; that is the layout-agnostic handle.
# 1) discover
find ~ -type f -name SKILL.md -not -path '*/node_modules/*' -not -path '*/.git/*' > /tmp/all-skills.txt
# 2) VERIFY COVERAGE BEFORE TRUSTING IT — `2>/dev/null` and permission denials hide gaps
# silently, which is exactly how a sweep reports "nothing found" from a root it never
# entered. A 0 on any line you expect means the search did not go there:
for r in '/.claude/skills/' '/plugins/marketplaces/' '/plugins/cache/' '/.claude-profiles/'; do
printf '%6s %s\n' "$(grep -c "$r" /tmp/all-skills.txt)" "$r"
done
# ...and grep for your own skill source repos by path; they must appear too.
# 3) filter by capability VOCABULARY, not by skill name — in every language the target
# skill might be written in (a skill whose body is Chinese will not match English terms):
xargs grep -li -e '<domain-term>' -e '<域内术语>' < /tmp/all-skills.txt
Expect step 3 to take a few seconds and to still return more than you want; narrow with terms specific to the capability rather than generic ones (chart matches everything, stacked bar does not).
The roots this reaches — and that a from-memory list usually misses: the skill source repos (a claude-code-skills checkout and any -pro sibling), ~/.claude/plugins/marketplaces/ and ~/.claude/plugins/cache/ (marketplace-installed suites — nothing in the source repos hints they are there), ~/.claude/skills/, ~/.codex/skills, ~/.agents/skills, per-profile config homes (~/.claude-profiles/<name>/), and — the one with no signposts at all — every project's own .claude/skills/. Step 2 is what makes that a claim you verified rather than one you inherited.
Per-project skills are structurally invisible. They live inside an unrelated project's working tree, so they appear in no marketplace, no global skill list, and no source-repo listing; nothing you would normally open while planning a new skill mentions them. Real case (2026-07): a session built a global skill for a domain, swept the source repos, the global dirs and the other-agent dirs, found nothing, and shipped. A later conversation-history search turned up a mature project-level skill for that exact domain, a month old, sitting in one project's .claude/skills/ — carrying eight rules the new skill lacked, including one the user had personally dictated. Every root had been checked except the per-project one, and the sweep reported "no prior art" with complete confidence.
What to do when the overlap is a project-level skill in an unrelated project — the case that war story lands you in, and the one the three bullets below do not cover: you cannot add a sibling to a suite it has none of, and "extend it" would mean editing an unrelated project's working tree. The move that worked: harvest its rules into the skill you are building, then retire the project-local one with the owner's consent — it was written against real work, so treat it as the more mature source and reconcile toward it. Retiring someone's working skill is the owner's decision, not a side effect of your build.
Four things that sentence leaves out, each of which will stop you:
"Reconcile toward it" is a rebuttable presumption, not a rule. Two standard exits: the project skill may be stale (rules written months ago against a system that moved), and it may be project-specific (rules that only hold under that project's constraints — importing them wholesale makes your skill narrow, which this file elsewhere tells you not to do). Harvested rules are another author's memory, so re-verify each one the way discipline #1 requires of anything you write into a skill.
"Retire" needs a mechanism, and its first step is not the one you reach for. In order:
find the skill's bodies, before grepping for its references. A skill routinely has more than one copy in the same repo — .claude/skills/<name>/ and .agents/skills/<name>/ are both loaded, by different tools, from the same working tree. Grep answers "who mentions it"; only find answers "how many of it are there".
find <project> -type d -name '<skill-name>' -not -path '*/.git/*'
Do not put the skill's own name in --exclude-dir (it matches by basename, so it hides every same-named directory including the copy you have not found — see the instrument rule in discipline #6). Real case (2026-07): a retirement did exactly that, fixed all five references it found, and left a second full copy under .agents/skills/ — git-tracked, no retirement marker, a stale snapshot missing the newest rule — which the other tool would still load as live.claude plugin marketplace update <marketplace> # your push is not their cache
claude plugin install <skill>@<marketplace>
find -L ~/.claude/plugins/cache -path '*<skill>*' -name '*.md' # -L: installs are often symlinks
The -L is not optional — plugin caches frequently symlink into a source repo, and a bare find reports the files missing (see the instrument rule in discipline #6).superseded by <skill> stub rather than a bare deletion, and make every copy's stub byte-identical. Keep the YAML frontmatter — a SKILL.md without it may fail to load rather than fail informatively — but rewrite the description so the stub announces its own retirement instead of advertising the old triggers; otherwise it keeps winning the routing it no longer serves. The body needs only: where the capability went, and one line on why it moved.Identify the owner with the ownership test below (it applies here too: a project-level skill has no marketplace.json, but the project's git remote still tells you whose it is). When the owner is the person you are talking to, "consent" is one AskUserQuestion. When the owner is unreachable, harvest only — do not retire (which leaves both skills live and competing for the trigger, same end state as a declined retirement — see Coexistence & Precedence below).
If the owner declines to retire it, you now have two skills competing for the same trigger; that is the Coexistence & Precedence problem below, not a failure.
Search by capability vocabulary, not by skill name. That project skill would not have matched a name search for the new skill's title; it matched on the domain terms inside its body. Grep the candidate roots for the concepts the new skill will handle.
If something overlaps:
Deciding which bullet applies — whose skill is it? A filesystem hit does not carry ownership. Read the marketplace's .claude-plugin/marketplace.json owner field, or git remote -v in the containing repo; a hit under ~/.claude/plugins/marketplaces/ can just as easily be your own marketplace installed back onto your machine. A project-level skill has no marketplace.json, but its project's git remote answers the same question.
Two cases the probes get wrong or cannot answer, so check for them before trusting the result: a fork shows your own remote while the content is someone else's — treat it as third-party, because their upstream improvements still stop reaching you. And when there is no marketplace.json and no remote (a local-only project, a skill hand-copied into a global skills dir), the probes are silent rather than negative: ask the owner instead of guessing.
Only when nothing overlaps do you build standalone.
Why this check earns its place at the top: a real 2026-07 session spent a day getting a third-party docx engine to produce correct Chinese business documents, then reached for the wrapper-skill branch — which skips straight past Prior Art Research. The shape it was about to ship was a fresh skill re-carrying that engine's capability. The correct shape was a three-layer reference chain: third-party engine untouched → a thin increment skill holding the correct usage plus the verified generator script → the domain-workflow skill calling that increment. The user had to catch it twice before it landed, with the second correction being the sharper one: "don't copy an extra one — write the correct usage on top of theirs, and reference their skill; that's what skill-as-code means."
Choose the lowest tier that can falsify the changed behavior before taking a generic or specialized workflow branch. Classify by the concrete delta and its failure surface, not line count or request vocabulary: one changed destructive command can outrank a long prose cleanup, while a request to "optimize" an existing skill may still be one bounded correction. Before selecting a tier, list the rules, contracts, scripts, permissions, and outputs you actually intend to change. If that list is not known yet, inspect first and keep the classification provisional; uncertainty about scope is not evidence for Tier 3.
| Tier | Use when | Required evidence | Do not add by default |
|---|---|---|---|
| 1 — Targeted | This is an existing skill; no capability, trigger family, workflow branch, output contract, dependency, permission, or external-write behavior is added or materially changed; and the edit is exactly one of: (a) spelling/format-only with no behavior change, (b) a factual doc/config correction whose truth a direct authority decides, or (c) a bounded implementation repair that restores an explicit existing contract and whose repaired behavior a deterministic regression check covers. A clarification that can change agent behavior is not Tier 1 | For all three: run quick_validate, inspect the diff, and complete the existing-skill migration gate. Then use the matching evidence only: (a) exact readback/format check; (b) authoritative fact plus its narrow check; (c) explicit existing contract plus deterministic regression. Add discipline #5's one fresh reviewer only when its rule/contract/number threshold is crossed | Agent behavior replays, paired runs, baselines, graders, benchmark, viewer, eval files |
| 2 — Sampled behavior | This is an existing skill; the change affects agent behavior but adds no capability, trigger family, output contract, script behavior, dependency, permission, or external write; and 1–2 named examples with explicit acceptance criteria can exercise the whole changed behavior. A bounded correction to one existing routing or evidence-selection rule stays here even when it changes the chosen path | Run only those 1–2 representative with-skill replays plus the narrow deterministic checks and the one fresh-context review required by discipline #5 | Baselines, paired fan-out, variance analysis, benchmark, viewer, or eval files by default. An explicit request for them goes through the separate evidence-budget gate and does not reclassify the change |
| 3 — Broad / high-risk | Any of these is true: any new skill; any new or materially changed capability; broad cross-branch rewrite or methodology expansion; trigger/description optimization; a new workflow branch or materially changed output contract, script capability, dependency, or permission; high-risk automation or external writes; or the changed behavior itself spans 3+ distinct prompt classes, repeated trials, or materially different approaches | Run deterministic gates first, then add only the evidence needed for the named failure axes. The full paired pipeline below is available only after the separate heavy-eval authorization gate passes; Tier 3 by itself does not start it, and the same gate can authorize extra evidence at another tier | Automatic paired fan-out, graders, benchmark, or viewer based only on the Tier 3 label |
A tier describes risk and uncertainty; it does not authorize token spend or agent fan-out. Passing this gate changes the permitted evidence plan, not the tier. The generic paired baseline → grader → benchmark → viewer pipeline may run only when either:
For an existing-skill optimization, default to zero eval agents: run deterministic checks first, then at most one or two with-skill replays if behavior remains uncertain. Discipline #5's one fresh-context reviewer is a release gate, not permission to create a reviewer team. A token/cost-sensitivity instruction blocks the heavy pipeline until the user explicitly reverses it.
Before spawning more than one research, mining, eval, or grading agent, separate roles from execution units:
If a unit is neither a distinct role/output nor a necessary isolated arm/shard, do not spawn it.
Escalate when a lower tier exposes unresolved behavior or contradictory evidence. A user's request to cancel or de-escalate evaluation immediately stops already-launched paired eval agents, baselines, graders, aggregation, and viewer work. Keep the risk classification if it remains informative, but report only the evidence actually run and the axes left unchecked; do not describe an unrun heavy suite as automatically "required" by the label. Do not cancel discipline #5's single fresh-context reviewer when its rule/contract/number threshold is crossed, or any safety gate needed to prevent destructive or external effects. The mechanical existing-skill migration audit, public-skill sanitization, and any domain-specific safety gate also remain independent of this router.
Before committing to the generic skill-creation flow, check whether the session that led up to this point actually calls for the wrapper skill workflow instead. A wrapper skill is a companion that installs, configures, diagnoses, and repairs a pre-existing third-party CLI tool or skill package — code that someone else wrote and that the user has just spent a session getting to work on their machine.
Signals this applies (any two together are enough):
.zip, running npx / pip install / brew install, dealing with an official installer.Signals it does not apply (use the generic workflow above instead):
When the wrapper skill workflow applies, preserve the verification tier selected above. Creating a wrapper is creating a new skill, so it is Tier 3. Do not continue reading the generic authoring sections below; jump to workflows/wrapper-skill/workflow.md and follow that workflow end-to-end, including its verification protocol. It is a retrospective distillation workflow — its job is to mine the current conversation for the install flow, the bugs that were fixed, and the design decisions that were made, and to turn that mining output into a complete, self-contained wrapper skill that another user can install and benefit from without reliving the debugging session.
The wrapper skill workflow has its own architecture contract, code templates, and Tier 3 verification protocol — it replaces incompatible generic test-case mechanics because its output is a user's install state rather than a file that can be easily asserted on; it does not downgrade the work. Run the compatible generic steps selected by the evidence plan; generic paired-eval steps still require the heavy-eval authorization gate. Record which mechanics the specialized protocol replaced. The canonical reference implementation is the ima-copilot skill (at the root of the daymade/claude-code-skills repository — a bare relative link here already broke once when this skill moved into a suite, exactly as the cross-skill-reference rule below warns), a wrapper around the Tencent IMA skill distilled from a real session using this exact workflow.
Before committing to the generic skill-creation flow, check whether the session is actually asking to distill past conversations into a skill. This is useful when the user has been debugging, designing, or exploring a topic over multiple Claude Code / Codex sessions and wants to turn the accumulated know-how into reusable references/.
Explicit source intent is required. A long live conversation, a recently completed debugging task, or use skill-creator to optimize <skill> is not consent to open local history and is not a reason to enter this workflow. Use the live conversation directly for a normal update. Enter conversation-mining only when the user explicitly asks to mine/distill earlier local conversations or identifies particular prior sessions as source material.
Signals this applies (all must hold):
Signals it does not apply (use the generic workflow above instead):
memory/ rather than a reusable reference file.When the conversation-mining workflow applies, preserve the verification tier selected above. A new mined skill is Tier 3; enriching an existing skill stays at the selected tier only if it satisfies that tier's capability boundary. Do not continue reading the generic authoring sections below; jump to workflows/conversation-mining/workflow.md and follow that workflow end-to-end, including its verification protocol. It is a retrospective distillation workflow: it discovers approved local histories, redacts and partitions them, runs only the mining pass(es) justified by the corpus, and promotes reviewed candidates after validation.
The conversation-mining workflow has its own architecture contract, agent prompts, templates, and verification protocol. That protocol implements the selected tier's specialized mechanics; run the compatible generic steps selected by the evidence plan, keep heavy generic steps behind their authorization gate, and record any substitution. It is the canonical way to turn explicitly approved conversation history into a skill's reusable knowledge base.
Before committing to the generic flow, check whether the session is asking to extract the user's real preferences from a batch of finished artifacts they have endorsed — approved HTML report pages, generated documents, designs. This is the third distillation source, distinct from the two above: the material is products, not conversations, and the output is taste made executable (explicit principles, quantified parameters, vocabulary), not knowledge or install fixes.
Signals this applies (any one is enough):
Signals it does not apply: the source material is dialogue/corrections rather than endorsed products (use conversation-mining); the samples are not personally approved by the user (approval is the admission gate — ask first).
When it applies, preserve the verification tier selected above, then jump to workflows/artifact-corpus-distillation/workflow.md and follow its verification protocol. A new corpus-derived skill is Tier 3; adding a materially new decision capability to an existing skill is also Tier 3. The specialized protocol implements the selected tier's corpus mechanics and does not downgrade them; run the compatible generic steps selected by the evidence plan, keep heavy generic steps behind their authorization gate, and record any substitution. Its core discipline, which also applies any time you add material to an existing skill: cataloging ≠ distillation — registering a sample in a corpus table changes nothing about the skill's next run; ask of every addition "does this change a decision rule?", and do not declare a distillation session done while the answer is no for everything written (methodology Case 15). The workflow's spine: script-extracted quantitative comparison across ALL artifacts (≥3-artifact threshold per pattern, checked exception lists per claimed constant) → layered induction with evidence anchors → write to the decision-rule layer (separating invariants from register-dependent variables) → independent completeness audit (standing discipline #5) → regression audit.
The user's private methodology — their domain rules, workflow decisions, competitive edge — is what makes a skill valuable. No public repo can provide that. But the user shouldn't waste time reinventing infrastructure (API clients, auth flows, rate limiting) when mature tools exist. Prior art research finds building blocks for the infrastructure layer so the skill can focus on encoding the user's unique methodology.
Two axes, don't conflate them. This section sources the infrastructure layer (tools / MCPs / libraries / existing skills to reuse). The methodology layer has two inputs of its own: the user's private edge (theirs alone, un-retrievable) and the domain's established best-practices / science, which you retrieve into context by default per standing discipline #3. Finding the right tool does not discharge the second — a viz skill that adopts a charting library but never absorbs Cleveland/Bertin is still capped at your pretraining. Do both.
Search these channels in order. Research inline by default. Use subagents only after the heavy-eval/agent-budget gate above establishes genuinely independent unknowns; the public-source channels are not a default fan-out package.
| Priority | Channel | What to search | How |
|---|---|---|---|
| 1 | Live conversation or explicitly approved history | User's proven workflows, verified API patterns, corrections made during debugging | Use the current conversation directly. Search earlier local history only after the explicit-source gate above, then use the redacted conversation-mining path rather than ad-hoc grep |
| 2 | Local documents & SOPs | User's private methodology, runbooks, existing skills | Search project directory, ~/.claude/CLAUDE.md, ~/.claude/references/ |
| 3 | Installed plugins & MCPs | Already-integrated tools | Check ~/.claude/plugins/, parse installed_plugins.json; check ~/.claude.json for configured MCP servers |
| 4 | skills.sh | Community skills | WebFetch https://skills.sh/?q=<keyword> |
| 5 | Anthropic official plugins | Official/partner plugins | WebFetch https://github.com/anthropics/claude-plugins-official/tree/main/plugins and external_plugins directory |
| 6 | MCP servers on GitHub | Existing MCP servers for the same API | WebSearch "<service-name> MCP server site:github.com" |
| 7 | Official API docs | The target service's own documentation | WebSearch "<service-name> API documentation" or WebFetch the docs URL |
| 8 | npm / PyPI | SDK or CLI packages | npm search <keyword> or curl https://pypi.org/pypi/<name>/json |
Channels 1-3 surface the user's own proven patterns and existing integrations. Channels 4-8 find public infrastructure. The user's private SOP always takes precedence — public tools are building blocks, not replacements. In competitive domains (finance, trading, proprietary operations), the valuable methodology will never be public.
Bias toward merge/extend over create-new, and sweep EVERY skill root — not just ~/.claude. When channels 1-3 turn up an existing skill that overlaps the requested domain, the usual right move is to extend or merge into it — except when it lives in an unrelated project's working tree, where the direction reverses: harvest from it into the skill you are building rather than merging into it (see the project-level case in the extend-vs-create check above) (one real "new skill" task became "make the existing extractor the extract-phase of the new archiver"), not to ship a parallel skill that competes for the same triggers — two overlapping skills fight over triggering and confuse users. When searching, discover the install roots rather than recalling a list — use the SKILL.md sweep and its coverage self-check from the extend-vs-create section above (searching for a directory named skills misses source repos, marketplace clones and plugin caches entirely, because their skill directories are named after the skill). Run the coverage check rather than trusting this sentence: every project's own .claude/skills/ is the root a from-memory list reliably drops, because nothing outside that project references it. A skill the user already installed anywhere is the strongest prior art there is, and a project-local one is often the most mature: it was written against real work.
If a public MCP server or skill is found, clone it and verify — don't trust the README:
Decision matrix:
| Finding | Action |
|---|---|
| Mature MCP/SDK handles the infrastructure | Adopt it, build on top — install the MCP, then build the skill as a workflow layer encoding the user's methodology |
| Partial MCP or SDK exists | Extend — use for infrastructure, fill gaps in the skill |
| Public skill covers the same domain | Use for structural inspiration only — public skills in competitive domains are generic by definition. The user's edge is their private SOP |
| Complementary skill exists that provides a sub-capability of what you're building | Bundle it — copy the complementary skill's self-contained assets into your bundle and wire them up. Do NOT rely on the user having it pre-installed. See "Complementary Skills" below |
| Nothing public exists | Build from scratch — validate API access patterns work (auth, endpoints, proxy) before writing the full skill |
| Integration cost > build cost | Build it — a 2-hour custom implementation you own beats a "mature" tool with integration friction and upstream risk |
| User deliberately supersedes an installed skill (fork, hardened edition) | Ship it with a supersede kit — see "Coexistence & Precedence" below |
Merging into the existing skill is the default fix for overlap (above). But when the user deliberately ships a skill that overlaps an installed one — a fork of an official plugin, a hardened in-house edition — the two entries will sit in the skill list with similar descriptions and Claude will route between them at random. Resolve it, in escalating order: rename if the overlap is accidental; add a description tiebreaker ("supersedes X — when both appear, always use this one"); and for distributed forks, stamp a conditional supersede kit into the skill with scripts/generate_supersede_kit.py — a consent-based SessionStart routing hook that only ever installs on machines where the competitor is actually present, refuses to install elsewhere, and self-disables if either side disappears. Mechanics, decision table, SKILL.md sample wording, and sandbox verification: references/skill-precedence-and-coexistence.md. This skill dogfoods the same kit against the official skill-creator plugin (see "First: coexistence check" at the top).
The more common case: your new skill silently loses the trigger to the installed population, without any deliberate fork. A skill's domain (image generation, PDF handling, dashboards) is often already crowded with several installed skills, and a fresh skill can lose auto-routing to all of them. So verify triggering early — the build isn't done when the content is good. After a draft exists, fire a few realistic queries through claude -p and check the new skill actually WINS; if it doesn't, name the specific competitor it lost to (different queries often lose to different skills). Then know two things: (1) prose can't always win a crowded slot — the resolution ladder is rename → description tiebreaker/SUPERSEDES → manual invocation → SessionStart routing hook (structural; modifies global config, so requires the user's explicit consent, same discipline as --no-verify); and (2) the fix depends on who authored the competitor — competitors that are third-party → accept manual invocation or a routing hook; competitors that are your own → merge/consolidate them into one, don't keep two of your skills fighting for the same trigger. (The full resolution ladder lives in references/skill-precedence-and-coexistence.md — that file is the SSOT; the summaries here and above are pointers, don't extend them independently.) Documenting the chosen path (e.g. an "Activation" note saying "invoke manually, competitors are third-party") stops the next session from re-litigating it. (methodology Case 13)
When building a skill that touches a domain with an existing complementary skill, you have two choices:
Rule: if a sub-capability your skill needs is provided by another installable skill, bundle it. This is especially important for:
statusline-generator's generate_statusline.sh)Example: claude-switch-models-setup manages multiple Claude Code profiles. Each profile needs a statusline. The statusline-generator skill provides generate_statusline.sh. Rather than depending on the user running statusline-generator first, the profile setup skill bundles statusline.sh and wires it into each new profile during claude-profiles-init. The two skills remain independently useful, but the wrapper skill works standalone.
Anti-pattern: writing "run other-skill's installer first" in your SKILL.md. That pushes the dependency to the user and creates a fragile install order. Bundle instead.
After research completes, present findings via AskUserQuestion:
Research complete for "[skill-name]". Here's what I found:
[1-2 sentence summary of what exists publicly]
RECOMMENDATION: [ADOPT / EXTEND / BUILD] because [one-line reason]
Options:
A) Adopt [tool/MCP X] for infrastructure, build methodology layer on top (Recommended)
B) Extend [partial tool Y] — use what works, fill gaps in the skill
C) Build from scratch — nothing found matches well enough
D) Show me the detailed findings before I decide
When in doubt, bias toward adopting mature infrastructure for the plumbing layer and building custom logic for the methodology layer — that's where the value lives.
Proactively ask questions about edge cases, input/output formats, example files, success criteria, and dependencies. Wait to write test prompts until you've got this part ironed out.
Check available MCPs when useful for research (searching docs, finding similar skills, looking up best practices). Research inline by default. Use a subagent only for a distinct unresolved question, and never turn tool availability into automatic parallel fan-out. Come prepared with context to reduce burden on the user.
Based on the user interview, fill in these components:
name: Skill identifier
description: When to trigger, what it does. This is the primary triggering mechanism - include both what the skill does AND specific contexts for when to use it. All "when to use" info goes here, not in the body. Note: currently Claude has a tendency to "undertrigger" skills -- to not use them when they'd be useful. To combat this, please make the skill descriptions a little bit "pushy". So for instance, instead of "How to build a simple fast dashboard to display internal Anthropic data.", you might write "How to build a simple fast dashboard to display internal Anthropic data. Make sure to use this skill whenever the user mentions dashboards, data visualization, internal metrics, or wants to display any kind of company data, even if they don't explicitly ask for a 'dashboard.'"
Budget it: the description has a hard 1024-character ceiling, and validation rejects anything longer. This is in direct tension with the "pushy" advice above — every trigger phrase you add for coverage spends budget — so measure before you expand rather than after: len(description), not vibes. The trap is not the first draft (which is rarely near the limit) but the update years later that adds triggers for newly-covered scope: a mature description often sits within a few dozen characters of the ceiling, at which point adding a trigger is zero-sum — you are deleting an existing one to pay for it. Make that trade consciously and say so in the commit, because a silently-dropped trigger phrase is a real narrowing of when the skill fires, and nobody will notice until it stops triggering for someone. (Seen in practice: an update added triggers for a newly-covered failure mode, pushed the description to 1280 characters, and took two rounds of compression to reach 1003 — the price was three pre-existing trigger phrases, which is a decision that deserved to be explicit rather than discovered while fighting a validator.) When you must cut, prefer phrases whose scenario is still reachable through a synonym or a sibling phrase, keep the ones with no other route in, and remember that qualifiers inside the prose ("on platform X and Y", parenthetical enumerations) are usually cheaper to drop than a distinct trigger phrase — the prose is re-derivable from the body, a trigger phrase is not.
compatibility: Required tools, dependencies (optional, rarely needed)
the rest of the skill :)
skill-name/
├── SKILL.md (required)
│ ├── YAML frontmatter (name, description required)
│ └── Markdown instructions
└── Bundled Resources (optional)
├── scripts/ - Executable code for deterministic/repetitive tasks
├── references/ - Docs loaded into context as needed
└── assets/ - Files used in output (templates, icons, fonts)
All frontmatter fields except description are optional. Configure skill behavior using these fields between --- markers:
---
name: my-skill
description: What this skill does and when to use it. Use when...
context: fork
agent: general-purpose
argument-hint: "[topic]"
---
| Field | Required | Description |
|---|---|---|
name | No | Display name for the skill. If omitted, uses the directory name. Lowercase letters, numbers, and hyphens only (max 64 characters). |
description | Recommended | What the skill does and when to use it. Claude uses this to decide when to apply the skill. If omitted, uses the first paragraph of markdown content. |
context | No | Set to fork to run in a forked subagent context. See "Inline vs Fork: Critical Decision" below — choosing wrong breaks your skill. |
agent | No | Which subagent type to use when context: fork is set. Options: Explore, Plan, general-purpose, or custom agents from .claude/agents/. Default: general-purpose. |
disable-model-invocation | No | Set to true to prevent Claude from automatically loading this skill. Use for workflows you want to trigger manually with /name. Default: false. |
user-invocable | No | Set to false to hide from the / menu. Use for background knowledge users shouldn't invoke directly. Default: true. |
allowed-tools | No | Pre-approved tools list. Recommendation: Do NOT set this field. Omitting it gives the skill full tool access governed by the user's permission settings. Setting it restricts the skill's capabilities unnecessarily. |
model | No | Model to use when this skill is active. |
argument-hint | No | Hint shown during autocomplete to indicate expected arguments. Example: [issue-number] or [filename] [format]. |
hooks | No | Hooks scoped to this skill's lifecycle. Example: hooks: { pre-invoke: [{ command: "echo Starting" }] }. See Claude Code Hooks documentation. |
Special placeholder: $ARGUMENTS in skill content is replaced with text the user provides after the skill name. For example, /deep-research quantum computing replaces $ARGUMENTS with quantum computing.
This is the most important architectural decision when designing a skill. Choosing wrong will silently break your skill's core capabilities.
CRITICAL CONSTRAINT: Subagents cannot spawn other subagents. A skill running with context: fork (as a subagent) CANNOT:
Decision guide:
| Your skill needs to... | Use | Why |
|---|---|---|
| Orchestrate parallel agents (Task tool) | Inline (no context) | Subagents can't spawn subagents |
| Call other skills (Skill tool) | Inline (no context) | Subagents can't invoke skills |
| Run Bash commands for external CLIs | Inline (no context) | Full tool access in main context |
| Perform a single focused task (research, analysis) | Fork (context: fork) | Isolated context, clean execution |
| Provide reference knowledge (coding conventions) | Inline (no context) | Guidelines enrich main conversation |
| Be callable BY other skills | Fork (context: fork) | Must be a subagent to be spawned |
Example: Orchestrator skill (MUST be inline):
---
name: product-analysis
description: Multi-path parallel product analysis with cross-model synthesis
---
# Orchestrates parallel agents — inline is REQUIRED
1. Auto-detect available tools (which codex, etc.)
2. Launch 3-5 Task agents in parallel (Explore subagents)
3. Optionally invoke /competitors-analysis via Skill tool
4. Synthesize all results
Example: Specialist skill (fork is correct):
---
name: deep-research
description: Research a topic thoroughly using multiple sources
context: fork
agent: Explore
---
Research $ARGUMENTS thoroughly:
1. Find relevant files using Glob and Grep
2. Read and analyze the code
3. Summarize findings with specific file references
Example: Reference skill (inline, no task):
---
name: api-conventions
description: API design patterns for this codebase
---
When writing API endpoints:
- Use RESTful naming conventions
- Return consistent error formats
Skills should be orthogonal: each skill handles one concern, and they combine through composition.
Pattern: Orchestrator (inline) calls Specialist (fork)
product-analysis (inline, orchestrator)
├─ Task agents for parallel exploration
├─ Skill('competitors-analysis', 'X') → fork subagent
└─ Synthesizes all results
competitors-analysis (fork, specialist)
└─ Single focused task: analyze one competitor codebase
Rules for composability:
context: fork) to use Task/Skill toolscontext: fork to run in isolated subagent contextBeyond orchestrator/specialist composition, skills often form sequential pipelines where one skill's output is the next skill's input. Each skill should proactively suggest the logical next step after completing its work.
Pattern: "Next Step" section at the end of SKILL.md
## Next Step: [Action Description]
After [this skill completes], suggest the natural next skill:
\```
[Summary of what was just accomplished].
Options:
A) [Next skill] — [one-line reason] (Recommended)
B) [Alternative skill] — [when this is better]
C) No thanks — [the current output is sufficient]
\```
Real-world pipeline examples:
youtube-downloader → asr-transcribe-to-text → transcript-fixer → meeting-minutes-taker → pdf-creator
deep-research → fact-checker → ppt-creator
doc-to-markdown → docs-cleaner
claude-code-history-files-finder → continue-claude-work
Rules for pipeline handoff:
When to add a handoff: Ask "does this skill's output commonly become another skill's input?" If yes, add a "Next Step" section. If the connection is rare or forced, don't add one.
Anti-pattern: Chaining skills that don't share a natural data flow. pdf-creator → youtube-downloader makes no sense. The pipeline must follow the user's actual workflow.
Never add manual flags for capabilities that can be auto-detected. Instead of requiring users to pass --with-codex or --verbose, detect capabilities at runtime:
# Good: Auto-detect and inform
Step 0: Check available tools
- `which codex` → If found, inform user and enable cross-model analysis
- `ls package.json` → If found, tailor prompts for Node.js project
- `which docker` → If found, enable container-based execution
# Bad: Manual flags
argument-hint: [scope] [--with-codex] [--docker] [--verbose]
Principle: Capabilities auto-detect, user decides scope. A skill should discover what it CAN do and act accordingly, not require users to remember what tools are installed.
| Frontmatter | You can invoke | Claude can invoke | Subagents can use |
|---|---|---|---|
| (default) | Yes | Yes | No (runs inline) |
context: fork | Yes | Yes | Yes |
disable-model-invocation: true | Yes | No | No |
context: fork + disable-model-invocation: true | Yes | No | Yes (when explicitly delegated) |
Skills use a three-level loading system:
Key patterns:
Domain organization: When a skill supports multiple domains/frameworks, organize by variant:
cloud-deploy/
├── SKILL.md (workflow + selection)
└── references/
├── aws.md
├── gcp.md
└── azure.md
Claude reads only the relevant reference file.
This goes without saying, but skills must not contain malware, exploit code, or any content that could compromise system security. A skill's contents should not surprise the user in their intent if described. Don't go along with requests to create misleading skills or skills designed to facilitate unauthorized access, data exfiltration, or other malicious activities. Things like a "roleplay as an XYZ" are OK though.
Prefer using the imperative form in instructions.
Defining output formats - You can do it like this:
## Report structure
ALWAYS use this exact template:
# [Title]
## Executive summary
## Key findings
## Recommendations
Examples pattern - It's useful to include examples. You can format them like this (but if "Input" and "Output" are in the examples you might want to deviate a little):
## Commit message format
**Example 1:**
Input: Added user authentication with JWT tokens
Output: feat(auth): implement JWT-based authentication
Usability patterns worth building into a skill - These four structural elements repeatedly turned a "works but confusing" skill into one users could actually drive — they were the concrete enhancements that made a heavily-used skill usable, so reach for them when a skill has modes, runs commands, or can be re-run:
Try to explain to the model why things are important in lieu of heavy-handed musty MUSTs. Use theory of mind and try to make the skill general and not super-narrow to specific examples. Start by writing a draft and then look at it with fresh eyes and improve it.
Keep factual dates — they tell readers when information was verified. A skill about Suno v5.5 should say "Suno v5.5 (March 2026)" because without the date, future readers can't judge if the information is still current. Removing dates makes things worse, not better.
What to avoid is conditional logic based on dates ("if before August 2025, use the old API") — that becomes wrong the moment the date passes and nobody updates it.
Rules:
scripts/)Executable code (Python/Bash/etc.) for tasks that require deterministic reliability or are repeatedly rewritten.
scripts/rotate_pdf.py for PDF rotation tasks~/.<skill-name>/) with its own backup — never inside the skill directory. Skill installs are wiped and re-created on every update and suite migration; a home-relative store survives them untouched. This is how a dictionary-accumulating skill survived a full suite migration with zero user data lossreferences/)Documentation and reference material intended to be loaded as needed into context to inform Claude's process and thinking.
references/finance.md for financial schemas, references/mnda.md for company NDA templateassets/)Files not intended to be loaded into context, but rather used within the output Claude produces.
assets/logo.png for brand assets, assets/slides.pptx for PowerPoint templatescomponents subfolder under assets/ holds user-approved verbatim-embed fragments with frozen behavior contracts and a registry reference — see the Component-shelf check in Step 4Decide the destination before applying any of this. Everything below describes what
breaks when a skill ships to strangers. For a skill that lives in the author's own private
repo, the same "violations" are usually why it works — a real absolute path is what makes
the script runnable, a real account in a template is what saves the next run from re-filling
it. quick_validate auto-detects this (it asks gh whether the containing repo is private)
and downgrades portability/identifier findings to notes there; --audience=public forces the
strict pass when a private skill is being prepared for release.
In a private skill, these findings are the owner's call, not yours. Do not placeholder a
real path, rewrite a hardcoded credential, or "sanitize" an example without asking — you will
break a working tool to satisfy a rule written for a destination it was never going to. If
you think something should change, say what you found and let the owner decide. (The design
precedent is npm's "private": true: a declared destination that changes what the tooling
enforces, added because people kept publishing things by accident.)
CRITICAL for skills intended for public distribution — these must not contain user-specific or company-specific information:
~/.claude/skills/scripts/example.py, references/guide.md)<workspace>/project, <user>, <organization>)~/.claude/skills/ when the passage is about those paths (teaching material, not a hardcoded dependency)Cross-skill references: a bare relative path always means "inside this skill's own bundle" — validators and readers both treat it that way, so a bare path pointing at another skill's file fails validation and misleads readers. When pointing at another skill, name the owner in prose ("marketplace-dev's cache-and-source-patterns reference") and invoke skills by their namespaced name (/suite-name:skill-name, not a bare /skill-name). Bare cross-references break silently when skills move between suites — one suite migration left 21 broken cross-references across two cleanup passes because of this.
CRITICAL: Skills should NOT contain version history or version numbers in SKILL.md:
## Version, ## Changelog) in SKILL.mdplugins[].versionFilenames must be self-explanatory without reading contents.
Pattern: <content-type>_<specificity>.md
Examples:
commands.md, cli_usage.md, reference.mdscript_parameters.md, api_endpoints.md, database_schema.mdTest: Can someone understand the file's contents from the name alone?
Two carve-outs: hyphenated names are as good as underscored ones (the separator was never the point — self-explanation is); and files inside a named workflow directory (workflows/<name>/workflow.md, patterns.md) are directory-qualified — the directory supplies the specificity, and renaming them would break the parallel structure across workflows.
Anthropic has written skill authoring best practices — retrieve it before you create or update any skills: https://platform.claude.com/docs/en/agents-and-tools/agent-skills/best-practices.md
Also read references/skill-development-methodology.md before starting — it covers the full development process with prior art research, counter review, and real failure case studies. The two references are complementary: the Anthropic doc covers principles, the methodology covers process.
Enter this section only when the heavy-eval authorization gate passes. Risk tier alone neither authorizes nor forbids this evidence; an explicit full-pipeline request does not reclassify the underlying change. Do not use it merely because a SKILL.md changed. A specialized workflow follows its substitution contract declared above.
After writing the skill draft, come up with 2-3 realistic test prompts — the kind of thing a real user would actually say. For skills that act on live systems (a running service, a logged-in client, production data), give each test prompt an explicit side-effect budget — e.g. "probe read-only and conclude; do NOT execute the download / drive the UI." An eval that mutates a live environment while "just testing" is a real action, not a test. Present them via AskUserQuestion:
Skill draft is ready. Here are [N] test cases I'd like to run:
1. "[test prompt 1]" — tests [what aspect]
2. "[test prompt 2]" — tests [what aspect]
3. "[test prompt 3]" — tests [what aspect]
Each test runs the skill + a baseline (no skill) for comparison.
Estimated time: ~[X] minutes total.
RECOMMENDATION: Run all [N] test cases now.
Options:
A) Run all test cases (Recommended)
B) Run test cases, but let me modify them first
C) Add more test cases before running
D) Skip testing — the skill looks good enough to ship
Save test cases to evals/evals.json. Don't write assertions yet — just the prompts. You'll draft assertions in the next step while the runs are in progress.
{
"skill_name": "example-skill",
"evals": [
{
"id": 1,
"prompt": "User's task prompt",
"expected_output": "Description of expected result",
"files": []
}
]
}
See references/eval_pipeline_schemas.md for the full schema (including the assertions field, which you'll add later).
Run this section only after the heavy-eval authorization gate passes. The risk tier remains whatever the changed behavior warrants. Execute the pipeline in decision-bearing stages and stop when the uncertainty or requested benchmark deliverable is resolved; do not pre-spawn downstream graders, aggregation, or viewer work. A user cancellation or de-escalation stops the heavy pipeline immediately. Do not use it without authorization or mechanically add generic mechanics that a specialized workflow explicitly replaces, and do not use /skill-test or any other testing skill.
Put results in <skill-name>-workspace/ as a sibling to the skill directory. Within the workspace, organize results by iteration (iteration-1/, iteration-2/, etc.) and within that, each test case gets a directory (eval-0/, eval-1/, etc.). Don't create all of this upfront — just create directories as you go.
For each approved test case, run one with-skill sample and its baseline under the same prompt and side-effect budget. These two arms intentionally share one failure axis but require isolated contexts; they are necessary experimental units, not extra reviewer roles. State the total arms and capped concurrency before launch. Run serially by default, and never exceed the authorized unit count.
With-skill run:
Execute this task:
- Skill path: <path-to-skill>
- Task: <eval prompt>
- Input files: <eval files if any, or "none">
- Save outputs to: <workspace>/iteration-<N>/eval-<ID>/with_skill/outputs/
- Outputs to save: <what the user cares about — e.g., "the .docx file", "the final CSV">
Baseline run (same prompt, but the baseline depends on context):
without_skill/outputs/.old_skill/outputs/. If no pre-edit snapshot exists, stop and reconstruct an authoritative baseline from Git before continuing; never use the already-edited tree as the old baseline. Know what this comparison can resolve: it measures only this round's delta. If the capability you most want to verify already exists in the pre-edit snapshot — a sibling session can commit exactly that fix just before you start — the with/old A/B has zero resolving power for it; pick an older ref as the baseline when that's the capability under test.Write an eval_metadata.json for each test case (assertions can be empty for now). Give each eval a descriptive name based on what it's testing — not just "eval-0". Use this name for the directory too. If this iteration uses new or modified eval prompts, create these files for each new eval directory — don't assume they carry over from previous iterations.
{
"eval_id": 0,
"eval_name": "descriptive-name-here",
"prompt": "The user's task prompt",
"assertions": []
}
Don't just wait for the runs to finish — you can use this time productively. Draft quantitative assertions for each test case and explain them to the user. If assertions already exist in evals/evals.json, review them and explain what they check.
Good assertions are objectively verifiable and have descriptive names — they should read clearly in the benchmark viewer so someone glancing at the results immediately understands what each one checks. Write assertions against the intent, not a literal tool path — "voice content survives into the answer", not "calls the sanctioned reader script". A run that reaches the intent through a different sanctioned route (e.g. reading an archive that already has the transcripts inlined) passes, and grading it as a literal-path failure manufactures a false negative you'll then "fix" in the wrong place. Subjective skills (writing style, design quality) are better evaluated qualitatively — don't force assertions onto things that need human judgment; their real verification paths (historical-task replay, production-as-eval with a write-back habit, render + human review) are listed under question 4 of "Capture Intent".
Update the eval_metadata.json files and evals/evals.json with the assertions once drafted. Also explain to the user what they'll see in the viewer — both the qualitative outputs and the quantitative benchmark.
When each subagent task completes, you receive a notification containing total_tokens and duration_ms. Save this data immediately to timing.json in the run directory:
{
"total_tokens": 84852,
"duration_ms": 23332,
"total_duration_seconds": 23.3
}
This is the only opportunity to capture this data — it comes through the task notification and isn't persisted elsewhere. Process each notification as it arrives rather than trying to batch them.
Once all runs are done:
Grade each run — spawn a grader subagent (or grade inline) that reads agents/grader.md and evaluates each assertion against the outputs. Save results to grading.json in each run directory. The grading.json expectations array must use the fields text, passed, and evidence (not name/met/details or other variants) — the viewer depends on these exact field names. For assertions that can be checked programmatically, write and run a script rather than eyeballing it — scripts are faster, more reliable, and can be reused across iterations. But objective grep/script assertions cut both ways (same-word-different-meaning false hits, wording-difference misses), so benchmark pass-rate is a signal, not a verdict: spot-check what each assertion actually matched, and watch for a baseline run that reveals a factual error in the skill itself (the "wait, the data IS in the API" moment). See methodology §5.3–5.6 + §6.4.
Aggregate into benchmark — run the aggregation script from the skill-creator directory:
python -m scripts.aggregate_benchmark <workspace>/iteration-N --skill-name <name>
This produces benchmark.json and benchmark.md with pass_rate, time, and tokens for each configuration, with mean +/- stddev and the delta. If generating benchmark.json manually, see references/eval_pipeline_schemas.md for the exact schema the viewer expects.
Put each with_skill version before its baseline counterpart.
Do an analyst pass — read the benchmark data and surface patterns the aggregate stats might hide. See agents/analyzer.md (the "Analyzing Benchmark Results" section) for what to look for — things like assertions that always pass regardless of skill (non-discriminating), high-variance evals (possibly flaky), and time/token tradeoffs.
Launch the viewer with both qualitative outputs and quantitative data:
nohup python <skill-creator-path>/eval-viewer/generate_review.py \
<workspace>/iteration-N \
--skill-name "my-skill" \
--benchmark <workspace>/iteration-N/benchmark.json \
> /dev/null 2>&1 &
VIEWER_PID=$!
For iteration 2+, also pass --previous-workspace <workspace>/iteration-<N-1>.
If the backgrounded viewer strands itself: the process stays alive but nothing is listening — check with lsof -a -p $VIEWER_PID -iTCP -sTCP:LISTEN (empty) or curl the URL (fails); "no log output" is NOT a usable signal here because the launch line above redirects it to /dev/null. Kill it and fall back to --static rather than re-launching the same way.
Cowork / headless environments: If webbrowser.open() is not available or the environment has no display, use --static <output_path> to write a standalone HTML file instead of starting a server. Feedback will be downloaded as a feedback.json file when the user clicks "Submit All Reviews". After download, copy feedback.json into the workspace directory for the next iteration to pick up.
Note: please use generate_review.py to create the viewer; there's no need to write custom HTML.
Results are ready! I've opened the eval viewer in your browser.
- "Outputs" tab: click through each test case, leave feedback in the textbox
- "Benchmark" tab: quantitative comparison (pass rates, timing, tokens)
Take your time reviewing. When you're done, come back here.
RECOMMENDATION: Review the Outputs tab first — your qualitative feedback drives the next iteration more than the numbers do.
Options:
A) I've finished reviewing — read my feedback and improve the skill
B) I have questions about the results before giving feedback
C) Results look good enough — skip iteration, let's package the skill
D) Results need major rework — let's discuss before iterating
The "Outputs" tab shows one test case at a time:
The "Benchmark" tab shows the stats summary: pass rates, timing, and token usage for each configuration, with per-eval breakdowns and analyst observations.
Navigation is via prev/next buttons or arrow keys. When done, they click "Submit All Reviews" which saves all feedback to feedback.json.
When the user tells you they're done, read feedback.json:
{
"reviews": [
{"run_id": "eval-0-with_skill", "feedback": "the chart is missing axis labels", "timestamp": "..."},
{"run_id": "eval-1-with_skill", "feedback": "", "timestamp": "..."},
{"run_id": "eval-2-with_skill", "feedback": "perfect, love this", "timestamp": "..."}
],
"status": "complete"
}
Empty feedback means the user thought it was fine. Focus your improvements on the test cases where the user had specific complaints.
Kill the viewer server when you're done with it:
kill $VIEWER_PID 2>/dev/null
This is the heart of the loop. Improve from the evidence plan: authoritative facts and deterministic checks for Tier 1, 1–2 named behavior replays for Tier 2, or user-reviewed paired results when the separate heavy-eval gate authorizes them at any tier. Do not import paired-eval artifacts into the default Tier 1/2 path without that authorization.
Generalize from the feedback. The big picture thing that's happening here is that we're trying to create skills that can be used a million times (maybe literally, maybe even more who knows) across many different prompts. Here you and the user are iterating on only a few examples over and over again because it helps move faster. The user knows these examples in and out and it's quick for them to assess new outputs. But if the skill you and the user are codeveloping works only for those examples, it's useless. Rather than put in fiddly overfitty changes, or oppressively constrictive MUSTs, if there's some stubborn issue, you might try branching out and using different metaphors, or recommending different patterns of working. It's relatively cheap to try and maybe you'll land on something great.
Keep the prompt lean without deleting the contract. Remove things that aren't pulling their weight, but treat every deletion from an existing skill as a regression candidate until the old-vs-new audit classifies it. Move detailed but reusable behavior into a directly linked reference; do not leave it only in evals, a changelog, or your memory. Read the transcripts, not just final outputs—if the skill causes unproductive work, simplify the instruction and rerun the old capability cases rather than assuming fewer words means better behavior.
Explain the why. Try hard to explain the why behind everything you're asking the model to do. Today's LLMs are smart. They have good theory of mind and when given a good harness can go beyond rote instructions and really make things happen. Even if the feedback from the user is terse or frustrated, try to actually understand the task and why the user is writing what they wrote, and what they actually wrote, and then transmit this understanding into the instructions. If you find yourself writing ALWAYS or NEVER in all caps, or using super rigid structures, that's a yellow flag — if possible, reframe and explain the reasoning so that the model understands why the thing you're asking for is important. That's a more humane, powerful, and effective approach.
Look for repeated work — in the eval transcripts AND in whatever conversation the skill was distilled from. Read the transcripts from the test runs and notice if the subagents all independently wrote similar helper scripts or took the same multi-step approach to something. If all 3 test cases resulted in the subagent writing a create_docx.py or a build_chart.py, that's a strong signal the skill should bundle that script. Write it once, put it in scripts/, and tell the skill to use it. This saves every future invocation from reinventing the wheel. The same signal hides in a source conversation you distilled a skill from — code that session wrote even once is code every future run must rewrite; don't wait for eval runs to prove the repetition (skills whose eval loop is skipped never get that proof — the Scripts check in Step 4 of the creation process is the catch-point for those).
Fold corrections back verbatim — same session, both levels. For taste-calibrated skills the user's corrections ARE the eval set, but only if they land where a future run will read them. Two properties make the write-back converge: (a) record the correction verbatim, not paraphrased — exact words carry calibration signal a summary flattens ("绝对禁止这种东西" teaches a hard boundary; "user prefers fewer jumps" does not). Quote the words inside the rule they correct, with a date. (b) Write back in the same session the correction happens, at both levels — fix the artifact AND the skill's rule/reference/component; a correction that only fixes the artifact is invisible to every future run, and one deferred to "later" usually never lands. While writing it back, check whether the skill's own text taught the anti-pattern just banned — a correction often falsifies an existing instruction, and leaving the old advice standing guarantees recurrence (real case: a decision-page contract advised jump-style "goto anchors to the referenced figure"; the user banned exactly that, so the write-back had to amend the old sentence, not just add a new rule beside it). When the corrected thing is an interaction fragment, the write-back's final step is shelf promotion — see the Component-shelf check in Step 4.
This task is pretty important (we are trying to create billions a year in economic value here!) and your thinking time is not the blocker; take your time and really mull things over. I'd suggest writing a draft revision and then looking at it anew and making improvements. Really do your best to get into the head of the user and understand what they want and need.
For Tier 1, apply an unambiguous evidence-backed correction directly; ask only when the evidence leaves a real choice. For Tier 2 or Tier 3, when user feedback exposes a meaningful design fork, present the improvement plan via AskUserQuestion:
I've read the feedback from [N] test cases. [X] had specific complaints, [Y] looked good.
Key issues:
- [Issue 1]: [plain-language summary]
- [Issue 2]: [plain-language summary]
RECOMMENDATION: [strategy] because [reason]
Options:
A) Iterative refinement — targeted fixes for the specific issues above (Recommended)
B) Structural redesign — the core approach needs rethinking (reclassifies Tier 1/2 work to Tier 3 before changing it)
C) Bundle a script — I noticed all test runs independently wrote similar code for [X] (reclassifies Tier 1/2 work to Tier 3 before adding the capability)
D) Expand test set first — add [N] more test cases to avoid overfitting (authorizes only the named extra evidence; risk tier still follows the changed behavior)
Selecting B or C may change the risk tier because it changes the implementation scope; selecting D does not. Each option authorizes only the named scope/evidence change. It does not authorize paired baselines, graders, benchmarks, a viewer, or additional roles unless those are named and the separate heavy-eval/fan-out gate passes.
After improving the skill:
quick_validate, diff inspection, and the migration gate; then re-run only the matching subtype evidence — (a) exact readback/format check, (b) authoritative fact plus its narrow check, or (c) explicit existing contract plus deterministic regression. Do not create an iteration workspace unless a separate paired plan is authorized.iteration-<N+1>/ directory, including baseline runs. For a new skill, the baseline is always without_skill; for an existing skill, the immutable original pre-edit version remains the preservation baseline for every iteration. An immediately previous iteration may supplement but never replace the original baseline.--previous-workspace pointing at the previous iteration; specialized workflows use their declared reviewer mechanics.A user-requested cancellation or de-escalation remains in force for the rest of the task without changing its classification. Do not restart paired evals, baselines, graders, aggregation, or viewer work unless the user explicitly re-authorizes that evidence plan.
At the end of each separately authorized generic paired iteration, use AskUserQuestion as a checkpoint:
Iteration [N] complete. Results: [pass_rate]% assertions passing, [delta vs previous].
RECOMMENDATION: [Continue / Accept / Revert] because [one-line reason from the delta and remaining feedback].
Options:
A) Continue iterating — I see more room for improvement
B) Accept this version — it's good enough, let's move to packaging
C) Revert to previous iteration — this round made things worse
D) Run blind comparison — rigorously compare this version vs the previous one
Keep going until:
For situations where you want a more rigorous comparison between two versions of a skill (e.g., the user asks "is the new version actually better?"), there's a blind comparison system. Read agents/comparator.md and agents/analyzer.md for the details. The basic idea is: give two outputs to an independent agent without telling it which is which, and let it judge quality. Then analyze why the winner won.
This is optional, requires subagents, and most users won't need it. The human review loop is usually sufficient.
The description field in SKILL.md frontmatter is the primary mechanism that determines whether Claude invokes a skill. After creating or improving a skill, offer to optimize the description for better triggering accuracy.
Create 20 eval queries — a mix of should-trigger and should-not-trigger. Save as JSON:
[
{"query": "the user prompt", "should_trigger": true},
{"query": "another prompt", "should_trigger": false}
]
The queries must be realistic and something a Claude Code or Claude.ai user would actually type. Not abstract requests, but requests that are concrete and specific and have a good amount of detail. For instance, file paths, personal context about the user's job or situation, column names and values, company names, URLs. A little bit of backstory. Some might be in lowercase or contain abbreviations or typos or casual speech. Use a mix of different lengths, and focus on edge cases rather than making them clear-cut (the user will get a chance to sign off on them).
Bad: "Format this data", "Extract text from PDF", "Create a chart"
Good: "ok so my boss just sent me this xlsx file (its in my downloads, called something like 'Q4 sales final FINAL v2.xlsx') and she wants me to add a column that shows the profit margin as a percentage. The revenue is in column C and costs are in column D i think"
For the should-trigger queries (8-10), think about coverage. You want different phrasings of the same intent — some formal, some casual. Include cases where the user doesn't explicitly name the skill or file type but clearly needs it. Throw in some uncommon use cases and cases where this skill competes with another but should win.
For the should-not-trigger queries (8-10), the most valuable ones are the near-misses — queries that share keywords or concepts with the skill but actually need something different. Think adjacent domains, ambiguous phrasing where a naive keyword match would trigger but shouldn't, and cases where the query touches on something the skill does but in a context where another tool is more appropriate.
The key thing to avoid: don't make should-not-trigger queries obviously irrelevant. "Write a fibonacci function" as a negative test for a PDF skill is too easy — it doesn't test anything. The negative cases should be genuinely tricky.
Present the eval set to the user for review using the HTML template:
assets/eval_review.html__EVAL_DATA_PLACEHOLDER__ → the JSON array of eval items (no quotes around it — it's a JS variable assignment)__SKILL_NAME_PLACEHOLDER__ → the skill's name__SKILL_DESCRIPTION_PLACEHOLDER__ → the skill's current description/tmp/eval_review_<skill-name>.html) and open it: open /tmp/eval_review_<skill-name>.html~/Downloads/eval_set.json — check the Downloads folder for the most recent version in case there are multiple (e.g., eval_set (1).json)This step matters — bad eval queries lead to bad descriptions.
Tell the user: "This will take some time — I'll run the optimization loop in the background and check on it periodically."
Save the eval set to the workspace, then run in the background:
python -m scripts.run_loop \
--eval-set <path-to-trigger-eval.json> \
--skill-path <path-to-skill> \
--model <model-id-powering-this-session> \
--max-iterations 5 \
--verbose
Use the model ID from your system prompt (the one powering the current session) so the triggering test matches what the user actually experiences.
While it runs, periodically tail the output to give the user updates on which iteration it's on and what the scores look like.
This handles the full optimization loop automatically. It splits the eval set into 60% train and 40% held-out test, evaluates the current description (running each query 3 times to get a reliable trigger rate), then calls Claude to propose improvements based on what failed. It re-evaluates each new description on both train and test, iterating up to 5 times. When it's done, it opens an HTML report in the browser showing the results per iteration and returns JSON with best_description — selected by test score rather than train score to avoid overfitting.
The loop self-aborts after iteration 1 if it detects total silence — you don't have to catch this by hand. This is a code-level guard in run_loop.py, not just advice, and it distinguishes two causes of "iteration 1 came back with zero triggers on every should-trigger query":
exit_reason: "infra_error: ..." — some query executions (should-trigger or not-should-trigger) raised exceptions (claude CLI not on PATH, timeout too short, network down) rather than cleanly returning "no trigger." Checked first, and deliberately fires on any nonzero error count, even a single flaky run out of dozens — a crash, however rare, is a more specific and actionable lead than "nothing fired," and the fix is environmental, not a description rewrite. The ratio in the message (e.g. 3/15) is the read on severity: a large fraction means "stop, fix your environment"; a small fraction alongside a lot of clean 0-trigger runs means the environment probably has a minor flake worth checking and the description may genuinely be bad — check both. Check stderr for Warning: query failed lines either way.exit_reason: "degenerate_harness: ..." — checked only once the branch above rules out any execution errors, so this means every should-trigger and not-should-trigger query actually ran and still fired zero times (this is what "precision=100%" via a zero-denominator default actually means: not "perfect," but "nothing to divide"). The probe genuinely measures nothing — go diagnose competitor collision or a low-threshold domain (below) before touching the description at all.Both checks run only against iteration 1, and only when zero should-trigger queries fired — a weak-but-nonzero iteration 1 (say 1/9 triggers) is a different, potentially-recoverable case and is deliberately left to iterate. degenerate_harness additionally requires not-should-trigger queries to have fired zero times too: if the description is merely polarity-inverted — missing every positive while accidentally matching several negatives — the probe is proven to work and improve_description has real gradient to act on, so the guard does not abort that case (only a genuinely dead probe does). And it requires zero execution errors on either side — a not-should-trigger query that raised an exception never actually ran, so its "0 triggers" can't be used as evidence the probe is dead; that's exactly what routes to infra_error instead. Either way it breaks immediately and skips improve_description entirely — the JSON and HTML still report best_description/best_score normally (nothing is suppressed), the exit reason is the signal that this particular run's numbers shouldn't be read as "this is a good description." (Real case, 2026-08: a full 5-iteration loop was launched with no pre-check; two complete iterations — each a full eval batch, minutes of wall time and dozens of claude -p subprocess calls — came back precision=100%/recall=0%/identical scores before anyone looked at the numbers, and every should-trigger and not-should-trigger query alike had fired zero times. The failure was diagnosable from iteration 1 alone; nothing in iterations 2+ added information.) The HTML report also renders a banner when either exit reason fires, so the browser view carries the same signal as the JSON/stderr, not just the two lower-visibility channels. (An earlier draft of this guard checked should-trigger triggers alone; two rounds of independent review — a fresh agent each round, the second checking the first round's fixes rather than re-covering old ground — constructed the polarity-inverted counter-example, the infra-vs-description ambiguity, the negative-side-errors gap, and a pre-existing --holdout 0 report crash it surfaced along the way, all fixed before shipping.)
One caveat this guard can't cover: with --runs-per-query 1 (the default is 3), a single should-trigger query with a genuinely-50%-ish trigger rate has a real chance of reading 0/1 by chance alone and tripping the guard on noise, not on a dead probe. The default runs_per_query=3 is what makes "zero across every repeat of every positive query" a strong signal — if you override it down, this guard's false-positive risk goes up with it.
Sanity-check the harness before you trust best_description — it can still return hollow output even when neither guard above fired. Both checks only catch a total failure at iteration 1; a harness can also limp along with a persistently weak-but-nonzero signal across all 5 iterations without ever tripping either one. If every iteration reports recall staying near 0% with identical or near-identical scores past iteration 1, that's the same underlying problem the guards couldn't rule out — the "winning" description is usually just noise around iteration 1 unchanged. Before applying any best_description, run one obviously-should-trigger query yourself and confirm recall > 0. A recall-flat result across iterations means the harness is a hidden variable (commonly: the skill is losing the trigger to installed competitors — see Coexistence below) — do NOT apply its "best"; hand-author the description and verify it with real probes instead. (methodology Cases 12, 14) There is a second recall-0 root cause, distinct from competitor loss: the skill's task domain is low-threshold — the model does the job itself and never consults any skill — spelled out at the end of How skill triggering works below. Distinguish the two before reacting, because the fixes are opposite: a competitor is fixed by precedence/supersede, a low-threshold domain by abandoning the trigger probe entirely for production-as-eval.
When you probe triggering yourself with claude -p, collect ALL skill calls in the run, not just the first — and remember tool-invocation is a proxy. A UserPromptSubmit/SessionStart hook can inject an unrelated skill before the model chooses, so an "exit on the first Skill call" probe will misreport a false "didn't trigger." And "did it call the Skill tool" is not the same as "did the skill's content shape the output" (the model may read the skill without a visible Skill call) nor "is the output correct." A buggy probe is itself a hidden variable that keeps you optimizing against a wrong conclusion.
Understanding the triggering mechanism helps design better eval queries. Skills appear in Claude's available_skills list with their name + description, and Claude decides whether to consult a skill based on that description. The important thing to know is that Claude only consults skills for tasks it can't easily handle on its own — simple, one-step queries like "read this PDF" may not trigger a skill even if the description matches perfectly, because Claude can handle them directly with basic tools. Complex, multi-step, or specialized queries reliably trigger skills when the description matches — with one systematic exception (a low-threshold task domain) spelled out at the end of this section.
This means your eval queries should be substantive enough that Claude would actually benefit from consulting a skill. Simple queries like "read file X" are poor test cases — they won't trigger skills regardless of description quality.
But some skills fail this test for a reason no query rewrite can fix — the skill's whole job is a low-threshold task. The paragraph above blames the query ("write a more substantial one"); this is the orthogonal case, where the skill's domain is what blocks triggering. If a skill exists to do something Claude will just do itself with a basic tool — convert audio to 16 kHz, downsample, extract one field, bulk-rename — then even a fully-specified query ("downsample this 48k stereo wav to 16k mono for whisper," path and all) won't trigger it: the model reaches straight for Bash/ffmpeg and never consults any skill. Query substance can't fix this, because the "I can just do this" judgment is about the task, not the wording.
Diagnose it before you burn an optimization loop: run one realistic query through claude -p and watch whether the model ever consults the skill across the whole run (per the ALL-skill-calls rule above), or goes straight to Bash and does the job itself. If it never consults, the trigger probe is structurally blind to this skill — recall reads ~0 no matter what you write, and that zero measures the model's do-it-myself reflex, not your description. Stop tuning against claude -p recall and verify the real way: production-as-eval (the user's next real, interactive use — headless -p is more action-biased than a real session and systematically under-reports triggering), plus output comparison where the skill produces a checkable artifact. (Observed on an audio-preprocessing skill: a headless run_eval sweep read recall 0 on every query — including an obvious "transcribe this recording" one — and a manual claude -p probe showed the model going straight to Bash to find and process the file, Skill=0 across the run. The zero measured headless action-bias, not the description; the real signal only shows up in interactive use.)
Take best_description from the JSON output and update the skill's SKILL.md frontmatter. Show the user before/after and report the scores.
NEVER edit installed skill copies first. Treat all of these as installed/runtime copies unless the user explicitly says they are the source:
~/.codex/skills/<skill-name>~/.claude/skills/<skill-name>~/.agents/skills/<skill-name>~/.claude/plugins/cache/...~/.codex/plugins/cache/...Editing installed copies first causes changes to be:
ALWAYS verify you're editing the source repository:
# WRONG - cache location (read-only copy)
~/.claude/plugins/cache/daymade-skills/my-skill/1.0.0/my-skill/SKILL.md
# WRONG - personal installed copy unless explicitly used as source
~/.codex/skills/my-skill/SKILL.md
# RIGHT - source repository
<repo-root>/my-skill/SKILL.md
Before any edit, run a source-location check and say which path is source:
pwd
git rev-parse --show-toplevel
rg -n '"name": "<skill-or-suite-name>"' .claude-plugin/marketplace.json
find . -path '*/SKILL.md' -maxdepth 4 | rg '(^|/)<skill-name>/SKILL.md$'
If the available-skills list points at ~/.codex/skills, ~/.claude/skills, or a plugin cache, do not assume that path is source. Locate the repository-backed source first, edit it, validate it, and only then sync the installed copy when the user needs immediate local runtime use.
Then answer the follow-up question that decides whether "sync the installed copy" is even work: does the runtime already read the source? Three installs behave differently, and guessing wrong either wastes a sync or ships an edit the user's next session never sees:
ls -la ~/.claude/skills/<name> # a symlink into the repo? -> edits are live already
grep -A3 '"<marketplace-name>"' ~/.claude/plugins/known_marketplaces.json # "source": "directory" -> reads the repo in place
source: directory pointing at the repo → same: it reads the working tree, so a version bump is bookkeeping for other consumers, not a local activation step.cp -r install) → the runtime is a separate copy and genuinely needs the official update command before the new content is live.And verify activation by content, not by a version string. A registry can record a path or version that does not exist on disk — one session read a plugin record naming a cache directory with the new version number in it and nearly reported the update as live; that directory had never been created, and the real runtime path was a symlink to the source all along. The authoritative check is to grep the runtime file for something only the new version contains:
grep -c "<a phrase unique to the new content>" <resolved-runtime-path>/SKILL.md # 0 = not live
Power users run several Claude sessions at once, and skill repos are exactly where they collide: while you edit skill A, a sibling session may commit skill B (or even an earlier round of skill A) under you. One real session hit all three symptoms inside an hour — a Write rejected because the file changed after reading, and HEAD moving twice mid-task (methodology Case 16). The failure isn't the collision; it's a stale baseline or a clobbering write that silently mixes two sessions' work. Standing rules:
git archive <HEAD-sha> <skill-dir> | tar -x -C <workspace>/skill-before and pass --baseline-origin git-ref:<sha> to the audit. A tree snapshot taken minutes before someone else's commit is a baseline for a tree that no longer exists. Extract into a fresh, non-existent directory. Into an existing one, tar -x silently overwrites same-named files and leaves files the archive doesn't contain untouched — a mixed snapshot with zero signal at extract time, which compare later rejects as not matching the ref. Same trap, other command: mv <dir> <existing-dir> nests instead of replacing — and where mv is aliased to mv -i, a target-already-exists rename prints one prompt line and defaults to not happening, with exit 0 either way (verified by experiment).git log --oneline -3, git show <new-commit> --stat), fold the other session's intent into your version — their edit usually has a reason — and only then write.git log --oneline -1 catches a moved SHA: if it moved since your baseline, re-run the regression compare against the new ref before verify — the audit tool will reject a stale review anyway ("after skill changed"), so catching it yourself saves a round. But a sibling session can do something worse than advance HEAD: it can switch the branch out from under you, because a checkout is worktree-wide. Real sequence — checkout -b feat/x, edit for a while, and meanwhile another session ran checkout main + pull; the commit then landed on main, violating the repo's "never commit directly to local main" rule while the feature branch still pointed at the old base. So add git branch --show-current to the pre-commit check, not just the SHA. When it has already happened, git reflog is the authoritative reconstruction (it records each checkout: moving from X to Y with order), and the repair — given a clean worktree — is git checkout -B <feature> <your-sha> followed by git branch -f main origin/main: both are ref moves that never touch the working tree, so neither can destroy a parallel session's uncommitted work the way reset --hard would.git add <skill-dir> <registry-file>), never git add . — the sibling session's uncommitted work must not ride along. (Already the rule for packaging; doubly load-bearing under concurrency.)When creating or updating a skill, follow these steps in order. Skip steps only when clearly not applicable.
Before starting any skill work, auto-detect all dependencies and proactively install anything missing. Discovering a missing tool mid-workflow (e.g., gitleaks at packaging time, PyYAML at validation) wastes time and breaks flow.
Run the quick check from references/prerequisites.md, auto-install what you can, and present the user a summary checklist. Only proceed when all blocking dependencies are satisfied.
Key blockers: Python 3, uv, PyYAML (validation/packaging), and gitleaks (security scan). The claude CLI is blocking only when a separately authorized evidence plan actually runs agent evals. Run Python tools with explicit uv dependency declarations, for example uv run --with PyYAML python -m scripts.quick_validate <skill-path> from the skill-creator root directory. Bare python3 depends on ambient site packages and can miss PyYAML.
Skip this step only when the skill's usage patterns are already clearly understood.
To create an effective skill, clearly understand concrete examples of how the skill will be used. This understanding can come from either direct user examples or generated examples that are validated with user feedback.
For example, when building an image-editor skill, relevant questions include:
To avoid overwhelming users, avoid asking too many questions in a single message.
Analyze each example by:
Match specificity to task risk:
Skip this step if the skill already exists.
When creating a new skill from scratch, always run the init_skill.py script:
scripts/init_skill.py <skill-name> --path <output-directory>
The script creates a template skill directory with proper frontmatter, resource directories, and example files.
Before writing, retrieve Anthropic's best-practices doc (linked in "Skill Creation Best Practice" above) and the methodology reference — do this even when you feel you already know them: the doc updates, training-data versions go stale, and "I basically know it" is exactly the state in which editors skip it and miss the newest guidance.
When editing, remember that the skill is being created for another instance of Claude to use. Focus on information that would be beneficial and non-obvious to Claude.
Existing-skill migration gate — required before the first edit:
Capture the complete current bundle before editing. For a non-Git or dirty source, use the tool so the snapshot carries a verifiable provenance manifest:
cd <skill-creator-path>
uv run --with PyYAML python -m scripts.audit_skill_regression snapshot \
--source <path/to/skill-folder> \
--output <workspace>/skill-before
For a clean Git-tracked source, materialize the directory from the chosen ref:
mkdir -p <workspace>/skill-before # tar -C requires the target to already exist
git -C <repo-containing-the-skill> archive <ref> <skill-dir-relative-to-repo-root> \
| tar -x -C <workspace>/skill-before
# lands at <workspace>/skill-before/<skill-dir>/SKILL.md — one level deeper than
# the snapshot subcommand's output, because `git archive` preserves the path
# prefix; --before in step 3 is <workspace>/skill-before/<skill-dir>, not
# <workspace>/skill-before itself.
Include SKILL.md, references, scripts, assets, workflows, and existing evals—not
just the main prompt. Never copy the already-edited tree and label it "before".
Use a directory nothing has extracted into before — reusing one that already
has content from an earlier run lets tar -x silently overwrite same-named files
while leaving stale files the new archive doesn't contain untouched, producing a
mixed snapshot with zero signal at extract time (compare only catches it later,
indirectly, as a tree-hash mismatch). See "Concurrent sessions on the same skill
repo" below for the fuller version of this trap, including the mv-based variant.
Inventory the old skill's actor/jobs, trigger contexts, runtime contracts, commands/flags, failure and recovery cases, page/domain variants, bundled resources, and eval coverage. Add preservation cases for important old edge behavior before a structural rewrite.
After editing, generate an old-vs-new review:
cd <skill-creator-path>
uv run --with PyYAML python -m scripts.audit_skill_regression compare \
--before <workspace>/skill-before \
--after <path/to/skill-folder> \
--output <workspace>/skill-regression-review.json \
--baseline-origin pre-edit-snapshot
If the old directory was reconstructed from Git, replace the final flag with
--baseline-origin git-ref:<ref>. The tool resolves the ref to an immutable
commit and verifies every included file and executable bit against that tree.
Renaming or moving the skill directory itself (not just editing its
contents) changes --after's path, which both baseline modes use for
identity — compare rejects that by default (on the assumption --before/
--after were mismatched by accident) with pre-edit snapshot source identity does not match the edited skill. Add --renamed-from <old-path>
(the path --source pointed at for snapshot, or the skill's old path
relative to its repo root for git-ref:) to declare the rename explicitly;
the identity check then verifies that path instead of --after, while the
content/tree-hash check is untouched, so an actually-mismatched pairing
still fails. Pass --renamed-from as an absolute path. Every path this
command takes resolves relative to the current working directory when given
as relative — not relative to --after, and not relative to each other —
and --renamed-from typically names a directory that no longer exists (it
was renamed away), so there's no existence check to catch a wrong
resolution the way there is for --before/--after; it just fails deeper,
confusingly. This bites skill-creator's own edits in particular: cd <skill-creator-path> above is skill-creator's own repo, which is usually a
different repo from the skill being audited, so a relative
--renamed-from silently resolves against the wrong one.
Review every candidate. Use exactly one disposition and record concrete
evidence/reason: preserved_or_moved, intentional_sanitization,
intentional_boundary, removed_by_explicit_user_request, not_reusable,
or true_gap_fixed. Runtime capabilities cannot use not_reusable; moving a
runtime capability outside this skill requires the owning destination, current
boundary evidence, and traceable user approval. Explicit retirement must also
quote/trace the user's approval. Preserved/sanitized/fixed claims must point to
a real current file and line and include a short contains quote that the
verifier can locate nearby. File-level candidates use the current file
fingerprint plus a named semantic review explaining why behavior survived—the
fingerprint alone proves file identity, not capability preservation.
Don't hand-edit the review JSON or rewrite the same filler script each round —
the classify subcommand does the mechanical part (locates the quote's line
in the destination file, fills evidence/semantic_review, fail-fasts on a
missing quote or a too-short reason). You still author every disposition and
reason; it only types them in:
uv run --with PyYAML python -m scripts.audit_skill_regression classify \
--review <workspace>/skill-regression-review.json \
--after <path/to/skill-folder> \
--map <workspace>/dispositions.json \
--reviewer "<who-reviewed>"
where dispositions.json maps candidate index (or id) to
{"destination": "<rel-file>", "needle": "<verbatim current quote>", "reason": "<why this counts as preserved/sanitized/…>", "disposition": "preserved_or_moved"} (disposition defaults to
preserved_or_moved; file-level candidates need only destination + a 40+
char reason — the fingerprint is computed for you). Copy the needle out of
the destination file (Read/grep/sed), never type it from memory — the lookup
is exact-match and fail-fasts on a missing quote, and the two ways a hand-typed
needle actually fails are full-width vs half-width punctuation (: vs :) and
memory-paraphrased near-synonym characters (也 vs 都) — both escape
self-review, and both get caught only by the tool rejecting your whole map (one
map rejected twice in a row for exactly those two reasons).
Verify the completed review. Hashes make the review stale after any further
edit, so regenerate and reclassify when the candidate changes. A passing
verification writes .skill-regression-reviewed, a content-bound local status
receipt. It helps detect later edits, but it is deliberately not standalone
packaging authority; packaging re-verifies the completed review itself:
uv run --with PyYAML python -m scripts.audit_skill_regression verify \
--before <workspace>/skill-before \
--after <path/to/skill-folder> \
--review <workspace>/skill-regression-review.json
What success looks like at each gate step (real output, so silent failure is recognizable):
$ … compare …
Regression audit: 8 candidate(s), 371 exact preservation(s) # exit 1 = candidates to review
$ … classify …
Classified 8 candidate(s). # exit 1 = some still unclassified
$ … verify …
Skill regression review passed.
Regression attestation created: .skill-regression-reviewed # exit 0 = gate cleared
compare returning 1 means review candidates exist, not that the tool failed;
2 means invocation/runtime failure. The tool proves exact movement and interface
preservation, but deliberately refuses to infer semantic equivalence from fuzzy
word overlap. A generic phrase such as “check permission denied” cannot silently
replace a precise signed-in-without-role contract. Also inspect candidates marked
only_outside_runtime: runtime behavior present only in evals, tests, or an
unreachable reference is absent from the normal invocation path.
Validate immediately after every SKILL.md edit — don't wait for packaging (Step 7). The failure this catches early is real: a frontmatter description written as an unquoted YAML scalar parses fine in Claude Code's lenient parser but breaks in strict parsers (codex reported invalid YAML: mapping values are not allowed on a skill that had been shipping for months), and a # inside an unquoted description doesn't even error — it silently truncates everything after it, so the trigger keywords vanish while every scan stays green.
cd <skill-creator-path>
uv run --with PyYAML python -m scripts.quick_validate <path/to/skill-folder>
Write the description as a YAML block scalar (description: >- followed by an indented paragraph) whenever it contains : or # or spans multiple sentences — block scalars tolerate both characters natively — the recommended convention for every new or edited description since the incident above.
When updating an existing skill: Scan every existing reference and bundled resource for corresponding updates, then pass the migration gate above. Moving a contract requires a direct runtime pointer from SKILL.md; an eval or changelog is not a replacement.
The next three checks are escalation probes, not unconditional scope expansion. If acting on one would add or materially change a capability, workflow branch, output contract, script behavior, dependency, permission, or external write, stop and reclassify to Tier 3 before changing the skill. Tier 1 and Tier 2 may inspect these questions, but they do not acquire new deliverables from them.
Scripts check: Before calling the edit done, ask: what code did the source conversation (or the eval transcripts) write — that every future invocation would otherwise rewrite? When the selected tier already authorizes that capability work, bundle it into scripts/ (parameterized, sanitized) and change the docs to point at it. Otherwise record the signal as a Tier 3 proposal and do not bundle it as a Tier 1/2 side effect. The division of labor: scripts carry the execution, docs carry the understanding — a skill whose method lives only in prose re-pays the full authoring cost on every run. This check exists here, in the edit step, precisely because paths that skip the eval loop (conversation distillation, direct edits) never reach the eval-transcript version of this check in "Improving the skill".
Component-shelf check (the same question, asked of artifact-EMBEDDED fragments): the Scripts check covers code the skill executes; artifact-generating skills (report pages, decks, documents) also accumulate fragments their outputs embed — an image-overlay widget, a sticky nav, a chart config, a CSS block. If successive outputs each hand-write a similar fragment, that is the same repetition signal pointing at a different shelf. Before adding a components subfolder or registry reference, apply the escalation rule above; Tier 1/2 surface the proposal but do not create the component capability. When Tier 3 is authorized, what turns a snippet into a shelf component is the contract around it: (a) verbatim-embed block — BEGIN/END markers copied whole into the artifact, zero dependencies, so single-file artifacts stay self-contained; (b) registry entry stating the interaction contract (triggers, key bindings, close behavior, edge cases) and provenance — which delivered artifact it came from, when the user approved it; (c) admission gate — only fragments the user has actually used and approved enter (the approved-corpus discipline applied to interactions; unapproved-but-pretty stays out); (d) behavior frozen, skin adjustable — calibrated behavior and key bindings are the contract and must not drift between runs, while colors and sizing may follow the artifact's register; (e) write-back loop — a fragment invented for one artifact is promoted to the shelf in the same session its approval lands. The reason this matters beyond token savings: hand-rewritten fragments drift — each rewrite subtly changes key bindings, close behavior, counters — and for a user who reads these artifacts daily, interaction consistency IS the product experience. In the user's founding words for the first such shelf: 交互形式要沉淀下来、可复用、有复利,代表一致的交互喜好 (2026-07). Real instance (project fingerprints removed): a report-page skill's lightbox-gallery component (image overlay: ←/→ cycles the group, ESC closes, in-place zoom, n/N counter) with its interaction-components registry reference — extracted the same session the user corrected jump-style references, and verified with an automated click-through test before shipping. See methodology Case 17.
Pipeline check: Consider whether this skill's output naturally feeds into another skill, and whether an existing skill should chain into this one. Adding or materially changing a "Next Step" handoff or pipeline contract requires Tier 3 reclassification before the edit; Tier 1/2 may surface the proposal but must not add it in passing.
Reference-and-self-application check (the defects that survive a careful author): a family of failure modes that all look like finished work from the inside, and none of which is caught by re-reading harder — each needs a mechanical action instead. (No count is written in that opener on purpose. "Three failure modes:" is a derived number that goes stale the moment anyone appends a bullet, and counting prose is the hardest drift to catch precisely because it does not contain the thing that changed — renumbering greps and diffs of the list itself both sail straight past it.) They are grouped here because they share one cause: writing an assertion and verifying it are different modes, and a single pass cannot hold both. While you are composing, "see rule 8" is the claim; you are not simultaneously opening rule 8.
Unlike the three escalation probes above, this one is not scoped by tier — it is scoped by what you wrote. A Tier 1 fix that added no pointer and no normative rule has nothing here to do, and you do not have to judge that yourself: the corollary's script answers it in seconds by reporting NONE prose-reference-shaped. Wrote a pointer or a rule, at any tier? Then the bullets apply.
grep -n '^N\. ' <file> and confirm exactly one hit falls in the section you mean; if several do, name the section too. (Do not turn this into a file-level alarm like "does this file contain more than one list starting at 1" — on any long document that is true almost always, so it fires on healthy input and gets ignored, which discipline #6 warns is worse than no check; run it on this file and see for yourself.) In the real case a bare "rule 1" had three candidate lists and a top-down search hit the wrong one first.git diff <base-ref> -- <file>, using the same <base-ref> as the corollary below. Reading it yourself is enough here — you are not pattern-matching it, so it needs no script — but it must carry that ref: a bare git diff shows unstaged work only and prints nothing the moment you git add, which is one of the five silent-empty modes this block's own corollary was built to escape. Split the new rule into its separate clauses, and write down, per clause, the line in that same hunk that satisfies it. (The scripts/reference_net.sh in the corollary below is a different job: it lists prose cross-references for you to resolve. It does not hand you the hunk, and it will not tell you whether a clause of your rule is satisfied.) A clause with no line beside it is the finding. The tempting short version — "does my new rule pass?" — cannot fail for the person who wrote it 30 seconds ago; that is precisely what discipline #6 means by preferring a falsifiable observation to a self-assessment, so this bullet owes the same artifact it demands. Its first victim is usually the paragraph beside it. Real case: a rule was added saying "always report both the raw and the filtered count — the difference is the contamination", and its own worked example, in the same commit, printed only the filtered numbers. A second statement in that same diff quoted two figures without saying whether they were collected under the qualifier the neighbouring new rule had just made mandatory. The scope is small and bounded: not "re-read the document", just "does the rule I wrote 30 seconds ago pass on the lines I wrote 30 seconds ago".scripts/reference_net.sh <base-ref> <file>… (in this skill's bundle). It lists the prose cross-references among the lines you added, so you can open each target and confirm it says what you claim. Read its header before first use — it explains why it takes a base ref rather than defaulting to HEAD, and what it deliberately does not do.Get <base-ref> before you start editing, not after. Resolve it once to a literal SHA — BASE=$(git rev-parse HEAD) at the moment you begin — and reuse that same value for this and for the bullet above. If you ran the existing-skill migration gate, it is the ref you already baselined against. Passing HEAD later is the trap: after you commit, HEAD contains your own work, the script truthfully reports IDENTICAL, and that is indistinguishable from having nothing to check. If you did not capture it up front, recover it (git log, git reflog, or the baseline you gave the migration gate) rather than substituting HEAD; the script prints a note when your base ref is also your current HEAD, but do not rely on catching it there.
Why a script here, when the rest of this block is prose. The one-liner this replaces went through five rounds of patches — anchor the diff to the right base, see staged edits, survive committing, skip the diff's own +++ header, drop a misleading -n — and four of those five added one more way for it to print nothing and exit 0, which is indistinguishable from "I checked and it was clean". The fifth was the other shape of the same disease: the -n it removed had been printing real hits with line numbers counted off the piped stream, so they looked authoritative and pointed nowhere — worse than silence, because a wrong answer outranks no answer. Either way the check kept shipping the defect it was written to catch. Prose cannot validate its own inputs, cannot say which of its outcomes occurred, and cannot be tested; a script does all three and its contract is that every outcome is named and bad input fails loudly. This is the Scripts check earlier in this same step, applied to this block — and the five rounds are what ignoring it costs.
Read its verdict, not just its exit code. The script exits 0 whenever it ran, so $? alone tells you nothing about what it found; the verdict line is where the answer is, and it always names one of: references found (resolve each), file identical to base, file changed but with no added lines, or added lines with nothing reference-shaped. Those are different results and the script keeps them different on purpose — the version of this check that collapsed them into one silent "nothing" is the reason it became a script. It costs seconds and does not depend on vigilance, which is what discipline #6 asks of any check worth writing. (It is a net, not a proof. Its blind spot is a pointer with no number in it — "see the section below", "as the rule above says" — so read the added lines too.)
Before this gate, when discipline #5 is due, its independent pass must have run, and the current change's independent-review.md (in your private git-tracked knowledge repo — not the wiped workspace, not any repo that is or may become public or distributed) must exist and be committed. It is always due for a new skill; for an existing skill use the threshold in the next paragraph. A file sitting uncommitted in a git working directory is not meaningfully different from a file that was never written; ls/test -f confirms it is on disk, not that it survives. For a new skill this is the first step where anything leaves your hands, so it is where that discipline is actually enforced rather than merely stated — a rule that lives 1000 lines above the point of use, with nothing checking it, loses to completion-drive every time.
For an edit to an already-published skill, the moment it leaves your hands is the push, not this step. This gate can be answered "internal-only, skip" in one sentence, and packaging may never run at all for a docs-only change — so anchoring the review here means a skill edit can reach a public branch having passed no independent eye. Real case (2026-07): a change to this very file shipped a discovery command that could not reach three of the roots the prose beside it claimed it covered; it was merged, and only a review commissioned afterwards caught it. So for an existing skill: the independent pass and its recorded artifact are due before git push / opening the PR — the gates that run at push (regression audit, validation, scans) all check structure, and none of them can tell you the instructions are wrong. This inherits discipline #5's threshold unchanged: it is due when a rule, contract, or number changed, not for a typo or a pure reformat. Making a spelling fix wait on a review round would teach exactly the reflex #6 warns about — "this one's small" becomes the universal exemption, and then it covers the changes that mattered too.
Not optional for a skill going to a public repo. Private content leaks into public skills all the time, and the leaks a scanner misses are the dangerous ones — a real name in a non-English language, a verbatim line from a real transcript, a real example dropped into an illustration. Skip only if the skill is genuinely internal-only.
Scope the pass by destination, not by topic. Only the artifact that ships publicly — the skill bundle itself — gets sanitized. Companion documents that stay in a private repo (the incident report the skill was distilled from, internal runbooks, the project's CLAUDE.md) keep their real hostnames, paths, and timestamps: redacting those destroys their audit value, and you will end up reverting it. One distillation session went through three rounds of rework precisely because the redaction pass was applied to everything the source material touched instead of just the public skill.
Check the destination first, and let it pre-fill the recommendation. Run
gh repo view --json isPrivate on the repo the skill will live in (or read the note
quick_validate already printed). A private destination makes option C the default
recommendation rather than an afterthought — "assume public unless told otherwise" is
what turns a private skill's working paths into placeholders nobody asked for.
The trigger for sanitizing is the destination's isPrivate, not how much the task
feels like publishing. These come apart, and when they do the feeling wins unless you
name it. Moving content into a marketplace skill feels like publishing — marketplaces
are where things get distributed — so the sanitizing reflex fires even when both the
source and the destination are private repos and nothing is going anywhere. Real case
(2026-07): a migration from a project-level skill into a private marketplace skill
generalized a real config path, a real hex value and a real named example into
placeholders. quick_validate had printed 🔒 audience: private on every run;
the author read it every time and sanitized anyway, because the activity read as
publication. The cost is not cosmetic — a real path is what lets the next reader go
check the value; "the project's own token file" cannot be opened.
So make it a lookup, not a judgment: read isPrivate for the destination, and if it
is true, sanitizing requires the owner to ask for it. A private→private move is a
move, not a release. When neither probe answers (no remote yet, quick_validate not
run), you have no lookup — fall back to treating it as public and say so, because the
asymmetry runs that way: an unnecessary question costs a sentence, an unnecessary leak
does not come back. And isPrivate reports the destination's state today — a skill
sitting in a private repo on its way to release gets its sanitization pass on the push
that publishes it, not on this one. If you find yourself reasoning about whether something "should"
be generalized in a private destination, that reasoning is the tell.
Use AskUserQuestion to confirm the depth (for a public destination, confirm the depth, not whether to do it; for a private one, confirm whether it is wanted at all):
This skill will be public. I'll do a sanitization pass — the core of it is
me reading the whole skill and judging each name/example/snippet, because
scanners miss real content that has no keyword to match.
Options:
A) Full — I replace everything that looks lifted from a real project/person
B) Selective — I show you each finding and you decide (Recommended)
C) This skill is genuinely internal-only — skip
Sanitization process — the read-through is the method, the scan is a helper:
security_scan.py (Step 6). They catch obvious secrets / paths / known names fast — but "no matches" is not a pass.<placeholder>, real snippet → <placeholder>). Two rules learned the hard way: the placeholder itself must not encode the real value — <acme-corp-domain> leaks exactly the name it was supposed to hide; name the role instead (<api-domain>, <upstream-provider>). And when you script a bulk replace, give it an explicit file whitelist scoped to the skill directory — an unscoped find-and-replace will happily rewrite the project's own CLAUDE.md and force a git restore.Before packaging or distributing a skill, run the security scanner to detect hardcoded secrets and personal information:
# Required before packaging
uv run --with PyYAML python -m scripts.security_scan <path/to/skill-folder>
# Verbose mode includes additional checks for paths, emails, and code patterns
uv run --with PyYAML python -m scripts.security_scan <path/to/skill-folder> --verbose
Detection coverage:
evals/. Non-shipping .enrich/, tests/, and dist/ artifacts are excluded by the same shared policy used by the packager and content-hash attestation.What it does NOT cover — why Step 5's read-through is still required: gitleaks and the regex rules only match known secret formats and patterns you listed. They are structurally blind to private content with no keyword — a real person/project name in a non-English language, a verbatim line from a real transcript, a real example lifted from your own work. A green security_scan means "no known-format secret was found", not "the skill is sanitized". Never treat it as the latter.
First-time setup: Install gitleaks if not present:
# macOS
brew install gitleaks
# Linux/Windows - see script output for installation instructions
Exit codes:
0 - Clean (safe to package)1 - High severity issues2 - Critical issues (MUST fix before distribution)3 - gitleaks not installed4 - Scan errorIn a private skill, a finding is information, not a work order. The scanner cannot tell a leaked credential from a credential that is supposed to be there — a template whose whole value is that it comes pre-filled, a script pointing at the one machine it runs on. Never auto-fix in a private repo: report what was found and let the owner choose. Option A below ("fix automatically") is for skills headed somewhere public.
If issues are found, present them via AskUserQuestion:
Security scan found [N] issues in "[skill-name]":
- [SEVERITY] [file]: [description]
- ...
RECOMMENDATION: Fix automatically — these look like [accidental leaks / false positives].
Options:
A) Fix all issues automatically (Recommended)
B) Review each finding — let me decide per-item (some may be intentional)
C) Override and proceed — I accept the risk for internal distribution
Once the skill is ready, package it into a distributable file:
cd <skill-creator-path>
uv run --with PyYAML python -m scripts.package_skill <path/to/skill-folder>
For every existing Git-tracked skill, packaging is blocked until the completed review is supplied and re-verified. A current marker is only a local status receipt, so committing first or hand-writing a marker cannot bypass the review. The review becomes stale on the next edit:
uv run --with PyYAML python -m scripts.package_skill \
<path/to/skill-folder> \
--regression-review <workspace>/skill-regression-review.json
Optional output directory, and --include-evals to ship the root evals/ directory (excluded by default as a development asset):
cd <skill-creator-path>
uv run --with PyYAML python -m scripts.package_skill <path/to/skill-folder> ./dist --include-evals
The packaging script will:
If validation fails, the script reports errors and exits without creating a package.
After packaging, update the marketplace registry to include the new or updated skill.
For new skills, add an entry to .claude-plugin/marketplace.json:
{
"name": "skill-name",
"description": "Copy from SKILL.md frontmatter description",
"source": "./skill-name",
"strict": false,
"version": "1.0.0",
"category": "developer-tools",
"keywords": ["relevant", "keywords"]
}
For updated skills, bump the version in plugins[].version following semver. Any change to a skill's files — even a one-line typo fix — needs a bump: without it, marketplace update sees no new version, so already-installed copies never refresh and users keep running the old skill while your fix sits unshipped.
Then record it in the changelog — this is the step that gets skipped. The bump makes the update installable; the entry is what makes it findable six months later, when someone hits the same problem and greps for it. And a changelog that documents every other skill's versions while silently dropping yours is worse than none at all: the gaps read as "nothing changed there".
Match the existing entries' shape instead of inventing one — in a Keep-a-Changelog file that
is usually - **skill-name** (\suite` vX.Y.Z): what broke, why, and what proves it fixed`.
Write it in the same commit as the bump; a changelog updated "later" is one that never
gets updated.
Real case (2026-08): two consecutive releases of one skill shipped with correct bumps, green gates and merged PRs — and no changelog entries at all, because nothing in this procedure asked for one. Both were caught only by a later audit. That is discipline #6 turned on this file itself: a rule that lives in a convention rather than in a step loses to completion-drive every time.
Keep the registry diff minimal — it is the single file every skill shares. A marketplace manifest is the one place where every concurrent editor collides, so an unrelated formatting change there is far more expensive than the same change anywhere else: it turns a clean three-line bump into a conflict for whoever else is mid-edit. When you script the update (parsing to JSON, mutating, writing back), the rewrite silently normalizes things the file may not have used — trailing newline, indent width, key order, unicode escaping. Round-trip discipline: re-read the file afterwards and run git diff --stat on it; the only lines that may appear are the fields you meant to change. If extra lines show up, restore the file's original convention rather than shipping the normalization (a scripted bump once added a trailing newline to a manifest that had never had one — one wasted diff line, in the file most likely to be edited by someone else at the same moment). The same instinct applies to any shared registry a skill touches: lockfiles, catalogs, index documents.
When a PR outlives a few merges, rebase — then prove you didn't eat anyone's work. The same property that makes the manifest a collision hotspot makes it the thing that goes stale: an open PR touching the registry and the changelog will conflict as soon as anything else lands, so expect mergeable: CONFLICTING rather than treating it as a surprise (one PR hit it after main moved 7 commits in an afternoon). Rebase rather than merge if the repo squash-merges — a merge commit in a squashed history buys nothing. The conflicts themselves are almost always additive: two authors each appended their own entry in the same section, so the resolution is to keep both, never --ours/--theirs, which silently discards a colleague's line.
The step people skip is the one that catches a bad resolution — after resolving, prove the only difference from the base is yours:
# Every version the base has vs. what your branch has; the diff must contain
# ONLY the entry you bumped. Anything else means the resolution ate someone's work.
python3 -c "
import json,subprocess
mine=json.load(open('<manifest>'))
base=json.loads(subprocess.run(['git','show','origin/main:<manifest>'],capture_output=True,text=True).stdout)
b={p['name']:p['version'] for p in base['plugins']}; m={p['name']:p['version'] for p in mine['plugins']}
print({k:(b.get(k),m.get(k)) for k in set(b)|set(m) if b.get(k)!=m.get(k)})"
Then push with --force-with-lease, never a bare --force: the lease makes the push fail if the remote moved since you last fetched, which is exactly the case where someone else pushed to your branch and a plain force would erase them.
Plugin boundaries are not this skill's domain. Whether to split skills into
separate plugins, how to lay out source/skills, and whether users can toggle
skills individually all belong to the packaging/distribution domain — the SSOT is
the marketplace-dev skill, not here. When a task actually needs those decisions:
ensure marketplace-dev is available (auto-install it if missing — the same way
skill-reviewer pulls in skill-creator when it needs its scripts), then read
marketplace-dev's cache-and-source-patterns reference and follow it. Don't restate
its rules here; a copy would drift.
Renaming, relocating, or removing a marketplace entry is a breaking change for
every user who already installed it — Claude Code does not clean up installed copies
when an entry disappears, leaving dangling installs that error on every marketplace update. Treat such changes like an API deprecation: ship a migration note in the
changelog, and follow marketplace-dev's guidance for the mechanics.
If you commit/push the skill repo yourself: for an existing skill whose current change crosses discipline #5's rule/contract/number threshold, confirm the review artifact records this change and is committed (check its exact path with git status and git log -1 -- <artifact>, not merely whether some historical independent-review.md exists). A typo or pure reformat does not require that artifact; an older review never satisfies a current substantive change. Step 5's note explains why push, not packaging, is the real enforcement point for an already-published skill. Then stage only the skill's explicit paths (git add <skill-dir> .claude-plugin/marketplace.json) — never git add .; the working tree is usually full of unrelated churn that will otherwise ride into the commit (one commit swept in a pile of unrelated transcript files and had to be git reset and re-staged). Before pushing, confirm the repo's real visibility with gh repo view --json visibility,isPrivate instead of assuming from the path — a public skill repo deserves a PR + review, not a direct push to main.
After completing the skill, use AskUserQuestion to determine next steps:
Skill "[name]" is complete. Security scan passed, marketplace updated.
RECOMMENDATION: [pick based on state — e.g. "B) optimize the description" if triggering was never verified, else "D) done for now"] because [one-line reason].
Options:
A) Package and export as .skill file for distribution
B) Run description optimization — improve auto-triggering accuracy (~5 min)
C) Expand test set and iterate more — add edge cases before shipping
D) Done for now — I'll test it manually and come back if needed
After testing the skill, users may request improvements. Often this happens right after using the skill, with fresh context of how the skill performed.
Refinement filter: Only add what solves observed problems. If best practices already cover it, don't duplicate.
present_files tool is available)Check whether you have access to the present_files tool. If you don't, skip this step. If you do, package the skill and present the .skill file to the user:
uv run --with PyYAML python -m scripts.package_skill <path/to/skill-folder>
After packaging, direct the user to the resulting .skill file path so they can install it.
In Claude.ai, use the same verification-depth router and heavy-eval authorization gate. When the full generic paired pipeline is explicitly authorized, the workflow is draft -> test -> review -> improve -> repeat, but because Claude.ai doesn't have subagents, some mechanics change. Here's what to adapt:
Running test cases: No subagents means no parallel execution. For each test case, read the skill's SKILL.md, then follow its instructions to accomplish the test prompt yourself. Do them one at a time. This is less rigorous than independent subagents (you wrote the skill and you're also running it, so you have full context), but it's a useful sanity check — and the human review step compensates. Skip the baseline runs — just use the skill to complete the task as requested.
Reviewing results: If you can't open a browser (e.g., Claude.ai's VM has no display, or you're on a remote server), skip the browser reviewer entirely. Instead, present results directly in the conversation. For each test case, show the prompt and the output. If the output is a file the user needs to see (like a .docx or .xlsx), save it to the filesystem and tell them where it is so they can download and inspect it. Ask for feedback inline: "How does this look? Anything you'd change?"
Benchmarking: Skip the quantitative benchmarking — it relies on baseline comparisons which aren't meaningful without subagents. Focus on qualitative feedback from the user.
The iteration loop: Same as before — improve the skill, rerun the test cases, ask for feedback — just without the browser reviewer in the middle. You can still organize results into iteration directories on the filesystem if you have one.
Description optimization: This section requires the claude CLI tool (specifically claude -p) which is only available in Claude Code. Skip it if you're on Claude.ai.
Blind comparison: Requires subagents. Skip it.
Packaging: The package_skill.py script works anywhere with Python and a filesystem. On Claude.ai, you can run it and the user can download the resulting .skill file.
name frontmatter field — use them unchanged. E.g., if the installed skill is research-helper, output research-helper.skill (not research-helper-v2)./tmp/skill-name/, immediately create the audit tool's pre-edit snapshot from that writeable copy, then edit and package from the copy with --regression-review. Do not pass --new-skill; a non-Git copy of an existing skill is still an existing skill./tmp/ first, then copy to the output directory — direct writes may fail due to permissions.If you're in Cowork, the main things to know are:
--static <output_path> to write a standalone HTML file instead of starting a server. Then proffer a link that the user can click to open the HTML in their browser.generate_review.py rather than custom HTML. Default tier evidence, unauthorized work, and specialized workflows that replace viewer mechanics do not acquire a viewer obligation merely because the work happens in Cowork.feedback.json as a file. You can then read it from there (you may have to request access first).package_skill.py just needs Python and a filesystem.run_loop.py / run_eval.py) should work in Cowork just fine since it uses claude -p via subprocess, not a browser, but please save it until you've fully finished making the skill and the user agrees it's in good shape.The agents/ directory contains instructions for specialized subagents. Read them when you need to spawn the relevant subagent.
agents/grader.md — How to evaluate assertions against outputsagents/comparator.md — How to do blind A/B comparison between two outputsagents/analyzer.md — How to analyze why one version beat anotherThe references/ directory has additional documentation:
references/eval_pipeline_schemas.md — JSON structures for evals.json, grading.json, benchmark.json, etc.references/sanitization_checklist.md — Checklist for sanitizing business-specific content before public distributionThe scripts/ directory includes deterministic gates used by this workflow:
scripts/audit_skill_regression.py — compares an immutable old skill bundle
with the edited bundle, creates an explicit disposition review, and verifies
its hashes/evidence before packaging an existing skill.scripts/reference_net.sh — lists the prose cross-references among the lines you
added, for the Reference-and-self-application check in Step 4 (Edit the Skill). Its own header is
contract: what it covers, what it deliberately leaves to lychee, and why it takes a
base ref rather than HEAD.Repeating one more time the core loop here for emphasis:
benchmark.json, and run eval-viewer/generate_review.pyPlease add the selected verification tier and its default evidence to your TodoList, if you have one. Add "Create evals JSON and run eval-viewer/generate_review.py so human can review test cases" only after the generic paired pipeline is explicitly authorized.
Good luck!
Frequently asked questions
A skill for creating new skills and iteratively improving them.
The source record exposes this install command: npx skills add https://github.com/daymade/claude-code-skills --skill "daymade-skill/skill-creator". Inspect the command and pinned source before running it.
The pinned source record declares support for: codex.
Static rules flagged write-files, exec-script, read-files in the source; the page lists the matching lines and excerpts.
Alternatives
CherryHQ/cherry-studio
Create new skills, modify and improve existing skills, and measure skill performance. Use when users want to create a skill from scratch, edit, or optimize an existing skill, run evals to test a skill, benchmark skill performance with variance analysis, or optimize a skill's description for better triggering accuracy.
netease-youdao/LobsterAI
Create new skills, modify and improve existing skills, and measure skill performance. Use when users want to create a skill from scratch, update or optimize an existing skill, run evals to test a skill, benchmark skill performance with variance analysis, or optimize a skill's description for better triggering accuracy.
proma-ai/Proma
Create new skills, modify and improve existing skills, and measure skill performance. Use when users want to create a skill from scratch, edit, or optimize an existing skill, run evals to test a skill, benchmark skill performance with variance analysis, or optimize a skill's description for better triggering accuracy.
Playa-0v0/Cyrene-Agent
Create new skills, modify and improve existing skills, and measure skill performance. Use when users want to create a skill from scratch, edit, or optimize an existing skill, run evals to test a skill, benchmark skill performance with variance analysis, or optimize a skill's description for better triggering accuracy.