knack
← all posts

GitHub Copilot Skills Make the Cross-Vendor SKILL.md Folder Real

Three major coding agents now read the same SKILL.md folder format. The author-once-deploy-everywhere pitch from October is finally infrastructure, not a handshake.

Three major coding agents now read the same SKILL.md folder format. GitHub Copilot skills shipped on December 18, 2025, joining Claude Code and OpenAI Codex on the agentskills.io spec. The "author once, deploy everywhere" pitch Anthropic's skills team made last fall is now real, not aspirational.

I tested it the next morning. Copied a skill out of github/awesome-copilot into a fresh repo's .github/skills/ directory, opened VS Code Insiders, typed a slash. The skill loaded. Same frontmatter, same body, same relative-path asset references that work in Claude Code. No translation step.

That's the whole story. The mechanics are what's worth a closer look.

What shipped on Dec 18

One sentence from the changelog post is worth quoting: "If you've already set up skills for Claude Code in the .claude/skills directory in your repository, Copilot will pick them up automatically." GitHub did not invent a new format. They adopted the one Anthropic published with Claude Code in October 2025, and they extended the lookup paths so existing skills work without moving files.

Copilot's main per-repo path is .github/skills/<skill-name>/SKILL.md. The agent also reads .claude/skills/ and .agents/skills/ from the repo root. User-level skills live at ~/.copilot/skills/, with ~/.claude/skills/ and ~/.agents/skills/ honored as fallbacks. Organization and enterprise-level scopes are listed as "coming soon" on the GitHub docs page.

Agent skills run across three Copilot surfaces: the cloud coding agent (the autonomous PR-opener), the Copilot CLI, and agent mode in VS Code. General VS Code support landed in early January after a brief Insiders window. The feature requires a paid plan: Pro, Pro+, Business, or Enterprise. Copilot Free does not get skills, which lines up with how GitHub gates the cloud agent in general.

The .github/skills/ convention up close

A skill is a directory. Inside the directory, a SKILL.md file. Frontmatter is YAML with two required fields:

---
name: webapp-testing
description: End-to-end Playwright tests for the customer dashboard. Use when the user asks to verify, smoke-test, or regression-check the dashboard UI.
---

name is lowercase alphanumeric plus hyphens, capped at 64 characters, and must match the parent directory. description is capped at 1024 characters and is the single most important field, because Copilot uses it to decide whether to auto-load the skill in response to a user prompt. Vague descriptions mean the skill never fires.

Below the frontmatter, prose. Instructions, examples, asset references via relative paths ([helper script](./run-tests.sh)). Anything in the folder is fair game for the model to read.

Four optional frontmatter fields are worth knowing. argument-hint populates the slash-command tab completion. user-invocable: false hides the skill from the slash menu while leaving auto-load on. disable-model-invocation: true does the opposite, forcing manual fire. context: fork is the interesting one. The skill runs in a subagent with its own context window, returning only its final result to the parent. Useful for skills that read many files or do long synthesis work, since it stops them from blowing up the parent's context.

These four fields are documented in the VS Code agent skills page and they are Copilot's only real departure from the base spec. Claude Code does not honor user-invocable or disable-model-invocation because Claude Code does not have a slash-menu vs auto-load distinction in the same way. The fields get ignored without errors. Portability holds.

The compatibility test

I ran the obvious experiment. Picked a curated skill from openai/skills, the OpenAI Codex catalog that launched in November. Copied the folder verbatim into .github/skills/ in a test repo. Opened the Copilot CLI. Asked it to do what the skill describes.

It worked. Not "mostly worked." Worked. Same instructions, same bundled assets, same model behavior, give or take the obvious fact that Copilot is running a different underlying model.

Then I ran it the other direction. Pulled a skill from awesome-copilot/skills/ and dropped it in .claude/skills/ in a separate repo. Claude Code loaded it on the next session. No edits.

This is what makes the open spec real. A spec two vendors implement is a handshake. A spec three vendors implement, with the largest developer-tools company on earth shipping it as a flagship feature, is infrastructure. The agentskills.io spec is now the de facto interchange format for agent instructions in the same way package.json is for Node dependencies.

What this means if you write skills

Three numbers tell the story. The awesome-copilot repo lists 208+ community skills. openai/skills ships dozens of curated ones plus a $skill-installer for adding more. The anthropics/skills repo has been seeded since October. A skill you write today, if you write it to the spec, runs on all three.

So write to the spec. One SKILL.md with the two required frontmatter fields, and a body that does not depend on tool names that only exist on one platform. Avoid hard-coding Bash vs Shell tool names in instructions. Reference assets by relative path. Keep the description action-oriented and specific so auto-load works. Skip the Copilot-only optional fields unless you actually need them. Claude Code and Codex ignore them without complaint, but the cleaner the file, the easier it is to share.

For deployment, the lowest-effort answer is to publish the same skill folder to three locations: .claude/skills/, .agents/skills/, and .github/skills/. This is the case I built Knack for. You write the skill once in a guided interview, and Knack produces one SKILL.md with the right frontmatter shape, ready to drop into any of the three paths. No reformatting, no per-vendor rewrite.

If you are maintaining a repo of skills for a team, you have one more decision: ship as a Git submodule, a package install, or a copy-paste. The awesome-copilot project ships its skills as a registered marketplace inside the Copilot CLI (copilot plugin install <name>@awesome-copilot), which is a thinly-disguised checkout into the right user-level directory. Codex has $skill-installer. Claude Code expects you to copy the folder or use a thin wrapper. None of this is standardized yet. The folder format is. The distribution channel is not.

A small note on the cloud agent

The Copilot coding agent, the cloud one that opens PRs from issues, picks up skills from your repo's .github/skills/ directory on every run. There is no separate config. No env var, no project setting in the GitHub UI, no per-agent install command. You commit the folder, the agent reads it. Cloud agents have historically been the hardest surface to customize, and "drop a folder in your repo" is the lowest-effort customization mechanism any cloud agent vendor has shipped so far. The same skill that runs locally in your IDE runs on the autonomous agent that submits PRs while you sleep, on the CLI you ssh into from a server, and in chat. One artifact, four surfaces.

Knack writes to that spec by default. One interview, one SKILL.md, three deploy targets.

The open question is which agent ships skills support next. Cursor and Windsurf both have agent modes. Neither has announced a SKILL.md loader. The format is open, the implementations are documented, and there are 208+ ready-to-load skills sitting in a public repo. I'd be surprised if they don't ship it by Q3.