Adopt: directory keeps its NN- ordering prefix; skill `name:` is the clean form without it (dir 16-seo-schema-validator → name: seo-schema-validator). Nicer to invoke, matches the original desktop/SKILL.md names, still globally unique. - 71 root SKILL.md: name: NN-foo → name: foo (flat skills + reference-curator suite). Plugins (mac-optimizer/multi-agent-guide/dintel-bootstrap) already clean; 95 already clean. - scripts/migrate_skill_root.py: derive name = dirname minus NN- prefix (skill_name()). - CLAUDE.md + SKILL-MIGRATION-GUIDE.md: document the dir-prefix / clean-name convention. verify_skills.py: 0 name collisions across all renamed skills. (The ~/.claude/skills symlinks were re-pointed to the clean names separately — filesystem only.) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4.3 KiB
Skill Migration Guide — add a root SKILL.md (hybrid pattern)
One page. How to make an existing dual-platform skill natively loadable as an Agent
Skill without rewriting it. Reference implementations: custom-skills/16-seo-schema-validator
and custom-skills/17-seo-schema-generator.
Why
Claude Code / Desktop / API natively load the Agent Skills format: a directory whose
root holds a SKILL.md (YAML frontmatter + body) plus optional bundled resources. Our
older skills keep the directive in desktop/SKILL.md and code/CLAUDE.md — not at the
root — so they aren't directly loadable. The fix is additive: promote a SKILL.md to
the root. Keep code/ and desktop/ as-is. No rewrite, no logic change.
Target (hybrid) structure
XX-skill-name/
├── SKILL.md # ← NEW: root directive, official format (loadable)
├── scripts/ # ← runnable scripts (single source of truth)
├── references/ # ← heavy docs, loaded on demand
├── templates/ # ← optional
├── fixtures/ # ← optional (sample/test inputs)
├── code/ # KEPT — code/CLAUDE.md redirects to ../SKILL.md + ../scripts
└── desktop/ # KEPT — desktop/SKILL.md + skill.yaml + tools/
Scripts live once at the root scripts/; code/CLAUDE.md points to ../scripts/
(don't duplicate). Don't move existing scripts that other skills already reference.
Recipe (≈10 min/skill)
- Copy
desktop/SKILL.md→ rootSKILL.md. (It's already frontmatter + body — the right shape; it was just in the wrong place.) - Fix the frontmatter against the checklist below.
- Promote resources to root siblings: if real scripts/docs live under
code/, move the canonical copy to rootscripts/+references/; reference them fromSKILL.mdwith relative paths (scripts/foo.py,references/bar.md). - Redirect
code/CLAUDE.mdto a short pointer: "canonical =../SKILL.md; scripts =../scripts/" (see 16/17code/CLAUDE.md). - Leave
desktop/intact (SKILL.md, skill.yaml, tools/). It stays the Desktop view. - Verify (below). Commit.
Frontmatter checklist (the only hard requirement)
---
name: skill-name-kebab-case # letters, numbers, hyphens ONLY
description: | # third person; START with "Use when…" / what+when
What it does in one line. Triggers: kw1, kw2, 한국어 트리거.
---
name: the clean skill name = directory name minus itsNN-ordering prefix (dir16-seo-schema-validator→name: seo-schema-validator). kebab-case, no spaces/parens/special chars. Dirs keep the number prefix for ordering; the skillnamenever carries it.description: third-person; says when to use + trigger keywords (EN + KO).- Whole frontmatter ≤ 1024 characters.
- Body: concise markdown (aim < 500 words of always-on content); push detail into
references/and link it — don't@-include (that force-loads and burns context). - Optional fields allowed:
version,author,license,allowed-tools,metadata.
Verify before committing
# frontmatter present + size sane
head -20 custom-skills/XX-skill/SKILL.md
python3 - <<'PY'
import re,sys,pathlib
t=pathlib.Path("custom-skills/XX-skill/SKILL.md").read_text()
m=re.match(r'^---\n(.*?)\n---',t,re.S); assert m,"no frontmatter"
fm=m.group(1); assert len(fm)<=1024,f"frontmatter {len(fm)} >1024"
assert re.search(r'^name:\s*[a-z0-9-]+\s*$',fm,re.M),"name must be kebab-case"
assert 'description:' in fm,"description required"
print("OK: frontmatter valid")
PY
# every relative path referenced in SKILL.md must exist
grep -oE '`(scripts|references|templates|fixtures)/[^`]+`' custom-skills/XX-skill/SKILL.md
# if the skill has scripts, run its bundled sample/fixture end to end
Adopt going forward
- New skills: create a root
SKILL.mdfrom day one (the hybrid above).code/+desktop/remain optional packaging, not the primary directive. - Existing skills: migrate incrementally — when you next touch a skill, apply the recipe. A bulk migration of all skills isn't worth the churn unless you specifically need them all loadable at once.
- When in doubt, copy the shape of
16-seo-schema-validator/17-seo-schema-generator.