-
Notifications
You must be signed in to change notification settings - Fork 0
Creating a Custom Skill
A skill is a single SKILL.md file that teaches the agent how to perform a task. The agent reads it, runs the bash blocks in order, and uses the markdown prose to make decisions between steps.
skills/
└── my-skill/
└── SKILL.md
The folder name becomes the slash command: skills/drupal-cr/ → /drupal-cr.
---
name: my-skill
description: One-line description shown in the skills panel.
distribution: public
---
# my-skill
Brief explanation of what this skill does.
## Step 1 — Do something
```bash
echo "This runs as a bash script"
RESULT=$(some-command)
echo "RESULT=$RESULT"Interpret the output. If RESULT is empty, tell the user and stop.
echo "Step 2 bash"
### Frontmatter fields
| Field | Required | Description |
|---|---|---|
| `name` | Yes | Must match the folder name |
| `description` | Yes | Short description (shown in UI skills panel) |
| `distribution` | No | `public` makes it shareable; omit for private |
## How the agent reads SKILL.md
The agent processes the file top to bottom:
- **Bash blocks** — executed verbatim as shell scripts
- **Markdown prose** — read as instructions for reasoning and branching
- **Step headings** — signal distinct phases; the agent waits for bash output before proceeding
This means you can write conditional logic in prose:
```markdown
If `CONTAINER` is empty, tell the user the stack is not running and offer to run `/drupal-serve` first.
If `CONTAINER` is set, continue to Step 2.
The agent extracts parameters from the user's message and passes them as $1, $2, etc.:
MODULE="${1:-}"
if [[ -z "$MODULE" ]]; then
echo "❌ Provide a module name. Example: /drupal-install token"
exit 1
fiMost Drupal skills need to run commands inside the PHP container or fall back to local binaries. Use this pattern consistently:
PHP_CONTAINER=$(docker ps --filter "status=running" --format '{{.Names}}' 2>/dev/null | grep -E "drupal.*(php|fpm)" | head -1)
if [[ -n "$PHP_CONTAINER" ]]; then
DRUSH="docker exec -i -w /var/www/html $PHP_CONTAINER vendor/bin/drush"
elif [[ -x "vendor/bin/drush" ]]; then
DRUSH="vendor/bin/drush"
else
echo "❌ Drush not found. Is the stack running? Try /drupal-serve"
exit 1
fiTo let the agent branch based on detected state, emit a variable in the bash output and reference it in prose:
if [[ -d "/workspace/drupal" ]]; then
echo "PROJECT_EXISTS=true"
else
echo "PROJECT_EXISTS=false"
fiThen in the prose after the block:
If `PROJECT_EXISTS=true`, ask the user whether to overwrite before continuing.
If `PROJECT_EXISTS=false`, proceed directly to Step 2.Skills in skills/ are synced to config/.pi/skills/ at container startup via entrypoint.sh. After adding a new skill:
- Place
SKILL.mdinskills/my-skill/ - Restart the container:
docker compose restart - Test it: type
/my-skillin the chat
For immediate testing without restart, copy manually:
docker cp skills/my-skill/ docker-drupalclaw-1:/config/.pi/skills/---
name: drupal-version
description: Show the installed Drupal core version.
distribution: public
---
# drupal-version
Shows the Drupal core version.
## Step 1 — Get version
```bash
PHP_CONTAINER=$(docker ps --filter "status=running" --format '{{.Names}}' 2>/dev/null | grep -E "drupal.*(php|fpm)" | head -1)
if [[ -n "$PHP_CONTAINER" ]]; then
docker exec -i -w /var/www/html "$PHP_CONTAINER" vendor/bin/drush core:status --field=drupal-version
else
echo "❌ Stack not running. Start it with /drupal-serve"
fiShow the version to the user.