A portable Zig CLI tool for vendoring and managing LLM skills from a central repository with per-project customization.
skills-repo/
<skill-name-1>/
SKILL.md
(optional additional files/subdirectories)
<skill-name-2>/
SKILL.md
(optional additional files/subdirectories)
...
Notes
- Each skill is a directory at the root level of the repository
- Skills must contain
SKILL.mdat minimum - Skills may contain additional files and subdirectories
- No naming restrictions on skill names (exact match required)
- The entire skill directory is copied during vendoring
your-project/
AGENTS.md # User's file (CLI doesn't modify)
.config/
skills/
skills.json # Local config (JSON5 format)
skills/
.gitignore # Ignores */OVERRIDE.md
README.md # Generated by CLI with LLM instructions
<skill-name-A>/
SKILL.md # Vendored copy (overwritten by updates)
OVERRIDE.md # Optional, local-only, user-created
(other vendored files...)
<skill-name-B>/
SKILL.md
(other vendored files...)
skills/.gitignore
*/OVERRIDE.md
- Local project config:
.config/skills/skills.json(in project root) - Global user config:
~/.config/skills/skills.json - Default:
git@github.com:DockYard/skills.git
.config/skills/skills.json:
{
"repo": "git@github.com:DockYard/skills.git"
// "branch": "main"
// "tag": "v1.0.0"
// "sha": "abc123def456"
}Rules
- Only one of
branch,tag, orshacan be specified at a time - If none specified, uses the repository's HEAD
- CLI validates and errors if multiple ref types are present
- Local config is only created when using
skill init --repoor related flags - Global config is manually created by users to override the default
OVERRIDE.mdis optional, local-only, user-created, and gitignored- When both
SKILL.mdandOVERRIDE.mdexist,OVERRIDE.mdtakes precedence - The CLI generates
skills/README.mdwith imperative instructions for LLMs - Agents must follow the precedence rules defined in
skills/README.md
- Creates
skills/directory - Creates
skills/README.mdwith LLM instructions - Creates
skills/.gitignorewith*/OVERRIDE.mdpattern - If
--repoor other flags provided: creates.config/skills/skills.jsonin project root - Validates that only one of
--branch,--tag, or--shais specified - Displays the source repo being used
- Prints the AGENTS.md block to stdout (does not modify AGENTS.md)
- Errors if
skills/directory already exists
- Lists all available skill names from the remote repo
- Fetches directly from remote (no caching) using git sparse checkout
- Simple output: one skill name per line
- Lists any directory under
skills/regardless of contents
- Copies entire skill directories from remote repo to project
- Does NOT automatically create
OVERRIDE.mdfiles - Errors and stops if any skill already exists locally
- Notes error and continues if a skill doesn't exist in remote
- Regenerates
skills/README.md - Requires
skills/directory to exist (runskill initfirst)
- Removes
skills/<name>/directory entirely - If
OVERRIDE.mdexists, prompts for confirmation before removing that skill - If user declines, skips that skill and continues to next
- Notes error and continues if skill doesn't exist locally
- Regenerates
skills/README.md
- No arguments: Lists installed skills and shows usage instructions
--all: Scans localskills/directory and updates all found skills<names>: Updates only specified skills- Update process for each skill:
- Temporarily move
OVERRIDE.mdif it exists - Delete the skill directory
- Copy fresh version from remote repo
- Restore
OVERRIDE.mdif it existed
- Temporarily move
- Silently skips local-only skills (not in remote) during
--all - Notes error and continues if specified skill not installed locally
- Skills must be explicitly added before they can be updated
- Regenerates
skills/README.md
- Prints the AGENTS.md block with instructions on where/how to add it
- Shows the source repo being used
- Does not modify any files
- Displays the active config file path and current configuration values
- Human-readable format:
Config: /path/to/.config/skills/skills.json Repository: https://github.com/DockYard/skills Branch: main - Shows which ref type is active (branch/tag/sha) if specified
- No git installed: Error with message "Error: This tool requires git to be installed"
- Repo unreachable: Descriptive error explaining why (network, auth, doesn't exist)
- Invalid branch/tag/sha: Error message indicating the ref doesn't exist
- Multiple ref types in config: Error requiring only one of branch/tag/sha
- No
skills/directory: Error directing user to runskill init - Error output: Individual errors go to stderr, success messages to stdout
- Exit codes: Non-zero if any errors occurred, even if some operations succeeded
- All operations fetch directly from remote repository
- Uses git sparse checkout to fetch only
skills/directory - Temporary operations use system temp directory (
std.fs.tmpDir()) - Immediate cleanup after each operation
- Requires git to be installed (dependency)
Generated during skill init and regenerated on add/remove/update. Uses imperative language optimized for LLM comprehension.
Example:
# Skills System
## Instructions for AI Agents
You MUST follow this precedence order when reading skills:
1. Read `SKILL.md` for the base skill instructions
2. If `OVERRIDE.md` exists in the same directory, it takes precedence and overrides `SKILL.md`
3. Always check for `OVERRIDE.md` before applying skill instructions
## Discovering Skills
To discover available skills in this project:
1. List all directories under `skills/`
2. Each directory represents one skill
3. Read the `SKILL.md` file in each skill directory for instructions
4. Check for `OVERRIDE.md` which contains local customizations
## Precedence Rules
- `OVERRIDE.md` is local-only and takes absolute precedence over `SKILL.md`
- `OVERRIDE.md` is gitignored to keep local customizations out of version control
- When both files exist, apply `OVERRIDE.md` instructions instead of `SKILL.md`
- Never assume all skills exist; only use those present under `skills/`
## Using Skills
When applying skills to your work:
1. Read `AGENTS.md` first for project-level behavior
2. Read this `skills/README.md` for system rules
3. For each required skill:
- Read `skills/<name>/SKILL.md` first
- If `skills/<name>/OVERRIDE.md` exists, use it instead
## Examples
If you need to apply the "testing" skill:
- Check if `skills/testing/` exists
- Read `skills/testing/SKILL.md`
- Check if `skills/testing/OVERRIDE.md` exists and use it if present
## Maintenance
Skills are managed using the `skill` CLI:
- Add skills: `skill add <name>`
- Remove skills: `skill remove <name>`
- Update skills: `skill update --all` or `skill update <name>`
- List available skills: `skill list`Output format when printed to terminal:
Source repository: https://github.com/DockYard/skills
Add the following block to your AGENTS.md file:
<!-- BEGIN: skills-system -->
Agents MUST resolve guidance in this order:
1) Project-level behavior: `AGENTS.md` (this file)
2) Skills system rules: `skills/README.md`
3) For each required skill:
- Read `skills/<name>/SKILL.md`
- If `skills/<name>/OVERRIDE.md` exists, its guidance OVERRIDES `SKILL.md`
Never assume all skills exist; only use those present under `skills/`.
If two skills conflict, prefer the more specific skill's OVERRIDES, then SKILL.md.
<!-- END: skills-system -->
skill updatealways fetches from the configured ref (branch/tag/sha) or HEAD- No per-skill version tracking
- Always overwrites vendored skill files
- Always preserves
OVERRIDE.mdfiles - Users manage version control conflicts via their own git workflow
- Zig 0.15.2
- Portable across macOS, Linux, Windows
main.zig- Entry point, command routing, argument parsingconfig.zig- Config file loading (JSON5 parsing), hierarchy resolutiongit.zig- Git operations (sparse checkout, list skills, fetch to temp)project.zig- Project structure management (init, validate)vendor.zig- Skill copying, OVERRIDE.md preservationrender.zig- Generateskills/README.mdand AGENTS.md blockcommands/- Individual command implementations
std.fs- File operations, temp directorystd.process- Shell out to git commandsstd.json- JSON5 parsing for config filesstd.fmt- String formatting and outputstd.mem- Memory operations- Built-in argument parsing or minimal hand-rolled parser
Provide pre-built binaries via Homebrew tap:
class Skill < Formula
desc "Vendor and manage LLM skills from a central repository"
homepage "https://github.com/DockYard/skill"
version "0.1.0"
on_macos do
if Hardware::CPU.arm?
url "https://github.com/DockYard/skill/releases/download/v0.1.0/skill-macos-arm64.tar.gz"
sha256 "<sha256>"
else
url "https://github.com/DockYard/skill/releases/download/v0.1.0/skill-macos-x86_64.tar.gz"
sha256 "<sha256>"
end
end
on_linux do
url "https://github.com/DockYard/skill/releases/download/v0.1.0/skill-linux-x86_64.tar.gz"
sha256 "<sha256>"
end
def install
bin.install "skill"
end
test do
system "#{bin}/skill", "--version"
end
endProvide an install script that:
- Detects OS and architecture
- Downloads appropriate pre-built binary from GitHub releases
- Verifies checksum
- Installs to
/usr/local/bin/skill(with sudo) or$HOME/.local/bin/skill(without sudo) - Makes executable
- Verifies installation
Example usage:
curl -fsSL https://raw.githubusercontent.com/DockYard/skill/main/install.sh | shOr:
wget -qO- https://raw.githubusercontent.com/DockYard/skill/main/install.sh | shRequirements:
- Zig 0.15.2
- Git
Steps:
git clone https://github.com/DockYard/skill.git
cd skill
zig build -Doptimize=ReleaseSafe
# Binary located at zig-out/bin/skill- Every command that needs git checks for availability first
- Clear error message if git not installed
- Descriptive errors for unreachable repos
- Auth errors with actionable messages
- Invalid ref (branch/tag/sha) with clear feedback
skill initerrors ifskills/existsskill adderrors if skill already exists (stops processing)skill removeprompts ifOVERRIDE.mdexists, continues if declined
- Validates only one of branch/tag/sha is specified
- Clear error messages for invalid JSON5 syntax
- Graceful handling of missing config (uses defaults)
- Empty skill directories are copied as-is during update
- Local-only skills silently skipped during
skill update --all - Missing skills noted but processing continues for batch operations
- ✅ Single centralized skills repository
- ✅ Per-project vendoring (only what you need)
- ✅ Optional local overrides (gitignored)
- ✅ No version complexity (always use specified ref or latest)
- ✅ Portable single-binary CLI (macOS, Linux, Windows)
- ✅ Multiple installation methods (Homebrew, script, source)
- ✅ Clear LLM instructions via generated README
- ✅ Simple configuration hierarchy
- ✅ No caching complexity (direct remote fetches)
# Initialize project
skill init # Use default/global config
skill init --repo <URL> # Set local repo
skill init --repo <URL> --branch <name> # Set repo and branch
skill init --repo <URL> --tag <name> # Set repo and tag
skill init --repo <URL> --sha <hash> # Set repo and specific commit
# Discover and add skills
skill list # List all available skills
skill add <name> # Add one skill
skill add <name1> <name2> <name3> # Add multiple skills
# Remove skills
skill remove <name> # Remove one skill
skill remove <name1> <name2> # Remove multiple skills
# Update skills
skill update # Show usage and installed skills
skill update --all # Update all installed skills
skill update <name> # Update one skill
skill update <name1> <name2> # Update multiple skills
# Information
skill env # Show config path and values
skill onboard # Print AGENTS.md block
# Workflow
skill init # Initialize project
skill list # Browse available skills
skill add testing docs # Add skills you need
# ... work on project ...
skill update --all # Update all skills to latestcd my-project
skill init
skill list
skill add swift-style testing documentation
# Manually create skills/swift-style/OVERRIDE.md if needed
git add skills/
git commit -m "Add skills system"skill init --repo https://github.com/myorg/custom-skills --branch develop
skill add custom-skillskill init --repo https://github.com/DockYard/skills --tag v1.2.0
skill add testing
# Skills are pinned to v1.2.0skill add testing
# Manually create and edit:
vim skills/testing/OVERRIDE.md
# Add local-only customizations
# File is gitignored, won't be overwritten by updates# Update everything
skill update --all
# Update specific skills
skill update testing documentation
# Check what's installed first
skill update- Skill dependencies (one skill requiring another)
- Skill validation/linting
- Interactive mode for adding skills
- Dry-run mode for updates
- Skill templates/scaffolding
- Multiple skills repos per project
- Skill search/filtering
- Publishing skills back to central repo