Install Agent Skills from Git repositories using symlinks
Project description
SkillHost
SkillHost manages Agent Skills from Git repositories. Git repositories are the source of truth for skill content, symlinks are the install mechanism, and ~/.skillhost/config.json is the persistent source of truth for registered agents, projects, and skill repositories.
SkillHost is intentionally small: it does not run code from skill repositories, does not scan your whole disk, and does not overwrite user-owned existing skills.
Install
pipx install skillhost
uv tool install skillhost
pip install skillhost
From a checkout:
uv tool install .
pip install .
SkillHost does not need an initialization step. Regular commands create the default ~/.skillhost state they need on demand; commands that do not need persistent config can run before config.json exists.
Current command list
skillhost [-h] [--version]
upgrade
register --project <name> --git <project-git-url>
register --agent <name> --user-dir <path> [--project-dir <path>]
unregister --project <name>
unregister --agent <name>
add <skill-git-repo> [--project <name>] [--name <repo-name>]
update [repo-name] [--project <name>] [--agent {codex,claude,opencode,openclaw,hermes}] [--all]
remove <repo-name> [--project <name>]
relink [repo-name] [--project <name>] [--agent {codex,claude,opencode,openclaw,hermes}] [--all]
unlink [repo-name] [--project <name>] [--agent {codex,claude,opencode,openclaw,hermes}] [--all]
clean
list [--project <name>]
projects
agents
doctor [--project <name>]
config
There are no user, project, register-project, config path, or config edit subcommands. Older flags such as --dry-run, --force, --all-projects, --all-skills, --include, and --exclude are not part of the current CLI.
Scope model
User scope is the default. These commands operate on user-level skill repositories unless --project <name> is provided:
skillhost add <repo>
skillhost update
skillhost relink
skillhost unlink <repo-name>
skillhost list
skillhost doctor
skillhost remove <repo-name>
Project scope is selected only with --project <name>:
skillhost add <repo> --project nsdk
skillhost update --project nsdk
skillhost relink --project nsdk
skillhost unlink --project nsdk --all
skillhost list --project nsdk
skillhost doctor --project nsdk
skillhost remove nsdk-skills --project nsdk
--all means all skill repositories in the selected scope. For update, relink, list, and doctor, omitting repo-name already means all repositories in the selected scope. For relink, omitting repo-name also opens the target selector in an interactive terminal unless --agent is provided. For unlink, omitting both repo-name and --all is refused to avoid accidental bulk unlinking.
State layout
Default state lives under ~/.skillhost:
~/.skillhost/
config.json
user_repos/
<repo-name>/
project_repos/
<project-name>/
<repo-name>/
skillhost config prints only the absolute path to config.json.
config.json stores:
version
home
agents
user_repos
projects
projects.<project>.remotes
projects.<project>.repos
repo URLs
normalized URLs
local repo paths
Each agent target directory also has a target-local .skillhost-links.json manifest. This manifest is separate from config.json and is used so unlink and remove only touch SkillHost-managed symlinks.
Agent targets
Built-in agents are initialized in config:
codex user: ~/.agents/skills project: .agents/skills
claude user: ~/.claude/skills project: .claude/skills
opencode user: ~/.config/opencode/skills project: .opencode/skills
openclaw user: ~/.openclaw/skills project: —
hermes user: ~/.hermes/skills project: —
Register another agent target:
skillhost register --agent cursor --user-dir ~/.cursor/skills --project-dir .cursor/skills
skillhost agents
skillhost unregister --agent cursor
OpenClaw and Hermes Agent are user-level targets only; SkillHost intentionally does not create project-level links for them. Claude Cowork currently exposes personal skills through its UI rather than a documented stable local user skills directory, so SkillHost does not link to Claude Cowork yet.
Agent registration updates config only. It does not link automatically; run skillhost relink when you want to refresh links.
User-level workflow
skillhost add git@github.com:org/company-skills.git
skillhost list
skillhost update
skillhost relink
skillhost unlink company-skills --agent codex
skillhost clean
skillhost remove company-skills
add clones the skill repository into ~/.skillhost/user_repos/<repo-name>, records it in config.json, discovers skills, and then prompts where to link the added skills: Codex, Claude Code, OpenCode, OpenClaw, Hermes Agent, or All. In non-interactive shells it keeps the safe previous behavior and relinks all enabled user-level agent targets when possible.
Use --name when you want the local repo name to differ from the Git URL basename:
skillhost add git@github.com:org/company-skills.git --name shared-skills
Project-level workflow
First register the project remote:
skillhost register --project nsdk --git git@github.com:org/nsdk.git
Then run project-scoped commands from inside the matching project checkout when you want project links to be created or removed:
cd ~/code/nsdk
skillhost add git@github.com:org/nsdk-skills.git --project nsdk
skillhost update --project nsdk
skillhost relink --project nsdk
skillhost unlink --project nsdk --all
skillhost remove nsdk-skills --project nsdk
Project relink and project unlink validate the current Git repository root and its origin remote against the registered project. SkillHost does not search the disk for project checkouts and does not perform cross-project bulk cleanup.
If you add or update a project skill repository outside the matching checkout, the repository is still recorded under ~/.skillhost/project_repos/<project>/<repo-name>, and SkillHost prints the command to run inside the project checkout.
Command details
skillhost upgrade
skillhost upgrade
Updates the installed SkillHost package using the installer that appears to own the current command: pipx upgrade skillhost for pipx-managed installs, uv tool upgrade skillhost for uv tool installs, and python -m pip install --upgrade skillhost as the fallback for ordinary pip or virtualenv installs.
skillhost register
skillhost register --project <name> --git <project-git-url>
skillhost register --agent <name> --user-dir <path> [--project-dir <path>]
Project registration normalizes and stores the project Git remote and creates ~/.skillhost/project_repos/<name>. Agent registration stores user and project target directories. --project and --agent are mutually exclusive.
skillhost unregister
skillhost unregister --project <name>
skillhost unregister --agent <name>
Removes the config entry only. It does not delete user-owned files and does not scan disk for unknown checkouts.
skillhost add
skillhost add <skill-git-repo> [--project <name>] [--name <repo-name>]
Clones a skill repository into the selected scope and records it in config. Without --name, the repo name is derived from the Git URL basename with .git stripped. GitHub HTTPS URLs are cloned through SSH automatically, so https://github.com/org/repo and git@github.com:org/repo.git both work for users with SSH access. If no skills are discovered, add leaves config and repo storage unchanged and exits with an error. On success, it prints how many skills were added and suggests skillhost list.
After a successful interactive add, SkillHost opens a small terminal selector for where to link the newly added skills. Use ↑/↓ to move, Space to select or unselect, and Enter to confirm. Leaving nothing selected defaults to all enabled targets. If the terminal cannot run the selector, SkillHost falls back to a text prompt where you can enter one number, multiple comma-separated numbers such as 1,3, or all/blank for all. Non-interactive add defaults to all enabled targets.
skillhost update
skillhost update [repo-name] [--project <name>] [--agent {codex,claude,opencode,openclaw,hermes}] [--all]
Before updating, update uses the same target selection flow as add and relink unless --agent is provided. It removes existing SkillHost-managed links for the selected repository or repositories only in the selected agent targets, so renamed or deleted skill directories do not leave stale symlinks behind. Then it runs git pull --ff-only for one repository or all repositories in the selected scope. It does not merge or rebase. After updating, it relinks the same selected agent targets when possible. Non-interactive update defaults to all enabled targets.
skillhost remove
skillhost remove <repo-name> [--project <name>]
Unlinks SkillHost-managed symlinks for that repo where safely discoverable, deletes the cloned repo under ~/.skillhost, and removes the repo entry from config. The repo argument can be the local repo name or a Git URL such as https://github.com/org/repo / git@github.com:org/repo.git; URLs are resolved to their repo basename. It does not support --all.
skillhost relink
skillhost relink [repo-name] [--project <name>] [--agent {codex,claude,opencode,openclaw,hermes}] [--all]
Creates or updates SkillHost-managed symlinks for one repo or all repos in the selected scope. Omitting repo-name means all registered repos in the selected scope; for example, skillhost relink refreshes every user-level repo, and skillhost relink --project nsdk refreshes every repo registered under project nsdk. Existing unmanaged files or directories are skipped. In an interactive terminal, relink uses the same target selector as add unless --agent is provided; non-interactive relink defaults to all enabled targets.
skillhost unlink
skillhost unlink [repo-name] [--project <name>] [--agent {codex,claude,opencode,openclaw,hermes}] [--all]
Removes only symlinks recorded in .skillhost-links.json. To unlink all repos in a scope, pass --all explicitly:
skillhost unlink --all
skillhost unlink --project nsdk --all
skillhost clean
skillhost clean
Scans all enabled user-level agent skill directories and removes broken symlinks. If you run it from inside a Git repository, it also scans that repo root's supported project-level agent skill directories, such as .agents/skills, .claude/skills, and .opencode/skills. If a broken symlink or missing destination is recorded in .skillhost-links.json, clean also removes the stale manifest entry. OpenClaw and Hermes are user-level-only targets, so they are not cleaned as project-level directories.
skillhost list, projects, agents, doctor, config
skillhost list [--project <name>]
skillhost projects
skillhost agents
skillhost doctor [--project <name>]
skillhost config
list shows repos and discovered skills in the selected scope. projects shows registered projects and normalized remotes. agents shows registered agent user/project target directories. doctor checks config, repos, duplicate skill names, targets, manifests, broken symlinks, and missing sources. config prints the absolute config path only.
Supported skill repository layouts
Single skill repo:
my-skill/
SKILL.md
Collection repo:
company-skills/
skills/
git/
SKILL.md
db/
SKILL.md
Flat collection repo:
company-skills/
git/
SKILL.md
db/
SKILL.md
Skill discovery is shallow. SkillHost checks root SKILL.md, direct children under skills/, or direct children under the repo root. It ignores hidden directories and obvious non-skill directories such as tests, docs, examples, scripts, references, and assets.
Git URL normalization
Common SSH and HTTPS Git URL forms normalize to host/org/repo:
git@github.com:org/repo.git -> github.com/org/repo
git@github.com:org/repo -> github.com/org/repo
https://github.com/org/repo.git -> github.com/org/repo
https://github.com/org/repo -> github.com/org/repo
ssh://git@github.com/org/repo.git -> github.com/org/repo
Project matching uses the current Git root plus git remote get-url origin, normalized with the same rules.
Safety rules
SkillHost does not execute code from skill repositories. It only clones repositories, pulls with git pull --ff-only, reads SKILL.md metadata, and creates or removes manifest-managed symlinks.
SkillHost never overwrites unmanaged existing targets, never removes user-owned skill directories, and never performs full-disk project discovery or cross-project bulk operations.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file skillhost-0.1.6.tar.gz.
File metadata
- Download URL: skillhost-0.1.6.tar.gz
- Upload date:
- Size: 63.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6ae200fe1bebf6a81604f7248ea977ed8999d15e9ecc83ed3c02cc25368d9342
|
|
| MD5 |
c518dfc4f34472174f54ab2dc766f71d
|
|
| BLAKE2b-256 |
c43e120aeecf7b9bfa785ab46f982cc85902a23c688ccd4cad88a48d03048646
|
File details
Details for the file skillhost-0.1.6-py3-none-any.whl.
File metadata
- Download URL: skillhost-0.1.6-py3-none-any.whl
- Upload date:
- Size: 21.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ce543f74df53bae94ac005e352cb7b2517ae6a211b37f4594ee9a6d9ba90df81
|
|
| MD5 |
b05ea3111798401f74dcee8eb82ba885
|
|
| BLAKE2b-256 |
2bcfbb2c8929942f14518f94e55a155f11506e408efe2e1a311c2cb85f307b94
|