Manage AI agent skills across Claude Code, Amp, Codex, OpenCode, Factory, and others.
# Install
brew install 803/sk/sk
# Add skills to your project
sk init
sk pkg add gh superpowers-marketplace/superpowers
sk sync- One manifest, multiple agents — Define skills once in
agents.toml, sync to all your AI coding tools - Cross-agent compatibility — Use Claude Code plugins with Amp, Codex, and OpenCode; sk extracts skills from
.claude-pluginpackages and syncs them everywhere - Team-shareable — Commit
agents.tomlto version control; teammates runsk sync - Live development — Local packages use symlinks; edit skills and changes appear instantly
- Smart reconciliation — Only updates what changed; safely removes stale skills without touching manually-added ones
- Flexible sourcing — Pull from GitHub, any git remote, local paths, or existing Claude Code plugins
- Installation
- Quick Start
- Core Concepts
- The Manifest
- Package Types
- Commands
- Creating Skill Packages
- How It Works
- Workflows
- Troubleshooting
# Homebrew (macOS/Linux)
brew install 803/sk/sk
# npm (requires Node.js 18+)
npm install -g @skills-supply/sk
# Scoop (Windows)
scoop bucket add 803 https://github.com/803/scoop-sk
scoop install sksk initCreates agents.toml with detected agents:
[agents]
amp = false
claude-code = true
codex = true
factory = false
opencode = false
[dependencies]sk pkg add https://github.com/obra/superpowerssk auto-detects the package type from URLs. You can also be explicit:
sk pkg add gh obra/superpowers # GitHub shorthand
sk pkg add claude-plugin superpowers@obra/market # Marketplace pluginsk syncSkills are now installed in each enabled agent's skills directory.
A skill is a markdown file (SKILL.md) that extends what an AI agent can do. Skills contain instructions, patterns, workflows, or domain knowledge that agents follow during conversations.
A package is a collection of one or more skills. Packages can be:
- A GitHub repository
- Any git remote (GitLab, Bitbucket, self-hosted)
- A local directory (for development)
- A Claude Code plugin (
.claude-plugindirectory)
The manifest (agents.toml) declares which packages you want and which agents should receive them. It's the single source of truth for your skill configuration.
Agents are the AI coding tools that consume skills. Each agent has its own skills directory:
| Agent | Global Skills | Project Skills |
|---|---|---|
| Amp | ~/.config/agents/skills/ |
./.agents/skills/ |
| Claude Code | ~/.claude/skills/ |
./.claude/skills/ |
| Codex | ~/.codex/skills/ |
./.codex/skills/ |
| Factory | ~/.factory/skills/ |
./.factory/skills/ |
| OpenCode | ~/.config/opencode/skill/ |
./.opencode/skill/ |
For global scope (--global), skills install to your home directory. For project scope (default), skills install within your project directory.
A dependency is a package declared in your manifest's [dependencies] section. When you run sk sync, each dependency is fetched and its skills are installed to your enabled agents.
An alias is the name you give a dependency in your manifest—the key before the = sign:
[dependencies]
superpowers = { gh = "superpowers-marketplace/superpowers" }
# ↑ alias ↑ package sourceAliases must be unique within a manifest. Installed skills are prefixed with their alias to avoid conflicts: superpowers-debugging, superpowers-code-review, etc.
| Scope | Manifest Location | Use Case |
|---|---|---|
| Project | ./agents.toml |
Skills for a specific repo |
| Global | ~/.sk/agents.toml |
Skills available everywhere |
# Project scope (default)
sk init && sk pkg add gh owner/repo && sk sync
# Global scope
sk init --global && sk pkg add gh owner/repo --global && sk sync --globalProject manifests are discovered by walking up from your current directory.
[agents]
amp = false # Amp (disabled)
claude-code = true # Anthropic's Claude Code
codex = true # OpenAI Codex CLI
factory = true # Factory (Droids)
opencode = false # OpenCode (disabled)
[dependencies]
# Claude Code plugin (from marketplace)
[dependencies.superpowers]
type = "claude-plugin"
plugin = "superpowers"
marketplace = "obra/superpowers-marketplace"
# GitHub packages
[dependencies.feature-dev]
gh = "claude-plugins-official/feature-dev"
branch = "main"
# Inline syntax also works
elements = { gh = "org/monorepo", path = "packages/elements" }
internal = { git = "[email protected]:myorg/skills.git", rev = "abc123" }
my-skills = { path = "../my-skills" }sk supports several package types. You can specify them explicitly (sk pkg add gh ...) or let sk auto-detect from a URL (sk pkg add https://...).
URL auto-detection:
https://github.com/owner/repo→ GitHub (gh)[email protected]:owner/repo.git→ GitHub (gh)https://gitlab.com/org/repo.git→ Git (git)
For plugins published to a Claude Code marketplace.
# Add a plugin from a marketplace
sk pkg add claude-plugin "superpowers@obra/superpowers-marketplace"
# Format: plugin-name@marketplace-source
sk pkg add claude-plugin "my-plugin@https://github.com/org/marketplace"
sk pkg add claude-plugin "my-plugin@[email protected]:org/marketplace.git"In your manifest:
[dependencies.superpowers]
type = "claude-plugin"
plugin = "superpowers"
marketplace = "obra/superpowers-marketplace"How it works:
- For Claude Code: Uses the native plugin installation (
claude install) - For other agents: Resolves the plugin source and extracts skills
This is the key to cross-agent compatibility—plugins designed for Claude Code work with Codex and OpenCode too.
Marketplace formats:
- GitHub shorthand:
owner/repo - HTTPS URL:
https://github.com/org/marketplace - SSH URL:
[email protected]:org/marketplace.git
Note: Marketplace plugins don't support --tag, --branch, --rev, or --path options.
Auto-detection: If you add a URL pointing to a marketplace repo, sk detects it and prompts you to select a plugin:
sk pkg add https://github.com/obra/superpowers-marketplace
# → Detected marketplace. Select a plugin: superpowers, other-plugin, ...For repositories hosted on GitHub.
# Basic
sk pkg add gh owner/repo
# Pinned to a tag (recommended for stability)
sk pkg add gh owner/repo --tag v1.0.0
# Track a branch (updates on each sync)
sk pkg add gh owner/repo --branch main
# Pinned to exact commit
sk pkg add gh owner/repo --rev abc123def
# Subdirectory in a monorepo
sk pkg add gh owner/repo --path packages/skillsRef behavior:
--tag— Pinned. Always uses that exact tag.--branch— Floating. Eachsk syncfetches the latest commit.--rev— Pinned. Always uses that exact commit.- No ref specified — Uses the repository's default branch (floating).
Note: tag, branch, and rev are called "refs" (git references). Registry packages use semantic versions instead—see the Registry section when available.
Authentication: Uses your existing git SSH keys. For private repos, ensure your SSH key has access.
For any git remote—GitLab, Bitbucket, self-hosted, or SSH URLs.
# HTTPS
sk pkg add git https://gitlab.com/org/repo.git
# SSH
sk pkg add git [email protected]:org/private-repo.git --tag v1.0.0Same ref options as GitHub packages (--tag, --branch, --rev).
When to use git vs gh:
- Use
ghfor GitHub repos (shorter syntax, GitHub-specific optimizations) - Use
gitfor everything else
For skills you're developing or testing locally.
sk pkg add path ../my-skills
sk pkg add path /absolute/path/to/skillsKey behavior: Local packages are symlinked, not copied. When you edit files in the source directory, changes appear immediately in the agent's skills directory. No need to re-run sk sync.
This makes local packages ideal for:
- Developing new skills
- Testing changes before publishing
- Team members working on shared skill repos
| Command | Description |
|---|---|
sk init |
Create an agents.toml manifest |
sk pkg add <type> <spec> |
Add a package to the manifest |
sk pkg remove <alias> |
Remove a package from the manifest |
sk pkg |
Interactive package management |
sk agent add <name> |
Enable an agent |
sk agent remove <name> |
Disable an agent |
sk agent |
Interactive agent management |
sk sync |
Sync skills to all enabled agents |
sk sync --dry-run |
Preview changes without writing |
--global— Use the global manifest (~/.sk/agents.toml)--non-interactive— Run without prompts (for scripts/CI)--init— Create manifest if it doesn't exist (withpkg add)
sk detects packages in several ways (checked in order):
- Manifest package — Has
agents.tomlwith[exports.auto_discover] - Plugin package — Has
.claude-plugin/plugin.json(skills inskills/subdirectory) - Subdirectory package — Contains subdirectories with
SKILL.mdfiles - Single-skill package — Has
SKILL.mdin the root
For most new packages, use the subdirectory structure:
my-skills/
├── debugging/
│ └── SKILL.md
├── code-review/
│ └── SKILL.md
└── testing/
└── SKILL.md
Every skill needs a SKILL.md file with YAML frontmatter:
---
name: debugging
---
# Debugging Skill
Instructions for systematic debugging...Requirements:
- File must be named exactly
SKILL.md - Must start with YAML frontmatter (
---) - Must include a
namefield - Name must be unique within the package
For more control, add an agents.toml to your package:
[package]
name = "my-skills"
version = "1.0.0"
[exports.auto_discover]
skills = "./skills" # Directory to scan for SKILL.md filesThis is useful when you want to:
- Specify a custom skills directory
- Add package metadata
- Combine skills with other exports
sk automatically detects Claude Code plugins (packages with .claude-plugin/plugin.json). Skills from these plugins can be synced to all agents, not just Claude Code.
This means you can:
- Use existing Claude Code plugins with Codex or OpenCode
- Publish one plugin that works across all AI coding tools
- Share plugin skills with teammates who use different agents
When you run sk sync, sk walks up from your current directory looking for agents.toml. The first manifest found is used. This means you can run sk sync from anywhere in your project.
For global scope (--global), sk uses ~/.sk/agents.toml directly.
Each dependency in your manifest is resolved to a fetchable source:
- Claude plugins — Resolved via marketplace, then fetched from plugin source
- GitHub packages — Cloned via git using
ghshorthand - Git packages — Cloned via the provided URL
- Local packages — Used directly (no clone)
Refs (tag, branch, rev) determine what gets checked out for git-based packages.
After fetching, sk scans each package for skills (checked in order):
- Manifest —
agents.tomlwith[exports.auto_discover]config - Plugin —
.claude-plugin/plugin.json(skills fromskills/subdirectory) - Subdirectories — Folders containing
SKILL.mdfiles - Single skill —
SKILL.mdin root
This means any GitHub, Git, or local package containing .claude-plugin/plugin.json is automatically treated as a plugin—you don't need to declare it as claude-plugin type. The explicit claude-plugin type is only needed for marketplace plugins.
Each discovered skill is validated (frontmatter, unique name).
Skills are installed to each enabled agent's skills directory:
- GitHub and Git packages — Files are copied
- Local packages — Symlinks are created
- Claude plugins — Native installation for Claude Code, extracted for others
Skill names are prefixed with the package alias to avoid conflicts: superpowers-debugging, feature-dev-code-review, etc.
sk maintains a state file (.sk-state.json) in each agent's root directory (e.g., ~/.claude/.sk-state.json for global, {project}/.claude/.sk-state.json for local). This tracks which skills sk installed, enabling:
- Safe removal — When you remove a package from your manifest, its skills are cleaned up
- Protection — sk won't overwrite manually-added skills (errors instead)
- Incremental sync — Only changed skills are updated
On each sync, sk compares the desired state (manifest) to the installed state:
- Skills in manifest but not installed → Install
- Skills installed but not in manifest → Remove
- Skills that changed → Update
This "npm prune" pattern ensures your installed skills always match your manifest.
Share skills across your team:
# One person sets up
sk init
sk pkg add gh your-org/team-skills
git add agents.toml
git commit -m "Add team skills"
git push
# Teammates run
git pull
sk syncDevelop skills with instant feedback:
# Add your local skills directory
sk pkg add path ../my-skills-dev
sk sync
# Edit SKILL.md files in ../my-skills-dev
# Changes appear immediately (symlinked)
# When ready, publish to git and switch to remote
sk pkg remove my-skills-dev
sk pkg add gh your-org/my-skills --tag v1.0.0
sk syncInstall skills in CI pipelines:
sk init --agents claude-code --non-interactive
sk pkg add gh org/skills --non-interactive --init
sk sync --non-interactiveUse global skills for tools you want everywhere, project skills for repo-specific needs:
# Global: your personal productivity skills
sk pkg add gh my-username/my-skills --global
sk sync --global
# Project: team-specific skills (committed to repo)
sk pkg add gh team/project-skills
sk syncsk found an existing skill with the same name that it didn't install. This protects manually-added skills from being overwritten.
Solutions:
- Rename your manual skill to avoid the conflict
- Remove the manual skill if you want sk to manage it
- Use a different package alias in your manifest
Your manifest has no packages in [dependencies].
Solutions:
- Add packages:
sk pkg add gh owner/repo - Check you're in the right directory (sk walks up to find
agents.toml)
sk uses your existing git SSH keys. For private repos:
Solutions:
- Ensure your SSH key is added:
ssh-add -l - Test access directly:
git ls-remote [email protected]:owner/private-repo.git - For HTTPS, configure git credentials
Check:
- Is the agent enabled? (
sk agentto view) - Did sync complete without errors?
- Is the skill file named exactly
SKILL.md? - Does the skill have valid YAML frontmatter with
name:?
Local packages use symlinks, so changes should appear immediately. If not:
Check:
- Is the symlink intact? Check the agent's skills directory
- Re-run
sk syncto recreate symlinks if needed
If you need to start fresh:
# For global scope: remove state files from home directory
rm ~/.claude/.sk-state.json
rm ~/.codex/.sk-state.json
rm ~/.factory/.sk-state.json
# For project scope: remove state files from project directory
rm .claude/.sk-state.json
rm .codex/.sk-state.json
rm .factory/.sk-state.json
# Re-sync
sk syncThis makes sk treat all existing skills as unmanaged.
MIT