Skill creator - knowledge skill for LLM to create skills
This commit is contained in:
237
SKILL.md
Normal file
237
SKILL.md
Normal file
@@ -0,0 +1,237 @@
|
|||||||
|
---
|
||||||
|
name: skill-creator
|
||||||
|
description: Instructions for creating new VibeStack skills
|
||||||
|
metadata:
|
||||||
|
version: "1.0.0"
|
||||||
|
vibestack:
|
||||||
|
main: false
|
||||||
|
type: knowledge
|
||||||
|
---
|
||||||
|
|
||||||
|
# Skill Creator
|
||||||
|
|
||||||
|
This document teaches you how to create new VibeStack skills.
|
||||||
|
|
||||||
|
## Before Creating a Skill
|
||||||
|
|
||||||
|
1. **Check if it exists**: Query Gitea API to see if skill already exists
|
||||||
|
```bash
|
||||||
|
curl -s "https://git.vibe-overflow.com/api/v1/repos/azat/{skill-name}" | jq '.id'
|
||||||
|
```
|
||||||
|
If returns an ID, skill exists. Don't recreate.
|
||||||
|
|
||||||
|
2. **Check installed skills**: Look in `/skills/` directory
|
||||||
|
```bash
|
||||||
|
ls /skills/
|
||||||
|
```
|
||||||
|
|
||||||
|
## Skill Structure
|
||||||
|
|
||||||
|
Every skill needs:
|
||||||
|
|
||||||
|
```
|
||||||
|
skill-name/
|
||||||
|
├── SKILL.md # Required: metadata + documentation
|
||||||
|
└── scripts/
|
||||||
|
├── autorun.sh # Optional: install dependencies
|
||||||
|
└── run.sh # Optional: start service (if skill runs continuously)
|
||||||
|
```
|
||||||
|
|
||||||
|
## SKILL.md Format
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
name: skill-name
|
||||||
|
description: One-line description of what it does
|
||||||
|
metadata:
|
||||||
|
version: "1.0.0"
|
||||||
|
vibestack:
|
||||||
|
main: false # true only for the main orchestrator
|
||||||
|
requires: # optional dependencies
|
||||||
|
- other-skill
|
||||||
|
metrics-port: 8080 # optional, if exposes metrics
|
||||||
|
type: knowledge # optional, for non-running skills
|
||||||
|
---
|
||||||
|
|
||||||
|
# Skill Name
|
||||||
|
|
||||||
|
Longer description of what the skill does.
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
| Variable | Default | Description |
|
||||||
|
|----------|---------|-------------|
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
How to use the skill...
|
||||||
|
```
|
||||||
|
|
||||||
|
## autorun.sh Pattern
|
||||||
|
|
||||||
|
Runs once when skill is loaded. Must be **idempotent**.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Idempotent installation
|
||||||
|
install_something() {
|
||||||
|
if command -v something &>/dev/null; then
|
||||||
|
echo "something already installed"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Installing something..."
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y something
|
||||||
|
echo "something installed"
|
||||||
|
}
|
||||||
|
|
||||||
|
install_something
|
||||||
|
|
||||||
|
echo "Skill setup complete"
|
||||||
|
```
|
||||||
|
|
||||||
|
## run.sh Pattern
|
||||||
|
|
||||||
|
Runs the service. Use `exec` to replace shell.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
PORT="${SKILL_PORT:-8080}"
|
||||||
|
|
||||||
|
echo "Starting service on port $PORT..."
|
||||||
|
exec some-command --port "$PORT"
|
||||||
|
```
|
||||||
|
|
||||||
|
### For HTTP APIs (bash + socat)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
PORT="${SKILL_PORT:-8080}"
|
||||||
|
|
||||||
|
# Create handler script
|
||||||
|
cat > /tmp/handler.sh << 'HANDLER'
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
read -r request_line
|
||||||
|
method=$(echo "$request_line" | cut -d' ' -f1)
|
||||||
|
path=$(echo "$request_line" | cut -d' ' -f2)
|
||||||
|
|
||||||
|
# Read headers
|
||||||
|
while read -r header; do
|
||||||
|
header=$(echo "$header" | tr -d '\r')
|
||||||
|
[ -z "$header" ] && break
|
||||||
|
done
|
||||||
|
|
||||||
|
send_response() {
|
||||||
|
local status="$1" body="$2"
|
||||||
|
printf "HTTP/1.1 %s\r\nContent-Type: application/json\r\nContent-Length: %d\r\n\r\n%s" \
|
||||||
|
"$status" "${#body}" "$body"
|
||||||
|
}
|
||||||
|
|
||||||
|
case "$path" in
|
||||||
|
/health) send_response "200 OK" '{"status":"ok"}' ;;
|
||||||
|
*) send_response "404 Not Found" '{"error":"not found"}' ;;
|
||||||
|
esac
|
||||||
|
HANDLER
|
||||||
|
chmod +x /tmp/handler.sh
|
||||||
|
|
||||||
|
echo "Starting HTTP server on port $PORT..."
|
||||||
|
exec socat TCP-LISTEN:$PORT,reuseaddr,fork EXEC:/tmp/handler.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## Creating and Pushing a New Skill
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Create directory
|
||||||
|
mkdir -p /skills/new-skill/scripts
|
||||||
|
|
||||||
|
# 2. Write SKILL.md
|
||||||
|
cat > /skills/new-skill/SKILL.md << 'EOF'
|
||||||
|
---
|
||||||
|
name: new-skill
|
||||||
|
description: What it does
|
||||||
|
metadata:
|
||||||
|
version: "1.0.0"
|
||||||
|
vibestack:
|
||||||
|
main: false
|
||||||
|
---
|
||||||
|
|
||||||
|
# New Skill
|
||||||
|
|
||||||
|
Documentation...
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# 3. Write scripts (if needed)
|
||||||
|
cat > /skills/new-skill/scripts/autorun.sh << 'EOF'
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
echo "Setup complete"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# 4. Create repo on Gitea
|
||||||
|
curl -X POST "https://git.vibe-overflow.com/api/v1/user/repos" \
|
||||||
|
-H "Authorization: token $GIT_TOKEN" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"name":"new-skill","private":false,"description":"What it does"}'
|
||||||
|
|
||||||
|
# 5. Initialize git and push
|
||||||
|
cd /skills/new-skill
|
||||||
|
git init
|
||||||
|
git add .
|
||||||
|
git commit -m "Initial skill implementation"
|
||||||
|
git branch -M main
|
||||||
|
git remote add origin "https://${GIT_USER}:${GIT_TOKEN}@git.vibe-overflow.com/${GIT_USER}/new-skill.git"
|
||||||
|
git push -u origin main
|
||||||
|
```
|
||||||
|
|
||||||
|
## Validation Checklist
|
||||||
|
|
||||||
|
Before pushing, verify:
|
||||||
|
|
||||||
|
- [ ] SKILL.md exists with valid YAML frontmatter
|
||||||
|
- [ ] `name` in frontmatter matches directory name
|
||||||
|
- [ ] `description` is set
|
||||||
|
- [ ] If has autorun.sh, it's idempotent (can run multiple times)
|
||||||
|
- [ ] If has run.sh, it uses `exec` for the main process
|
||||||
|
- [ ] No hardcoded secrets (use environment variables)
|
||||||
|
- [ ] Repo doesn't already exist on Gitea
|
||||||
|
|
||||||
|
## Common Patterns
|
||||||
|
|
||||||
|
### Installing apt packages
|
||||||
|
```bash
|
||||||
|
apt-get update && apt-get install -y package-name
|
||||||
|
```
|
||||||
|
|
||||||
|
### Installing from GitHub releases
|
||||||
|
```bash
|
||||||
|
VERSION="1.0.0"
|
||||||
|
curl -sSL "https://github.com/org/repo/releases/download/v${VERSION}/binary" -o /usr/local/bin/binary
|
||||||
|
chmod +x /usr/local/bin/binary
|
||||||
|
```
|
||||||
|
|
||||||
|
### Reading environment with defaults
|
||||||
|
```bash
|
||||||
|
PORT="${SKILL_PORT:-8080}"
|
||||||
|
HOST="${SKILL_HOST:-0.0.0.0}"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Exporting for other skills
|
||||||
|
```bash
|
||||||
|
mkdir -p /run/vibestack
|
||||||
|
echo "SOME_URL=http://localhost:$PORT" > /run/vibestack/skill-name.env
|
||||||
|
```
|
||||||
|
|
||||||
|
## Environment Variables Available
|
||||||
|
|
||||||
|
- `SKILLS_DIR` - Skills directory (default: `/skills`)
|
||||||
|
- `GIT_HOST` - Git server (default: `git.vibe-overflow.com`)
|
||||||
|
- `GIT_USER` - Git user (default: `azat`)
|
||||||
|
- `GIT_TOKEN` - Git auth token
|
||||||
Reference in New Issue
Block a user