Skill Authoring¶
Package Structure¶
A skill package is a zip archive with this layout:
my-skill.zip
├── metadata.json # Required — skill identity and schema
├── instructions.md # Required — agent-facing instructions
├── scripts/ # Optional — executable scripts
│ └── run.sh
└── deps.txt # Optional — pip-compatible dependencies
metadata.json¶
Every skill package must include a metadata.json at the root.
Required Fields¶
| Field | Type | Description |
|---|---|---|
skill_format_version |
int |
Must be 1 |
name |
string |
Lowercase alphanumeric with hyphens (^[a-z0-9][a-z0-9-]*$) |
version |
string |
Semantic version (major.minor.patch) |
description |
string |
What the skill does (1-500 chars) |
content_hash |
string |
SHA-256 hex digest of the package contents (64 chars) |
Optional Fields¶
| Field | Type | Description |
|---|---|---|
author |
string |
Author or team name |
tags |
string[] |
Tags for categorisation |
dependencies |
string[] |
Other skill slugs this skill depends on |
runtime_requirements |
object |
min_tier (basic/codeready/mesh/terminal/browser/desktop/full), python_version |
Example¶
{
"skill_format_version": 1,
"name": "code-review",
"version": "1.0.0",
"description": "Reviews code for quality, style, and correctness.",
"content_hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"author": "ConflictHQ",
"tags": ["review", "quality"],
"runtime_requirements": {
"min_tier": "codeready"
}
}
instructions.md¶
Markdown file with agent-facing instructions. This is what the agent reads when the skill is loaded. Write it as if you are briefing someone who has never seen the task before.
Creating a Skill¶
1. Create the skill record¶
curl -X POST http://localhost:8000/api/v1/skills/ \
-H "Content-Type: application/json" \
-H "Authorization: Token YOUR_TOKEN" \
-d '{
"name": "code-review",
"category": "tool",
"description": "Reviews code for quality.",
"instructions": "Review the provided code for bugs, style issues, and correctness."
}'
2. Write the package files¶
mkdir code-review && cd code-review
cat > metadata.json << 'EOF'
{
"skill_format_version": 1,
"name": "code-review",
"version": "1.0.0",
"description": "Reviews code for quality, style, and correctness.",
"content_hash": "PLACEHOLDER"
}
EOF
cat > instructions.md << 'EOF'
# Code Review
Review the provided code for:
- Bugs and logic errors
- Style and naming conventions
- Security vulnerabilities
- Performance concerns
Provide specific, actionable feedback with line references.
EOF
3. Compute the content hash¶
The content_hash is the SHA-256 of all files in the package except metadata.json itself, concatenated in sorted order:
shasum -a 256 instructions.md scripts/* deps.txt 2>/dev/null \
| sort | shasum -a 256 | cut -d' ' -f1
Update metadata.json with the computed hash.
4. Package as a zip¶
5. Upload via API¶
curl -X POST http://localhost:8000/api/v1/skills/code-review/upload/ \
-H "Authorization: Token YOUR_TOKEN" \
-F "file=@code-review.zip"
Response:
{
"slug": "code-review",
"storage_ref": "skills/code-review/e3b0c44..zip",
"content_hash": "e3b0c44...",
"version_number": 1,
"deduplicated": false
}
Versioning and Updates¶
Upload a new zip to the same skill slug. The system auto-increments the version number. If the content hash matches the latest version, the upload is deduplicated.
curl -X POST http://localhost:8000/api/v1/skills/code-review/upload/ \
-H "Authorization: Token YOUR_TOKEN" \
-F "file=@code-review-v2.zip"
Dynamic vs Baked-In Skills¶
Downloaded at agent boot time from object storage. Use when:
- Skills change frequently
- Different tasks need different skill versions
- You want to update skills without rebuilding agent images
The brief includes the storage_ref and content_hash. The agent entrypoint downloads and verifies.
Pre-installed in the agent Docker image. Use when:
- The skill is core to the agent tier
- Download latency matters (large skill packages)
- Offline / air-gapped environments
Add to the agent Dockerfile:
The agent entrypoint detects baked-in skills by checking for /agent/skills/{slug}/package/. If present, it skips the download and optionally verifies the content hash.
A brief can reference both baked-in and dynamic skills. The agent handles each independently.
Example Skills¶
Minimal: hello-world¶
{
"skill_format_version": 1,
"name": "hello-world",
"version": "1.0.0",
"description": "A minimal example skill that greets the user.",
"content_hash": "7d1a54127b222502f5b79b5fb0803061152a44f92b37e23c6527baf665d4da9a"
}
With Dependencies: data-pipeline¶
data-pipeline/
├── metadata.json
├── instructions.md
├── scripts/
│ ├── validate.py
│ └── transform.py
└── deps.txt
{
"skill_format_version": 1,
"name": "data-pipeline",
"version": "2.1.0",
"description": "Validates and transforms structured data files.",
"content_hash": "abc123...",
"author": "Data Team",
"tags": ["data", "etl", "validation"],
"dependencies": ["hello-world"],
"runtime_requirements": {
"min_tier": "codeready",
"python_version": ">=3.12"
}
}
Validation¶
The upload endpoint validates packages before accepting them:
- Must be a valid zip file
- Must contain
metadata.jsonandinstructions.mdat the root metadata.jsonmust conform to the schema (required fields, valid semver, valid name format)- Compressed size limit: 50 MB
- Uncompressed size limit: 200 MB
- Unknown fields in metadata are rejected
Validation errors
Validation errors return HTTP 400 with a descriptive message. Fix the issue and re-upload.