Paths note: All ~/code/skills/... references below default to the public repo path; override via $SKILLS_REPO_ROOT. Same for ~/.copilot/skills/ (override $SKILLS_LOCAL_ROOT) and ~/.copilot/skill-state/skill-review/ (override $SKILLS_STATE_DIR). See the repo README "Forking and portability" section.
skill-create
When to use
- The user says "make this a skill", "create a skill for X", or similar.
- You (the agent) just solved a non-trivial task with reusable steps and the user confirms it should become a skill.
- You're following the auto-create trigger in
$HOME/.copilot/copilot-instructions.md (see ## Skill self-learning).
Do not invoke this for one-off tasks, throwaway scripts, or facts that belong in memory (store_memory) rather than a reusable procedure.
Two-root skill layout (where new skills go)
There are two roots, with different authority:
- LOCAL native root
~/.copilot/skills/<name>/ — agent-managed, mutable.
Loaded directly by Copilot CLI (no plugin, no registry). It is a local git
repo with NO remote (commits are reversible; nothing is ever pushed). This is
the default home for new agent-created skills and for any skill the user is
fine keeping personal/local.
- PUBLIC plugin repo
~/code/skills/skills/<name>/ — curated, shared via
the dfrysinger/skills plugin. Loads via .claude-plugin/plugin.json
.skills[] (explicit allowlist). Use this only for skills the user wants
published. The autonomous skill-review daemon never writes here.
Layout is flat: <root>/<name>/SKILL.md. No category subdirectories. Pick
one short kebab-case name; class-level umbrella, not session-specific.
If the user is ambiguous about where the skill should live, default to LOCAL.
A user can later promote local→public with skill-manage/scripts/promote-skill.sh.
HARDLINE authoring standards (non-negotiable)
Lifted from Hermes Agent's AGENTS.md — these are the rules every skill must
meet. The skill is not done until all eight pass.
Description ≤ 1024 characters, includes "Use when…" Frontmatter description: is the only thing the agent sees when picking a skill. State the capability in plain language, then a second sentence with concrete triggers. No marketing words ("powerful", "comprehensive", "seamless"). Don't repeat the skill name. Verify:
awk '/^description:/{gsub(/^description: */,""); print length}' SKILL.md
Tools referenced in prose must be the ones Copilot CLI actually exposes. Use names like view, edit, create, grep, glob, bash, task, manage_schedule, web_fetch, ask_user, report_intent. Do not name shell utilities the agent already has wrapped — grep → grep tool, cat/head/tail → view, find/ls → glob. Third-party CLIs are fair game inside scripts/ but should not be the headline interaction surface.
Platform gating. Skills using macOS-only primitives (security, osascript, launchctl, /Users/... hardcoded paths, pbcopy) must say so in the SKILL.md ## Prerequisites section. Default posture: try cross-platform first (Python pathlib, tempfile.gettempdir(), etc.); gate only when the dependency is genuinely OS-bound.
Modern section order in SKILL.md body. # <Skill Name> title, 1-3 sentence intro stating what it does (and what it does NOT do), then:
## When to use — concrete trigger conditions
## Prerequisites — required env vars, tools, files (if any)
## Quick start — minimal working invocation
## Workflow / ## Procedure — step-by-step
## Pitfalls — known failure modes (optional but encouraged)
## Verification — how to confirm it worked (optional)
Target ≤100 lines for simple skills, ≤200 for complex. Cut intro fluff,
marketing prose, and re-explanations of env vars already in ## Prerequisites.
Scripts go in scripts/, references in references/, templates in templates/. Don't expect the model to inline-write parsers or non-trivial logic every call — ship a helper script. Reference it from SKILL.md by path relative to the skill directory.
Frontmatter shape.
---
name: <slug> # lowercase, regex ^[a-z0-9][a-z0-9._-]*$, ≤64 chars
description: <≤1024 chars, two sentences ending with "Use when…">
---
Optional: version, author, license, platforms: [macos].
Name is filesystem-safe and globally distinct across BOTH roots. Slug regex ^[a-z0-9][a-z0-9._-]*$. Check for collisions everywhere:
grep -lr "^name: <slug>$" \
~/code/skills/skills/ ~/.copilot/skills/ \
~/.copilot/installed-plugins/ 2>/dev/null
Size caps. SKILL.md body ≤ 100k characters (~36k tokens). Individual supporting files ≤ 1 MiB. If you're over, split into references/.
Procedure (LOCAL root — the default)
This is the path the autonomous daemon uses and the right default for any new
agent-created skill. NO git push, NO plugin.json registration.
Gather (use ask_user if anything is missing; never multiple-choice for @dfrysinger):
- Skill
name (kebab-case)
- One-sentence what-it-does + one-sentence "Use when…"
- Whether it needs scripts (deterministic ops) or references (long docs)
Pre-flight collision check across BOTH roots:
ls -d ~/code/skills/skills/<name> ~/.copilot/skills/<name> 2>/dev/null \
&& echo "COLLISION"
If collision, ask the user to pick a different name or confirm overwrite.
Also run ~/code/skills/skills/skill-review/scripts/check-tombstone.sh <name>
— exit 0 means a curator tombstone exists and you must NOT recreate it.
Create the directory:
mkdir -p ~/.copilot/skills/<name>/{scripts,references}
Only create the subdirs you'll actually populate.
Author SKILL.md following the modern section order (rule 4).
Validate.
~/code/skills/skills/skill-manage/scripts/validate-skill.sh \
~/.copilot/skills/<name>/SKILL.md
Test scripts. Sanity-run anything in scripts/ to confirm it executes.
Mark provenance (only when this skill was created autonomously, not by hand):
~/code/skills/skills/skill-review/scripts/mark-agent-created.sh \
<name> <session_id> <mode>
Commit in the LOCAL repo only:
cd ~/.copilot/skills
git add <name>/
git commit -m "skills/<name>: <one-line summary>
<Optional body.>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>"
There is no remote — nothing is pushed.
Tell the user how to activate it:
- Run
/skills reload in any open Copilot CLI session, or restart.
- The skill loads automatically as
/<name> (native personal skill — no
plugin entry needed).
Procedure (PUBLIC repo — when the user asks for a shareable skill)
Use only when the user explicitly wants the skill shared via the plugin. Do
NOT default to this path for autonomous creation.
Steps 1–6 same as above, but with ~/code/skills/skills/<name>/ as the
target dir. Skip step 7 (no .agent-created marker on a curated skill).
Register the skill in .claude-plugin/plugin.json (REQUIRED — skills
are an explicit allowlist; an unlisted dir is silently ignored):
~/code/skills/skills/skill-manage/scripts/registry.sh register <name>
Commit and push the public repo:
cd ~/code/skills
git add skills/<name>/ .claude-plugin/plugin.json
git commit -m "skills/<name>: <summary>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>"
git push origin main
Refresh the plugin cache so the new skill loads:
git -C ~/.copilot/installed-plugins/_direct/dfrysinger--skills pull --ff-only
Then /restart (or /skills reload is not enough for plugin changes).
If the skill already exists in the LOCAL root and you just want to publish it,
use ~/code/skills/skills/skill-manage/scripts/promote-skill.sh <name> instead
— it moves, strips provenance, registers, and commits both repos.
Pitfalls
- Forgetting that LOCAL and PUBLIC have different rules. Local skills need
no
plugin.json entry and never get pushed. Public skills require
registration and a plugin-cache refresh. Don't apply the public workflow to
a local skill (you'll fail at git push since there's no remote).
- Description that doesn't trigger. If your description doesn't include
concrete keywords for when to load the skill, the agent will never pick it.
Re-read rule 1.
- Skill that duplicates an existing capability. Before creating, glob
~/code/skills/skills/**/SKILL.md AND ~/.copilot/skills/**/SKILL.md for
overlap. Better to extend an existing skill via skill-manage patch than to
create a near-duplicate.
- Auto-create spam. The auto-create trigger in
copilot-instructions.md
is a proposal (Tier 1) or contained autonomous (Tier 2 daemon). The bar
is: "would I want to invoke this same procedure again next month?"
- Vendoring third-party skills. When importing externally-authored skills,
copy them verbatim, pin the source commit, preserve the license, and add a
NOTICE.md (see ~/code/skills/skills/NOTICE.md for the existing example).
Verification
After completing the procedure, the new skill should:
- Exist at
~/.copilot/skills/<name>/SKILL.md (LOCAL) or
~/code/skills/skills/<name>/SKILL.md (PUBLIC)
- Pass
validate-skill.sh with zero errors
- For PUBLIC only: be listed in
.claude-plugin/plugin.json .skills[]
- Be committed in its owning repo
- Appear as
/<name> after /skills reload (LOCAL) or /restart after
plugin cache refresh (PUBLIC)
If any of these fail, the skill is not done — fix and re-validate.
Source: dfrysinger/skills — distributed by TomeVault.
1---2name: skill-create3description: Create a new personal skill in dfrysinger/skills, enforcing HARDLINE authoring standards (frontmatter, naming, structure, size caps). Use when the user says "make this a skill", "create a skill for X", or when an agent recognizes a reusable procedure worth saving (per the auto-create trigger in copilot-instructions.md). For modifying an existing skill, use /skill-manage instead. Use when this capability is needed.4---56> **Paths note:** All `~/code/skills/...` references below default to the public repo path; override via `$SKILLS_REPO_ROOT`. Same for `~/.copilot/skills/` (override `$SKILLS_LOCAL_ROOT`) and `~/.copilot/skill-state/skill-review/` (override `$SKILLS_STATE_DIR`). See the repo README "Forking and portability" section.789# skill-create1011## When to use1213- The user says "make this a skill", "create a skill for X", or similar.14- You (the agent) just solved a non-trivial task with reusable steps and the user confirms it should become a skill.15- You're following the auto-create trigger in `$HOME/.copilot/copilot-instructions.md` (see `## Skill self-learning`).1617Do **not** invoke this for one-off tasks, throwaway scripts, or facts that belong in memory (`store_memory`) rather than a reusable procedure.1819## Two-root skill layout (where new skills go)2021There are two roots, with different authority:2223- **LOCAL native root** `~/.copilot/skills/<name>/` — agent-managed, mutable.24 Loaded directly by Copilot CLI (no plugin, no registry). It is a local git25 repo with NO remote (commits are reversible; nothing is ever pushed). This is26 the default home for new agent-created skills and for any skill the user is27 fine keeping personal/local.28- **PUBLIC plugin repo** `~/code/skills/skills/<name>/` — curated, shared via29 the `dfrysinger/skills` plugin. Loads via `.claude-plugin/plugin.json`30 `.skills[]` (explicit allowlist). Use this only for skills the user wants31 published. The autonomous skill-review daemon never writes here.3233Layout is **flat**: `<root>/<name>/SKILL.md`. No category subdirectories. Pick34one short kebab-case name; class-level umbrella, not session-specific.3536If the user is ambiguous about where the skill should live, default to LOCAL.37A user can later promote local→public with `skill-manage/scripts/promote-skill.sh`.3839## HARDLINE authoring standards (non-negotiable)4041Lifted from Hermes Agent's `AGENTS.md` — these are the rules every skill must42meet. The skill is **not done** until all eight pass.43441. **Description ≤ 1024 characters, includes "Use when…"** Frontmatter `description:` is the only thing the agent sees when picking a skill. State the capability in plain language, then a second sentence with concrete triggers. No marketing words ("powerful", "comprehensive", "seamless"). Don't repeat the skill name. Verify:45 ```bash46 awk '/^description:/{gsub(/^description: */,""); print length}' SKILL.md47 ```48492. **Tools referenced in prose must be the ones Copilot CLI actually exposes.** Use names like `view`, `edit`, `create`, `grep`, `glob`, `bash`, `task`, `manage_schedule`, `web_fetch`, `ask_user`, `report_intent`. Do **not** name shell utilities the agent already has wrapped — `grep` → `grep` tool, `cat`/`head`/`tail` → `view`, `find`/`ls` → `glob`. Third-party CLIs are fair game inside `scripts/` but should not be the headline interaction surface.50513. **Platform gating.** Skills using macOS-only primitives (`security`, `osascript`, `launchctl`, `/Users/...` hardcoded paths, `pbcopy`) must say so in the SKILL.md `## Prerequisites` section. Default posture: try cross-platform first (Python `pathlib`, `tempfile.gettempdir()`, etc.); gate only when the dependency is genuinely OS-bound.52534. **Modern section order in SKILL.md body.** `# <Skill Name>` title, 1-3 sentence intro stating what it does (and what it does NOT do), then:54 - `## When to use` — concrete trigger conditions55 - `## Prerequisites` — required env vars, tools, files (if any)56 - `## Quick start` — minimal working invocation57 - `## Workflow` / `## Procedure` — step-by-step58 - `## Pitfalls` — known failure modes (optional but encouraged)59 - `## Verification` — how to confirm it worked (optional)6061 Target ≤100 lines for simple skills, ≤200 for complex. Cut intro fluff,62 marketing prose, and re-explanations of env vars already in `## Prerequisites`.63645. **Scripts go in `scripts/`, references in `references/`, templates in `templates/`.** Don't expect the model to inline-write parsers or non-trivial logic every call — ship a helper script. Reference it from SKILL.md by path relative to the skill directory.65666. **Frontmatter shape.**67 ```yaml68 ---69 name: <slug> # lowercase, regex ^[a-z0-9][a-z0-9._-]*$, ≤64 chars70 description: <≤1024 chars, two sentences ending with "Use when…">71 ---72 ```73 Optional: `version`, `author`, `license`, `platforms: [macos]`.74757. **Name is filesystem-safe and globally distinct across BOTH roots.** Slug regex `^[a-z0-9][a-z0-9._-]*$`. Check for collisions everywhere:76 ```bash77 grep -lr "^name: <slug>$" \78 ~/code/skills/skills/ ~/.copilot/skills/ \79 ~/.copilot/installed-plugins/ 2>/dev/null80 ```81828. **Size caps.** SKILL.md body ≤ 100k characters (~36k tokens). Individual supporting files ≤ 1 MiB. If you're over, split into `references/`.8384## Procedure (LOCAL root — the default)8586This is the path the autonomous daemon uses and the right default for any new87agent-created skill. NO git push, NO plugin.json registration.88891. **Gather** (use `ask_user` if anything is missing; never multiple-choice for @dfrysinger):90 - Skill `name` (kebab-case)91 - One-sentence what-it-does + one-sentence "Use when…"92 - Whether it needs scripts (deterministic ops) or references (long docs)93942. **Pre-flight collision check across BOTH roots:**95 ```bash96 ls -d ~/code/skills/skills/<name> ~/.copilot/skills/<name> 2>/dev/null \97 && echo "COLLISION"98 ```99 If collision, ask the user to pick a different name or confirm overwrite.100 Also run `~/code/skills/skills/skill-review/scripts/check-tombstone.sh <name>`101 — exit 0 means a curator tombstone exists and you must NOT recreate it.1021033. **Create the directory:**104 ```bash105 mkdir -p ~/.copilot/skills/<name>/{scripts,references}106 ```107 Only create the subdirs you'll actually populate.1081094. **Author SKILL.md** following the modern section order (rule 4).1101115. **Validate.**112 ```bash113 ~/code/skills/skills/skill-manage/scripts/validate-skill.sh \114 ~/.copilot/skills/<name>/SKILL.md115 ```1161176. **Test scripts.** Sanity-run anything in `scripts/` to confirm it executes.1181197. **Mark provenance** (only when this skill was created autonomously, not by hand):120 ```bash121 ~/code/skills/skills/skill-review/scripts/mark-agent-created.sh \122 <name> <session_id> <mode>123 ```1241258. **Commit in the LOCAL repo only:**126 ```bash127 cd ~/.copilot/skills128 git add <name>/129 git commit -m "skills/<name>: <one-line summary>130131 <Optional body.>132133 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>"134 ```135 There is no remote — nothing is pushed.1361379. **Tell the user how to activate it:**138 - Run `/skills reload` in any open Copilot CLI session, or restart.139 - The skill loads automatically as `/<name>` (native personal skill — no140 plugin entry needed).141142## Procedure (PUBLIC repo — when the user asks for a shareable skill)143144Use only when the user explicitly wants the skill shared via the plugin. Do145NOT default to this path for autonomous creation.1461471. Steps 1–6 same as above, but with `~/code/skills/skills/<name>/` as the148 target dir. Skip step 7 (no `.agent-created` marker on a curated skill).1491502. **Register the skill in `.claude-plugin/plugin.json`** (REQUIRED — skills151 are an explicit allowlist; an unlisted dir is silently ignored):152 ```bash153 ~/code/skills/skills/skill-manage/scripts/registry.sh register <name>154 ```1551563. **Commit and push** the public repo:157 ```bash158 cd ~/code/skills159 git add skills/<name>/ .claude-plugin/plugin.json160 git commit -m "skills/<name>: <summary>161162 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>"163 git push origin main164 ```1651664. **Refresh the plugin cache** so the new skill loads:167 ```bash168 git -C ~/.copilot/installed-plugins/_direct/dfrysinger--skills pull --ff-only169 ```170 Then `/restart` (or `/skills reload` is not enough for plugin changes).171172If the skill already exists in the LOCAL root and you just want to publish it,173use `~/code/skills/skills/skill-manage/scripts/promote-skill.sh <name>` instead174— it moves, strips provenance, registers, and commits both repos.175176## Pitfalls177178- **Forgetting that LOCAL and PUBLIC have different rules.** Local skills need179 no `plugin.json` entry and never get pushed. Public skills require180 registration and a plugin-cache refresh. Don't apply the public workflow to181 a local skill (you'll fail at `git push` since there's no remote).182- **Description that doesn't trigger.** If your description doesn't include183 concrete keywords for when to load the skill, the agent will never pick it.184 Re-read rule 1.185- **Skill that duplicates an existing capability.** Before creating, glob186 `~/code/skills/skills/**/SKILL.md` AND `~/.copilot/skills/**/SKILL.md` for187 overlap. Better to extend an existing skill via `skill-manage patch` than to188 create a near-duplicate.189- **Auto-create spam.** The auto-create trigger in `copilot-instructions.md`190 is a *proposal* (Tier 1) or contained autonomous (Tier 2 daemon). The bar191 is: "would I want to invoke this same procedure again next month?"192- **Vendoring third-party skills.** When importing externally-authored skills,193 copy them verbatim, pin the source commit, preserve the license, and add a194 `NOTICE.md` (see `~/code/skills/skills/NOTICE.md` for the existing example).195196## Verification197198After completing the procedure, the new skill should:1992001. Exist at `~/.copilot/skills/<name>/SKILL.md` (LOCAL) or201 `~/code/skills/skills/<name>/SKILL.md` (PUBLIC)2022. Pass `validate-skill.sh` with zero errors2033. For PUBLIC only: be listed in `.claude-plugin/plugin.json` `.skills[]`2044. Be committed in its owning repo2055. Appear as `/<name>` after `/skills reload` (LOCAL) or `/restart` after206 plugin cache refresh (PUBLIC)207208If any of these fail, the skill is not done — fix and re-validate.209210---211> Source: [dfrysinger/skills](https://github.com/dfrysinger/skills) — distributed by [TomeVault](https://tomevault.io).212<!-- tomevault:4.0:skill_md:2026-06-16 -->