Skills are reusable, invokable instruction sets for Claude Code. They're how you package a multi-step workflow — with its context, examples, scripts, and edge cases — into a single slash command that works the same way every time. A well-written skill is better than a macro: it's instructions to an intelligent agent, not a fixed script.
A skill is a markdown file with frontmatter that Claude Code loads on demand via the Skill tool. When you invoke /graphify or /cut-subject, Claude Code finds the corresponding SKILL.md file, reads it into context, and follows its instructions exactly as written.
Skills are:
~/.claude/skills/ and is available in every repo you open.These skills are in active use and cover a range of complexity levels — from simple single-tool wrappers to multi-step pipelines with sub-agents:
Build knowledge graphs from any codebase or corpus. Runs entity extraction, relationship mapping, community detection, and produces an interactive HTML viewer + GraphRAG-ready JSON.
Background removal via rembg. Accepts image paths, handles batch processing, selects the right model for the subject type (person, object, product), and saves outputs with naming conventions.
Six-step pipeline for routing cross-repo and architecture questions through knowledge graphs. Intercepts before grep/glob, queries the appropriate graph registry entry, and returns a relevant subgraph.
Generates AI-themed quote memes. Takes a quote (or generates one), selects a background, styles the typography, and outputs a web-shareable image. Uses ComfyUI pipelines.
Captures embedded hardware test sessions as structured, graph-ingestible markdown logs. Auto-invokes after any bring-up or debug session concludes with a fix. Populates the hardware test graph.
Generates a non-destructive check-deps.sh audit script for any project being prepared for public release. Checks for all required system dependencies, prints friendly install instructions.
All skills live under ~/.claude/skills/, one subdirectory per skill:
A well-structured SKILL.md has six sections. Each serves a different purpose for the agent executing the skill.
YAML block at the top. Declares what the skill is called, what it does in one sentence, and the trigger conditions — both explicit slash commands and proactive invocation patterns.
Explicit trigger conditions and anti-patterns. This is what prevents false positives — the skill firing when you didn't ask for it. Be specific about the exact conditions that should trigger vs. similar-looking conditions that should not.
Numbered steps in imperative voice: "Run X", "Check Y", "If Z, do W". These are what Claude executes. Each step should be unambiguous — the agent shouldn't have to guess what you meant.
At least one end-to-end example showing typical usage. For complex skills, add examples for edge cases too. Examples are the most reliable way to encode expected behavior.
Explicit anti-patterns. What mistakes does a naive agent make without guidance? List them here. For the cut-subject skill, this might be "do not use the anime model on product photos."
What does done look like? What files should exist, what should be printed, what should the agent report back to the user? Explicit success criteria prevent the agent from stopping too early or doing extra work.
Walk through a real skill — background removal via rembg — from frontmatter to output format:
---
name: cut-subject
description: Remove backgrounds from images using rembg. Handles single files, batches, and model selection.
triggers:
- slash: /cut-subject
- proactive: when user asks to "remove background", "cut out subject", "make transparent"
---
# cut-subject — Background Removal Skill
## When to Use
Invoke when:
- User types `/cut-subject [path or paths]`
- User asks to "remove the background from this image"
- User asks to "cut out the subject" or "make the background transparent"
- User pastes an image path and mentions transparency, cutout, or compositing
Do NOT invoke when:
- User is asking about image generation (that's a different pipeline)
- User mentions "background" in a non-image context (e.g., "run this in the background")
- The file is not an image format (.jpg, .jpeg, .png, .webp, .heic)
## Models Available
| Model | Flag | Best for |
|-------|------|---------|
| u2net (default) | (none) | General subjects, objects |
| isnet-general-use | --model isnet | High-detail subjects, fine edges |
| u2net_human_seg | --model human | Portraits, people — much better for faces |
| silueta | --model silueta | Silhouettes, fashion/product shots |
## Steps
1. Identify the input file(s) from the user's message or arguments.
- If a directory is given, process all .jpg, .jpeg, .png, .webp files in it.
- If no path is given, ask the user for the image path.
2. Select the appropriate model:
- If the image contains a person or face → use u2net_human_seg
- If it's a product photo → use silueta
- Otherwise → use default (u2net)
- User can override with --model flag
3. Run rembg. Output file naming:
- Single file: same name + "_cutout" suffix, PNG format
- Batch: same directory, "_cutout" suffix on each, PNG format
4. Run the helper script:
```bash
python3 ~/.claude/skills/cut-subject/scripts/remove-bg.py \
--input [path] \
--output [output_path] \
--model [selected_model]
```
5. Verify output:
- Confirm output file exists
- Report file path and size to user
## Example
User: `/cut-subject ~/photos/product-shot.jpg`
Steps:
1. Input: ~/photos/product-shot.jpg
2. Model: silueta (product photo)
3. Output: ~/photos/product-shot_cutout.png
4. Run: python3 remove-bg.py --input ~/photos/product-shot.jpg --output ~/photos/product-shot_cutout.png --model silueta
5. Report: "Done. Saved to ~/photos/product-shot_cutout.png (1.2MB)"
## What NOT to Do
- Do not use the anime model on real-world photos — it produces poor edges
- Do not overwrite the original file — always add the _cutout suffix
- Do not process .gif files — rembg does not handle animated images
- Do not skip model selection — picking the right model matters significantly for quality
## Success Criteria
- Output PNG file exists at the expected path
- Output file size is non-zero
- User is told the exact output path
Claude Code discovers skills via the Skill tool, but you should also list them in your ~/.claude/CLAUDE.md so the agent knows they exist and when to invoke them proactively:
# ~/.claude/CLAUDE.md (excerpt)
# Skills
- **graphify** (`~/.claude/skills/graphify/SKILL.md`) — any input to knowledge graph. Trigger: `/graphify`
When the user types `/graphify`, invoke the Skill tool with `skill: "graphify"` before doing anything else.
- **cut-subject** (`~/.claude/skills/cut-subject/SKILL.md`) — background removal via rembg. Trigger: `/cut-subject`
Also invoke proactively when user asks to remove background from an image.
- **wyltek-test-log** (`~/.claude/skills/wyltek-test-log/SKILL.md`) — hardware test session logging.
Trigger: `/wyltek-log` or "log this test". Also invoke proactively after any wyltek-embedded-builder
bring-up/debug session concludes with a fix.
- **release-deps-check** (`~/.claude/skills/release-deps-check/SKILL.md`) — dep audit script generator.
Trigger: `/check-deps`. Also invoke proactively when prepping any project for public release.
When a skill needs to run a non-trivial shell operation repeatedly, put that operation in scripts/ and reference it from SKILL.md. The script does the mechanical work; the SKILL.md provides the decision-making context.
#!/usr/bin/env bash
# Generated by release-deps-check skill
# Non-destructive dependency audit — reads only, never installs
set -euo pipefail
REQUIRED_TOOLS=("PLACEHOLDER_TOOLS")
OPTIONAL_TOOLS=("PLACEHOLDER_OPTIONAL")
MIN_NODE="PLACEHOLDER_NODE_VERSION"
MIN_PYTHON="PLACEHOLDER_PYTHON_VERSION"
echo "=== Dependency Check ==="
echo ""
ALL_OK=true
for tool in "${REQUIRED_TOOLS[@]}"; do
if command -v "$tool" &>/dev/null; then
VERSION=$("$tool" --version 2>&1 | head -1)
echo " [OK] $tool — $VERSION"
else
echo " [MISSING] $tool — required. Install: PLACEHOLDER_INSTALL_$tool"
ALL_OK=false
fi
done
if [ "$ALL_OK" = true ]; then
echo ""
echo "All required dependencies found. Ready to run."
else
echo ""
echo "Missing dependencies detected. See above for install commands."
exit 1
fi
The SKILL.md for release-deps-check tells Claude to:
SKILL.md is read by an AI agent with judgment, not executed by bash. Write it the way you'd brief a competent developer on a new task: explain the goal, the constraints, the decisions they need to make, and what success looks like. The agent handles the rest.
| Vague (bad) | Specific (good) |
|---|---|
| When user mentions background | When user asks to remove image background or mentions "transparent PNG" with an image file |
| When user asks about graphs | When user types /graphify, OR when user asks to "build a knowledge graph from" a path |
| When user mentions testing | When user types /wyltek-log or when an embedded hardware debug session concludes with "fixed" or a confirmed flash |
Every skill should explicitly list what mistakes a naive agent would make. This is the highest-leverage section for preventing quality issues. If you've run the skill and seen it do something wrong once, document it here.
Don't build a skill that does background removal AND image resizing AND format conversion. Build three skills. Composability is more valuable than completeness — users can chain skills, but they can't split a monolithic skill.
Skills can instruct Claude to spawn sub-agents for parallel workloads. The graph-routing skill does this: it spawns a query agent against the graph while the main agent continues preparing context. The wyltek-test-log skill spawns a formatting agent to structure the log while the main agent ingests it into the RAG system.
## Steps (excerpt from a parallelised skill)
3. Spawn two sub-agents in parallel:
- Agent A: Query the CKB ecosystem graph for entities related to the failing component
- Agent B: Search the session logs from the past 7 days for similar symptoms
4. Wait for both agents to complete, then merge their findings before proceeding.
Note: Use the Agent tool with separate tasks. Do not wait for Agent A before launching Agent B.
Some skills maintain state between invocations via files in ~/.claude/. The wyltek-test-log skill appends to a structured log file that accumulates hardware test results across sessions. The save-session skill writes session summaries to ~/.claude/session-logs/.
## State management (from wyltek-test-log)
After writing the log entry:
1. Append to ~/.claude/shared/hardware-test-log.md (create if missing)
2. Ingest the new entry to the RAG system:
curl -X POST http://your-rag-server:9990/ingest \
-d '{"source": "hardware-test", "text": "CONTENT", "title": "TITLE"}'
3. Update ~/.claude/session-logs/last-hardware-session.txt with today's date
Skills and hooks are complementary. A hook can proactively trigger a skill (by writing to stdout on UserPromptSubmit), and a skill can configure hooks (by editing settings.json during setup). The release-deps-check skill, for example, can optionally install a PostToolUse hook that runs the check-deps.sh after every CI config change.
---
name: my-skill
description: One sentence: what this skill does.
triggers:
- slash: /my-skill
- proactive: when [specific condition]
---
# my-skill
## When to Use
Invoke when:
- User types `/my-skill [args]`
- [Specific proactive condition]
Do NOT invoke when:
- [Common false positive scenario 1]
- [Common false positive scenario 2]
## Steps
1. [First action — imperative voice]
2. [Second action]
3. If [condition], do [A], otherwise do [B].
4. [Final action]
## Example
User: `/my-skill some-argument`
Expected behavior:
- [What happens step by step]
- [What gets output]
- [What gets reported to user]
## What NOT to Do
- [Anti-pattern 1]
- [Anti-pattern 2]
## Success Criteria
- [What done looks like]
- [Specific file or output that must exist]
Skills can be packaged as Claude Code plugins for sharing with the ecosystem. A plugin is a directory with a plugin.json manifest, one or more SKILL.md files, and optional scripts. Users install plugins via the Claude Code plugin system and all skills in the plugin become immediately available.
# Plugin structure
my-plugin/
plugin.json # Manifest: name, version, description, author
skills/
skill-one/
SKILL.md
scripts/
helper.sh
skill-two/
SKILL.md
README.md
# plugin.json
{
"name": "wyltek-creative-skills",
"version": "1.0.0",
"description": "Image gen, TTS, and video skills for Wyltek Studio",
"author": "your-username",
"skills": ["cut-subject", "quote-meme", "tts-generate"]
}
| Check | Why |
|---|---|
| Frontmatter complete (name, description, triggers) | Required for discovery and proactive invocation |
| When to use section has explicit NOT-to-use cases | Prevents false positives |
| Steps are numbered and in imperative voice | Unambiguous for agent execution |
| At least one end-to-end example | Most reliable way to encode expected behavior |
| Success criteria defined | Agent knows when to stop |
| Registered in CLAUDE.md | Agent knows the skill exists and when to use it |
| Tested with an edge case | Edge cases reveal missing instructions |
| Anti-patterns documented from real failures | Prevents repeating mistakes |
See also: CLAUDE.md Guide · Hooks & Safety · Knowledge Graphs