Skip to content
Back to skills

Create Skill

ASecurity

Guide for creating a new agent skill in this project — one SKILL.md under .agents/skills/ that Claude Code, GitHub Copilot and Codex all read, portable frontmatter, bundled scripts, and the symlink refresh step. Use when asked to convert knowledge into a skill, create a slash command, or add a new skill file.

  • 3 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 22, 2026
ai-agentsgoshellbashnodegitapi

Works with

  • claude code
  • cli
  • api

Security analysis

A100/100

Scanned October 6, 2026

npx -y skills add owlmeans/common --skill create-skill --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Create Skill?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Create Skill
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/owlmeans-create-skill/badge)](https://www.skillsdirectory.com/skills/owlmeans-create-skill)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: create-skill
description: Guide for creating a new agent skill in this project — one SKILL.md under .agents/skills/ that Claude Code, GitHub Copilot and Codex all read, portable frontmatter, bundled scripts, and the symlink refresh step. Use when asked to convert knowledge into a skill, create a slash command, or add a new skill file.
---

# Creating an agent skill

Skills live in `.agents/skills/<skill-name>/SKILL.md` — one directory per skill, one copy for
every agent. This is the [Agent Skills](https://agentskills.io) standard location: GitHub Copilot
and Codex read it natively, and Claude Code reads it through the generated per-skill symlinks in
`.claude/skills/`.

**Never** author a per-agent copy: no `.github/instructions/<name>.instructions.md`, no
`.github/copilot-instructions.md`, no `.github/skills/`, and no real files under `.claude/skills/`
or `.agents/linked-skills/` — both of those are generated and gitignored.

## Naming

The directory name is the skill's identity: frontmatter `name` must equal it, and it is what an
agent types to load the skill. Lowercase, hyphens, ≤ 64 chars.

A local skill **shadows** an upstream one of the same name — `link-skills.sh` links a dependency's
skill only when no local skill claims the name. So a local skill named after an `@owlmeans` package
(`resource`, `web-client`, `auth`, …) hides that package's own guidance for the whole repo. Name
a skill after the concern it covers, never after a package this project consumes.

A skill also shadows a **Claude Code built-in slash command** of the same name: with a skill called
`context`, typing `/context` loads the skill instead of the context-usage view — in every repo that
links or installs it, and nothing reports it. Never name a skill after a built-in command, one of its
aliases (`/settings` is `/config`, `/cost` is `/usage`) or a bundled skill (`/loop`, `/simplify`);
type `/` in a Claude Code session to see the taken names. A skill about a package whose name is taken
carries the `owlmeans-` prefix — `owlmeans-context` for `@owlmeans/context`, `owlmeans-config` for
`@owlmeans/config`. The OwlMeans release harness refuses a colliding canonical skill name
(`sync-agent-meta` exit 14).

## File structure

```
.agents/skills/<skill-name>/
├── SKILL.md          # Required — entrypoint with frontmatter + instructions
├── reference.md      # Optional — detailed reference docs
├── examples.md       # Optional — usage examples
└── scripts/          # Optional — bundled shell scripts the skill runs
    └── <name>.sh
```

## Skills with scripts

A bundled script lives in exactly one place: `.agents/skills/<name>/scripts/<script>.sh`. Every
agent can reach it from the repo root, so there is no second copy to keep in sync.

1. Place the script in `.agents/skills/<name>/scripts/<script>.sh` and `chmod +x` it.
2. Document the invocation in the SKILL.md body under a "Script reference" section, using the
   repo-root-relative path.
3. Set `allowed-tools: Bash(sh *)` in frontmatter so the script runs without a prompt.

## SKILL.md frontmatter

```yaml
---
name: skill-name                  # REQUIRED — must equal the directory name (lowercase, hyphens, ≤64 chars)
description: What it does and when to use it   # REQUIRED — ≤1024 chars; the auto-invocation signal
allowed-tools: Bash(bun *), Read  # comma-separated; tools usable without per-call approval
disable-model-invocation: true    # set true for side-effect tasks (deploy, commit)
user-invocable: false             # set false for background knowledge only
metadata:                         # anything non-standard goes here
  scope: general
---
```

The `description` is the field everything turns on: every agent reads it to decide when to load
the skill, so state both the topic and the trigger ("Use when …"). It is YAML, so a value
containing `: ` (colon-space) has to be quoted — unquoted, the file stops parsing and the skill
silently disappears from every agent. Keep it under 1024 characters; Copilot rejects longer ones.

| Field | Use when |
|---|---|
| `name` | Always — must match the directory name, or Copilot rejects the skill |
| `description` | Always — primary signal for when an agent loads the skill; keep under 1024 chars |
| `allowed-tools` | Skill needs to run specific commands without prompting — a comma-separated list |
| `disable-model-invocation: true` | Skill has side effects (git push, deploy, etc.) — the operator invokes it manually |
| `user-invocable: false` | Skill is background knowledge, not an action — hide from the `/` menu |
| `metadata.scope: general` | Skill is cross-cutting and ships with the `@owlmeans/agent-skills` installer — auto-routes to the installer bundle and is never pruned by a sync run |
| `argument-hint` | Skill takes arguments — show hint in autocomplete |

Six fields are portable: `name`, `description`, `license`, `compatibility`, `allowed-tools` and
nested `metadata` — exactly what the Agent Skills frontmatter parser in `@owlmeans/agent-skills`
reads. `user-invocable`, `disable-model-invocation` and `argument-hint` are understood by Claude
Code and Copilot; use them only when the skill genuinely needs them. Everything else, including
project-specific routing markers such as `scope: general`, belongs under `metadata:`.

Write `allowed-tools` as a comma-separated list (`Bash(bun *), Read`), a flow sequence
(`[Bash(bun *), Read]`), or an indented `- ` block. The parser breaks entries on commas, newlines
and `- ` only — never on a bare space — so `Bash(bun *) Read` is read as one tool whose name is
`Bash(bun *) Read`. `@owlmeans/agent-skills` keeps the parsed list advisory and enforces no tool
policy itself; the agent running the skill is what honours it.

## Decision guide

| Scenario | Approach |
|---|---|
| Project-specific CLI/build knowledge | Skill, no `disable-model-invocation` (let the agent auto-use it) |
| Side-effect workflow (commit, deploy) | `disable-model-invocation: true` |
| Background reference only | `user-invocable: false` |

## What may enter AGENTS.md

`AGENTS.md` — with every file it `@`-imports and `.agents/memory/MEMORY.md` — is loaded in full in
every session, so it has a budget: **≤ 40 000 chars**, checked by `sh .agents/scripts/agents-size.sh`
from the repo root. A line enters it only as:

1. a mandatory rule that must hold before any skill is loaded (git, reporting, environments,
   naming, code structure) — stated in one or two lines, with the detail in a skill;
2. one line of the package map or the command list;
3. one line of the skills index: `` - `/name` — when to load it ``, ≤ 160 chars.

Everything else is loaded on demand: a subsystem's rules, contracts and failure fingerprints go to
the skill that governs it, and the outage that taught them to `.agents/memory/`. Never paraphrase a
skill's `description:` into the index — skills self-describe. A change that would push the file over
budget shortens or moves an existing line in the same change.

## After creating a skill

1. Run `sh .agents/scripts/link-skills.sh` — Claude Code cannot see the skill until the symlink
   exists. The same run refreshes the dependency links in `.agents/linked-skills/`, so a new local
   skill immediately shadows an upstream one of the same name. A committed `SessionStart` hook runs
   the script too, as does the root `package.json` `prepare` script where the repo has one — so the
   links also refresh at session start and on install.
2. Remove any redundant `.agents/<topic>.md` file the skill replaces.
3. If the skill distilled memory content into rules, shrink the source `.agents/memory/` node to a
   pointer line (`memory-promotion` where present) — the memory index does not list skills.
4. Add one line to the skills index in `AGENTS.md` (`/name` — when to load it, ≤ 160 chars) — never a paragraph (§ What may enter AGENTS.md).
5. Test by typing `/skill-name`.

## Package README next to the skill

A package skill is for agents; `packages/<pkg>/README.md` is the npm-facing page for people, and it
is built from the same sources — the skill, `src/index.ts` and real downstream usage. An
application-facing package (one the root `README.md` lists under "Application packages") keeps this
shape:

1. Title, then one paragraph on when an app uses the package and what to use instead.
2. `## Installation` — the pin line is tooling-managed (`versions`); never hand-edit it.
3. `## Concepts` — the package's own terms, 3–6 bullets.
4. `## Usage` — 3–5 progressively richer examples that import only symbols the package really
   exports, written protocol-first and with `entitySlug`/`entityId` naming.
5. `## API` — the full public export list, subpath exports included.
6. `## Common pitfalls` — the skill's rules as short bullets.
7. `## Related packages`, then the generated `owlmeans:agent-guidance` block, left byte-identical.

A supporting package may keep a shorter README, but it still states purpose, install and one
working example. Promoting a package to "Application packages" in the root README means bringing
its README to the full shape in the same change.

## Skill vs memory file

- **Skill**: reusable procedure or reference that benefits from being a slash command, or that an
  agent should load automatically based on context
- **Memory node** (`.agents/memory/*.md`): fact-shaped knowledge per the `agent-memory` protocol;
  procedure-shaped or repeatedly-touched memory promotes into a skill (`memory-promotion` where
  present)
- **Never paste memory text into a skill** — restate it as a general rule (trigger → step → the
  failure it prevents), stripping dates, phase/status markers, versions and incident narrative
  (`memory-promotion` → Distillation)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…