Claude Code skills are SKILL.md files with instructions the agent loads when a task needs them. A plugin packages skills, agents and hooks as one unit you install in many repositories. We ship ours as one plugin, wizrd (our internal Claude Code plugin and CLI, not public), enabled in the committed settings of a repository, and a validator in CI fails the repository when a skill is broken.
That setup came out of a mess: copies of the same skills in several repositories, each slowly different. Below is how skills and plugins work, how we load one plugin everywhere, and what broke along the way.
I run everything through Claude Code. Around it I define the system: skills, agents, memory, rules. It works like an operating system.
Filip Papranec
Founder, Digitaliko
What are Claude Code skills and plugins?
A skill is a folder with one file, SKILL.md. On top sits frontmatter with a name and a description, under it the instructions. The Claude Code docs say it plainly: skill descriptions are loaded into context so Claude knows what is available, and the full skill content only loads when it is used. You can also run a skill yourself as /name.
A plugin is a directory of skills, agents, hooks or MCP servers that Claude Code installs and loads as one unit. Its manifest sits in .claude-plugin/plugin.json. Plugin skills get a namespace, so our review skill runs as /wizrd:review and never collides with a project's own /review.
Where each piece belongs:
Piece
What it is
When it loads
Can the agent skip it?
CLAUDE.md
Rules and context for the repository
Every session, in full
Yes, it is text
Skill
Instructions for one kind of task
Description always, body when used
Yes, it is text
Hook
A command on an event, such as before a Bash call
On its event
No, it runs below the agent
Plugin
A package of skills, agents, hooks and MCP servers
When enabled, in every session
Its hooks no, its skills yes
The last column matters most. A skill tells the agent how to do a task well. It does not force anything. What must hold goes into a hook, a lint rule or CI.
Why did we put all our skills into one plugin?
Our company repository holds every client and service repository as a submodule. A session started inside a client repository did not see the company's skills, because Claude Code looks for project skills only up to the root of the repository it is in.
So the skills were copied. Several client repositories carried their own versions of plan, execute and review. When we compared them, every copy had diverged from the others. Nobody decided that. It just happened, one small fix at a time, in one repository and not in the next.
The fix was not more discipline. It was one plugin that loads everywhere. Since then, a session in the company repository, a client repository or a service repository gets the same skills, agents and hooks. A change lands in one PR, and the old copies were deleted in companion PRs.
How does one plugin load in every repository?
A plugin needs a home, called a marketplace. That is just a .claude-plugin/marketplace.json file that lists plugins and where to fetch each one. Ours lists one plugin, the repository itself:
The repository that uses it enables the plugin in its committed .claude/settings.json. This is the real block from our company repository, where the plugin repo is a submodule at services/wizrd:
Search every repository for skill folders and commands with the same name. Diff them. That shows what drifted.
02
One plugin repository
Move the best version of each skill into skills/, add .claude-plugin/plugin.json and a marketplace file.
03
Enable it per repository
enabledPlugins and the marketplace in the committed .claude/settings.json, so a new teammate gets it with the clone.
04
Delete the copies
In the same week, not later. A copy that stays is the next drift.
05
Validate in CI
A check that fails the repository when a skill has no name, no description or no audience.
Hooks travel the same way. Our plugin ships a SessionStart greeting and two PreToolUse hooks on Bash: one blocks AI attribution in commits and PRs, one blocks pushes the operator may not make. Their paths start with ${CLAUDE_PLUGIN_ROOT}, so they resolve in every repository. Why that matters is in Claude Code hooks that silently do nothing.
What does a skill need to work for a team?
Less than we first thought. A real frontmatter from our plugin, with the description shortened:
---
name: issue
description: Create GitHub issues at the right level following the canonical labels and issue-body spec. Triggers on /wizrd:issue, gh issue, file issue, create issue, log a task.
allowed-tools: Bash, Read
audience: both
---
Three fields carry the weight:
description with real trigger words. The model decides from this line whether to load the skill. "Helps with issues" loads at random. The words people actually type load it when they should.
audience: human, agent or both. It is our own field, not a Claude Code one. A skill an agent runs alone must never wait for a person. Our validator warns when a skill marked agent or both asks a popup question or waits for approval. An agent asks on GitHub instead.
Clear names. Two of our skills once differed by one letter and did opposite things. We renamed them.
For a while we also required fixed sections in every skill: a playbook, a quality gate, decision authority. They mostly restated the body. We dropped the requirement and cut the skills down to the instructions that change behaviour. Now the validator asks only for name, description and audience.
What broke along the way?
Most of it was quiet. Things passed while they no longer checked anything.
A rename that would have passed CI forever. Once the plugin gave us a namespace, the old prefix on every skill name was redundant, so we dropped it. Our check for references to deleted skills had that prefix hardcoded in its regex. Left alone, it would have matched nothing after the rename and stayed green forever.
The validator called live skills stale. It built its list of skills from a local folder. After the move into the plugin, a client repository that mentioned plan or review had nothing local to match, and its CI went red. The fix was to read the plugin's own skills too.
Skills nobody used. Some skills had not run for months. Each one still sat in context on every turn, because a plugin's skill names and descriptions are always loaded. We deleted them. Three variants of one skill became one skill with modes, and our own skill for writing skills went in favour of the built-in skill-creator.
Is it perfect? No. Sometimes I overcomplicate things.
Filip Papranec
Founder, Digitaliko
Most of these fixes were deletions. That is the pattern we keep seeing: a shared plugin makes waste visible, because everyone now carries it in every session.
Personal or shared: which skills belong in the plugin?
Not every skill has to be shared. How one person likes to work can stay in their own ~/.claude/skills/. What the whole team depends on belongs in the plugin: planning, review, opening issues, the steps a client release goes through.
Personal rules are a style of work. Everyone can work the way they prefer. The shared ones belong to the company.
Filip Papranec
Founder, Digitaliko
Our plugin is internal, so you cannot install it. Our public Claude Code production starter has no skills. It carries the layer below them: agent rules, hooks and a CI gate. That is where we would start.
We set up skills, hooks, rules and CI right in a team's repositories as part of AI-native SDLC for development teams. Is your team short of hands rather than rules? See a senior developer for your team. AI writes all of our code today, and a senior is accountable for the result. Since 2023 we have delivered 15+ production projects.
We get back to you within two business days, and together we pick what to fix first.
A skill is a folder with a SKILL.md file: frontmatter with a name and a description, then instructions. Claude Code keeps the description in context and loads the full instructions only when a task needs them, or when you run the skill as /name.
What is the difference between a skill and a plugin?
A skill is one set of instructions. A plugin is a directory that packages skills, agents, hooks and MCP servers as one unit, with a manifest in .claude-plugin/plugin.json. Plugin skills are namespaced, so ours run as /wizrd:review.
How do I share Claude Code skills with my team?
Put them in a plugin, list the plugin in a marketplace and enable it in the committed .claude/settings.json of each repository. Everyone gets the same version, and a change lands everywhere in one PR instead of in copies that drift apart.
Do many skills slow Claude Code down?
Each skill the model can call on its own keeps its name and description in context on every turn. That costs tokens even when nothing runs. We delete skills nobody uses and keep descriptions short and specific.
Should a skill replace hooks or CI checks?
No. A skill is instructions the agent may follow. Anything that must hold goes into a hook, a lint rule, a test or CI, where the agent cannot skip it.
Ask AI about this article
The AI also draws on our other articles and experience from real projects.
Most Claude Code tips are written by solo users. These seven are team practices: a short CLAUDE.md that CI keeps short, one shared plugin, permissions and hooks in the repo, one issue to one PR, a test that fails first and a reviewer that did not write the code.
Claude Code subagents split work inside one session, worktrees isolate file edits. Our rule from running parallel agents every day: subagents only read, every change gets its own worktree and PR. What broke, and how to start.
Cursor vs Claude Code for a team, not a benchmark: Cursor is an editor with an agent inside, Claude Code is an agent that runs the same on a laptop, in CI and in a background loop. Why our whole harness runs on Claude Code, and when Cursor is the better pick.