Skills are reusable instruction sets that the agent loads on demand. A skill is a directory containing a SKILL.md file with optional YAML frontmatter and a markdown body of instructions. When the agent encounters a task that matches a skill, it loads the skill’s instructions into its context and follows them.
A skill is a dependency-free markdown file (SKILL.md) with optional frontmatter:
---
name: deploy-checks
description: Pre-deployment validation checklist for production releases
---
# Deploy Checks
Before deploying to production, verify ALL of the following:
1. **Tests pass**: Run `go test ./...` and ensure zero failures
2. **No debug logs**: `grep -rn "fmt.Println\|console.log" --include="*.go" --include="*.js" .`
must return nothing (excluding test files)
3. **No TODO/FIXME in diff**: `git diff --cached | grep -E "TODO|FIXME"` must return nothing
4. **Migration files ordered**: Check that all new migration files have sequential timestamps
5. **Env vars documented**: Any new env vars are added to `.env.example`
6. **CHANGELOG updated**: The changelog has an entry for this release
If any check fails, stop and report the issue. Do not proceed with deployment.
~/.local/share/pvyai/skills/
├── deploy-checks/
│ └── SKILL.md
├── commit-convention/
│ └── SKILL.md
└── skills.lock # Provenance hashes (git source + sha256)
Each skill lives in its own directory. The directory name becomes the skill’s default name if no frontmatter name: is provided.
pvyai skills add https://github.com/your-org/deploy-checks-skill.git
This performs a git clone --depth 1, validates the SKILL.md, writes it to the skills directory, and records a sha256 hash in skills.lock.
pvyai skills add ./my-local-skill/
Create a directory under the skills root and add a SKILL.md:
mkdir -p ~/.local/share/pvyai/skills/my-skill/
$EDITOR ~/.local/share/pvyai/skills/my-skill/SKILL.md
PVYai looks for skills in this order (first match wins on name conflicts):
PVYAI_SKILLS_DIR env var (if set)$XDG_DATA_HOME/pvyai/skills/ (Linux: ~/.local/share/pvyai/skills/)~/.local/share/pvyai/skills/ (fallback)pvyai skills list # List all installed skills
pvyai skills list --json # JSON output
pvyai skills info deploy-checks # Show details (source, hash, content preview)
pvyai skills info deploy-checks --json
pvyai skills remove deploy-checks # Uninstall a skill
The skills.lock file records the source and hash of each installed skill:
{
"deploy-checks": {
"source": "https://github.com/your-org/deploy-checks-skill.git",
"hash": "sha256:a1b2c3d4..."
}
}
This lets you audit where skills came from and detect tampering.
Optional YAML-style frontmatter at the top of SKILL.md:
| Field | Required | Description |
|---|---|---|
name |
No (defaults to directory name) | The skill name (lowercase, used for /name slash command and skill("name") tool call) |
description |
No | One-line description shown in the system prompt and picker |
Without frontmatter, the directory name is used as the skill name.
[a-z0-9._-])/deploy-checksskill("deploy-checks")There are three ways a skill gets activated:
/deploy-checks
/deploy-checks staging environment
The skill’s body becomes the prompt, with user arguments appended. If no arguments are given and the skill expects some, the agent will ask what to target.
Slash-command precedence: builtin > user command (.pvyai/commands/) > skill.
Type /skills to open a searchable picker showing all installed skills:
┌────────────────────────────────────────┐
│ Skills │
├────────────────────────────────────────┤
│ deploy-checks Pre-deploy checks │
│ commit-convention Enforce commit msg │
│ api-reviewer Review API endpoints │
│ ... │
└────────────────────────────────────────┘
Press Enter on a skill to fill the composer with /<skill-name> for you to complete with arguments.
The agent can autonomously call the skill tool to load a skill’s instructions:
{"name": "skill", "arguments": {"name": "deploy-checks"}}
The system prompt includes an <available_skills> block listing all installed skills with their names and descriptions. The agent is instructed:
Before acting on a request, scan this list; when the request matches a skill’s name or description, call
skillwith its exact name FIRST and follow the loaded guidance.
This means the agent proactively loads relevant skills without you having to invoke them explicitly.
When skills are installed, the agent’s system prompt gains:
<available_skills>
- deploy-checks: Pre-deployment validation checklist for production releases
- commit-convention: Enforce conventional commit message format
- api-reviewer: Review API endpoints for REST conformance and error handling
</available_skills>
Each description is truncated to 200 runes, and the total block is capped at 4096 bytes. If you install many skills, the list is truncated — keep descriptions concise.
The skill loader resolves all symlinks and refuses any SKILL.md that escapes the skills root directory. This prevents a hostile or symlinked skill from becoming an arbitrary-file reader — the skill tool has allow permission (no prompt), so this confinement is critical.
Installing a skill never executes its content. The file is read, parsed, and stored — but no code in the skill body runs during installation. The skill body only enters the agent’s context when the skill tool is called during a conversation.
If two skills have the same name (e.g. installed from different git sources), the first one wins (lexicographic directory order). Use --force to overwrite:
pvyai skills add https://github.com/other-org/deploy-checks.git --force
The skills.lock file records a sha256 hash of each skill’s SKILL.md at install time. Use pvyai skills info <name> to verify the current file matches the recorded hash.
PVYai has a related but distinct system: user commands (slash commands defined as .md files in .pvyai/commands/ or ~/.config/pvyai/commands/). The key differences:
| Aspect | Skills | User Commands |
|---|---|---|
| Location | ~/.local/share/pvyai/skills/ |
~/.config/pvyai/commands/ or .pvyai/commands/ |
| File name | SKILL.md (in a directory) |
<command-name>.md (flat file) |
| Invocation | /<name> [args] or model-pulled |
/<name> [args] |
| Model-pulled | ✓ (via skill tool) |
✗ (user-only) |
| Frontmatter | name:, description: |
description:, model:, agent:/mode: |
| Template expansion | ✗ | ✓ ($ARGUMENTS, $1-$9, $$) |
| Precedence | Lowest (after builtin + user commands) | Middle (after builtin, before skills) |
.pvyai/commands/deploy.md:
---
description: Deploy the current branch to staging
model: claude-sonnet-4.5
---
Run the deployment script for the $ARGUMENTS environment.
Steps:
1. Run `./scripts/deploy.sh $ARGUMENTS`
2. Verify the deployment with `curl -s https://staging.example.com/health`
3. Report the result
Usage: /deploy staging
The $ARGUMENTS placeholder is replaced with everything after the command name. $1 through $9 are positional arguments (space-separated).
~/.local/share/pvyai/skills/deploy-checks/SKILL.md:
---
name: deploy-checks
description: Pre-deployment validation checklist for production releases
---
# Pre-Deployment Checklist
Before deploying, verify ALL of the following. Stop and report if any check fails.
1. Run `go test ./...` — all tests must pass
2. Run `golangci-lint run` — no lint errors
3. Check `git diff --cached` for debug statements (fmt.Println, console.log)
4. Verify CHANGELOG.md has an entry for this version
5. Ensure no TODO/FIXME in staged changes
6. Confirm all new env vars are documented in .env.example
~/.local/share/pvyai/skills/commit-convention/SKILL.md:
---
name: commit-convention
description: Enforce conventional commit message format
---
# Conventional Commit Messages
When creating git commits, follow the Conventional Commits specification:
Format: `type(scope): description`
Types: feat, fix, docs, style, refactor, test, chore, perf, ci, build
Examples:
- `feat(auth): add OAuth2 login flow`
- `fix(api): handle null response from upstream`
- `docs(readme): update installation instructions`
Rules:
- Keep the subject line under 72 characters
- Use imperative mood ("add" not "added")
- Don't end with a period
- Reference issues with #issue-number in the body
~/.local/share/pvyai/skills/api-reviewer/SKILL.md:
---
name: api-reviewer
description: Review API endpoints for REST conformance and error handling
---
# API Review Guidelines
When reviewing API endpoints, check:
## REST Conformance
- GET requests must be idempotent and cacheable
- POST creates resources (201 with Location header)
- PUT/PATCH updates resources (200 with updated body)
- DELETE returns 204 No Content
- Use proper HTTP status codes (not 200 for everything)
## Error Handling
- All error responses use a consistent JSON structure
- Error messages don't leak internal details
- 4xx for client errors, 5xx for server errors
- Rate limiting headers present (X-RateLimit-*)
## Input Validation
- All inputs validated before processing
- SQL injection protection (parameterized queries)
- File upload size limits enforced
- Content-Type checked on all endpoints