skm-cli 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- skm_cli-0.1.0/.gitignore +1 -0
- skm_cli-0.1.0/AGENTS.md +175 -0
- skm_cli-0.1.0/PKG-INFO +161 -0
- skm_cli-0.1.0/README.md +150 -0
- skm_cli-0.1.0/draft.md +35 -0
- skm_cli-0.1.0/images/skm-install.png +0 -0
- skm_cli-0.1.0/kb/plans/2026-03-09-skm-skill-manager.md +1461 -0
- skm_cli-0.1.0/kb/sessions/2026-03-09-refactor-config-structure.md +35 -0
- skm_cli-0.1.0/kb/sessions/2026-03-10-add-local-path-support.md +34 -0
- skm_cli-0.1.0/kb/sessions/2026-03-10-extend-skm-install-direct-source.md +35 -0
- skm_cli-0.1.0/kb/sessions/2026-03-10-handle-existing-skill-dir-override.md +30 -0
- skm_cli-0.1.0/kb/sessions/2026-03-10-implement-skm-view-command.md +30 -0
- skm_cli-0.1.0/kb/sessions/2026-03-10-install-idempotent-sync.md +41 -0
- skm_cli-0.1.0/link-skill +91 -0
- skm_cli-0.1.0/pyproject.toml +34 -0
- skm_cli-0.1.0/skills.example.yaml +38 -0
- skm_cli-0.1.0/src/skm/__init__.py +0 -0
- skm_cli-0.1.0/src/skm/cli.py +352 -0
- skm_cli-0.1.0/src/skm/commands/__init__.py +0 -0
- skm_cli-0.1.0/src/skm/commands/check_updates.py +54 -0
- skm_cli-0.1.0/src/skm/commands/install.py +400 -0
- skm_cli-0.1.0/src/skm/commands/list_cmd.py +100 -0
- skm_cli-0.1.0/src/skm/commands/remove.py +90 -0
- skm_cli-0.1.0/src/skm/commands/update.py +114 -0
- skm_cli-0.1.0/src/skm/commands/view.py +54 -0
- skm_cli-0.1.0/src/skm/config.py +157 -0
- skm_cli-0.1.0/src/skm/detect.py +50 -0
- skm_cli-0.1.0/src/skm/git.py +103 -0
- skm_cli-0.1.0/src/skm/linker.py +116 -0
- skm_cli-0.1.0/src/skm/lock.py +39 -0
- skm_cli-0.1.0/src/skm/py.typed +0 -0
- skm_cli-0.1.0/src/skm/tui.py +107 -0
- skm_cli-0.1.0/src/skm/types.py +136 -0
- skm_cli-0.1.0/src/skm/utils.py +9 -0
- skm_cli-0.1.0/tests/test_cli_e2e.py +420 -0
- skm_cli-0.1.0/tests/test_config.py +192 -0
- skm_cli-0.1.0/tests/test_detect.py +81 -0
- skm_cli-0.1.0/tests/test_git.py +54 -0
- skm_cli-0.1.0/tests/test_install.py +203 -0
- skm_cli-0.1.0/tests/test_install_from_source.py +416 -0
- skm_cli-0.1.0/tests/test_linker.py +142 -0
- skm_cli-0.1.0/tests/test_list_cmd.py +41 -0
- skm_cli-0.1.0/tests/test_local_path.py +216 -0
- skm_cli-0.1.0/tests/test_lock.py +25 -0
- skm_cli-0.1.0/tests/test_types.py +39 -0
- skm_cli-0.1.0/uv.lock +226 -0
skm_cli-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.venv/
|
skm_cli-0.1.0/AGENTS.md
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# SKM - Skill Manager
|
|
2
|
+
|
|
3
|
+
A CLI tool that manages AI agent skills by cloning GitHub repos, detecting skills via `SKILL.md`, and symlinking them to agent directories based on a central YAML config.
|
|
4
|
+
|
|
5
|
+
## Tech Stack
|
|
6
|
+
|
|
7
|
+
- Python 3.12+, uv, click, pyyaml, pydantic
|
|
8
|
+
- Git operations via subprocess (unified `run_cmd` helper raises `click.ClickException` on failure)
|
|
9
|
+
- Tests: pytest
|
|
10
|
+
|
|
11
|
+
## Project Structure
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
src/skm/
|
|
15
|
+
├── cli.py # Click CLI entry point (group + subcommands)
|
|
16
|
+
├── types.py # Pydantic data models + constants
|
|
17
|
+
├── config.py # Load skills.yaml → SkmConfig
|
|
18
|
+
├── lock.py # Read/write skills-lock.yaml
|
|
19
|
+
├── detect.py # Walk cloned repos for SKILL.md files
|
|
20
|
+
├── git.py # Clone, pull, fetch, commit SHA helpers (unified run_cmd error handling)
|
|
21
|
+
├── utils.py # Utility functions (compact_path)
|
|
22
|
+
├── linker.py # Symlink skills to agent dirs, resolve includes/excludes
|
|
23
|
+
└── commands/
|
|
24
|
+
├── install.py # Clone repos, detect skills, link to agents, update lock
|
|
25
|
+
├── list_cmd.py # Print installed skills from lock file
|
|
26
|
+
├── check_updates.py # Fetch remotes, compare commits, show available updates
|
|
27
|
+
└── update.py # Pull latest for a skill's repo, re-link, update lock
|
|
28
|
+
tests/
|
|
29
|
+
├── test_types.py # Pydantic model validation
|
|
30
|
+
├── test_config.py # Config loading, error handling
|
|
31
|
+
├── test_lock.py # Lock file I/O
|
|
32
|
+
├── test_detect.py # Skill detection logic (local + network tests against real repos)
|
|
33
|
+
├── test_git.py # Git operations (clone, commit retrieval, clone failure handling)
|
|
34
|
+
├── test_linker.py # Symlink creation, agent filtering
|
|
35
|
+
├── test_install.py # Install command unit tests
|
|
36
|
+
└── test_cli_e2e.py # End-to-end CLI tests for all commands
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Key Paths
|
|
40
|
+
|
|
41
|
+
- **Config:** `~/.config/skm/skills.yaml` — YAML dict with `packages` (repo list) and optional `agents.default`
|
|
42
|
+
- **Lock:** `~/.config/skm/skills-lock.yaml` — tracks installed skills, commits, symlink paths
|
|
43
|
+
- **Store:** `~/.local/share/skm/skills/` — cloned repos cached here
|
|
44
|
+
- **Agent dirs:** Skills are symlinked into each agent's skill directory (e.g. `~/.claude/skills/`, `~/.codex/skills/`)
|
|
45
|
+
|
|
46
|
+
## Architecture
|
|
47
|
+
|
|
48
|
+
Config-driven: parse `skills.yaml` → clone repos to store → detect skills by walking for `SKILL.md` → symlink to agent dirs → write lock file.
|
|
49
|
+
|
|
50
|
+
Each command function (`run_install`, `run_list`, etc.) accepts explicit paths and agent dicts as parameters, making them testable with `tmp_path` fixtures without touching real filesystem locations.
|
|
51
|
+
|
|
52
|
+
## Error Handling
|
|
53
|
+
|
|
54
|
+
All git subprocess calls go through `run_cmd()` in `git.py`, which captures stdout/stderr and raises `click.ClickException` on non-zero exit codes. This produces user-friendly error messages instead of raw `CalledProcessError` tracebacks.
|
|
55
|
+
|
|
56
|
+
## Path Handling
|
|
57
|
+
|
|
58
|
+
Paths stored in `skills-lock.yaml` (e.g. `linked_to`) use `compact_path()` from `utils.py` to replace the home directory with `~`, avoiding exposure of usernames. When reading these paths back for filesystem operations, `Path.expanduser()` is used.
|
|
59
|
+
|
|
60
|
+
## CLI Commands
|
|
61
|
+
|
|
62
|
+
- `skm install` — Clone repos (idempotent: skips pull if already cloned), detect skills, create symlinks, remove stale links, update lock. Treats `skills.yaml` as declarative state: removes links for skills dropped from config or agents changed by includes/excludes. Only removes links tracked in the lock file — manually created files in agent dirs are never touched.
|
|
63
|
+
- `skm list` — Show installed skills and their linked paths from lock file
|
|
64
|
+
- `skm check-updates` — Fetch remotes, compare against locked commits, show changelog
|
|
65
|
+
- `skm update <skill_name>` — Pull latest for a skill's repo, re-link, update lock
|
|
66
|
+
|
|
67
|
+
## Config Format (skills.yaml)
|
|
68
|
+
|
|
69
|
+
Top-level YAML dict with `packages` and optional `agents`:
|
|
70
|
+
|
|
71
|
+
```yaml
|
|
72
|
+
agents:
|
|
73
|
+
default: # optional: select which KNOWN_AGENTS are active (omit = all)
|
|
74
|
+
- claude
|
|
75
|
+
- standard
|
|
76
|
+
|
|
77
|
+
packages:
|
|
78
|
+
- repo: https://github.com/vercel-labs/agent-skills
|
|
79
|
+
skills: # optional: filter to specific skills (omit = all)
|
|
80
|
+
- react-best-practices
|
|
81
|
+
agents: # optional: further filter agents for this package
|
|
82
|
+
excludes:
|
|
83
|
+
- standard
|
|
84
|
+
- repo: https://github.com/blader/humanizer # installs all detected skills to default agents
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
`agents.default` selects which agents from `KNOWN_AGENTS` are used as the base set. Per-package `agents.includes/excludes` then filters from that base set.
|
|
88
|
+
|
|
89
|
+
## Skill Detection
|
|
90
|
+
|
|
91
|
+
A skill is a directory containing a `SKILL.md` file with YAML frontmatter including a `name` field. Detection order:
|
|
92
|
+
1. Root `SKILL.md` → singleton skill (the repo itself is the skill)
|
|
93
|
+
2. `./skills/` subdirectory exists → walk its children
|
|
94
|
+
3. Otherwise → walk all subdirectories from repo root
|
|
95
|
+
4. Stop descending once `SKILL.md` is found (no nested skill-in-skill)
|
|
96
|
+
|
|
97
|
+
## Known Agents
|
|
98
|
+
|
|
99
|
+
Defined in `src/skm/types.py` as `KNOWN_AGENTS`:
|
|
100
|
+
- `standard` → `~/.agents/skills`
|
|
101
|
+
- `claude` → `~/.claude/skills`
|
|
102
|
+
- `codex` → `~/.codex/skills`
|
|
103
|
+
- `openclaw` → `~/.openclaw/skills`
|
|
104
|
+
|
|
105
|
+
## Testing
|
|
106
|
+
|
|
107
|
+
### Running Tests
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
uv sync
|
|
111
|
+
uv run pytest -v # all tests
|
|
112
|
+
uv run pytest tests/test_cli_e2e.py -v # e2e only
|
|
113
|
+
uv run pytest -k "install" -v # filter by name
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Test Isolation
|
|
117
|
+
|
|
118
|
+
All tests run entirely within pytest's `tmp_path` — no real agent directories, config files, or git repos are touched. This is achieved two ways:
|
|
119
|
+
|
|
120
|
+
- **Unit tests** (`test_install.py`, `test_linker.py`, etc.): call `run_*` functions directly with explicit `config`/`lock_path`/`store_dir`/`known_agents` parameters pointing to `tmp_path` subdirectories.
|
|
121
|
+
- **E2E tests** (`test_cli_e2e.py`): invoke the CLI through Click's `CliRunner` with `--config`, `--store`, `--lock`, and `--agents-dir` flags to redirect all I/O into `tmp_path`.
|
|
122
|
+
|
|
123
|
+
Git repos used in tests are local repos created via `git init` inside `tmp_path` — no network access required. Tests marked with `@pytest.mark.network` clone real GitHub repos and require internet access.
|
|
124
|
+
|
|
125
|
+
### CLI Path Overrides
|
|
126
|
+
|
|
127
|
+
The CLI group accepts four flags to override default paths, useful for both testing and safe manual experimentation:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
skm --config /tmp/test.yaml \
|
|
131
|
+
--store /tmp/store \
|
|
132
|
+
--lock /tmp/lock.yaml \
|
|
133
|
+
--agents-dir /tmp/agents \
|
|
134
|
+
install
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
- `--config` — path to `skills.yaml` (default: `~/.config/skm/skills.yaml`)
|
|
138
|
+
- `--lock` — path to `skills-lock.yaml` (default: `~/.config/skm/skills-lock.yaml`)
|
|
139
|
+
- `--store` — directory for cloned repos (default: `~/.local/share/skm/skills/`)
|
|
140
|
+
- `--agents-dir` — base directory for agent symlinks; creates subdirs per agent name (overrides `KNOWN_AGENTS` paths)
|
|
141
|
+
|
|
142
|
+
### E2E Test Helpers
|
|
143
|
+
|
|
144
|
+
`test_cli_e2e.py` provides reusable helpers for writing new tests:
|
|
145
|
+
|
|
146
|
+
- `_make_skill_repo(base, repo_name, skills)` — creates a local git repo with specified skills. Each skill is `{"name": str, "subdir": bool}` where `subdir=True` (default) puts it under `skills/<name>/`, `False` makes it a singleton at repo root.
|
|
147
|
+
- `_cli_args(tmp_path)` — returns the common `--config/--store/--lock/--agents-dir` flags for full isolation.
|
|
148
|
+
- `_write_config(tmp_path, repos, agents=None)` — writes a `skills.yaml` with `{"packages": repos}` format, optionally including `agents` config.
|
|
149
|
+
- `_load_lock(tmp_path)` — loads the lock file as a plain dict for assertions.
|
|
150
|
+
|
|
151
|
+
### Writing New Tests
|
|
152
|
+
|
|
153
|
+
To add a new e2e test, follow this pattern:
|
|
154
|
+
|
|
155
|
+
```python
|
|
156
|
+
def test_my_scenario(self, tmp_path):
|
|
157
|
+
repo = _make_skill_repo(tmp_path, "my-repo", [{"name": "my-skill"}])
|
|
158
|
+
_write_config(tmp_path, [{"repo": str(repo)}]) # wraps in {"packages": ...}
|
|
159
|
+
|
|
160
|
+
runner = CliRunner()
|
|
161
|
+
result = runner.invoke(cli, [*_cli_args(tmp_path), "install"])
|
|
162
|
+
|
|
163
|
+
assert result.exit_code == 0, result.output
|
|
164
|
+
# assert on symlinks, lock contents, output text, etc.
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Development
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
uv sync
|
|
171
|
+
uv run pytest -v # run tests
|
|
172
|
+
uv run skm --help # run CLI
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Do not run formatters or style linters on the code.
|
skm_cli-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: skm-cli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Skill Manager - manage agent skills from GitHub repos
|
|
5
|
+
Author-email: Reorx <novoreorx@gmail.com>
|
|
6
|
+
Requires-Python: >=3.12
|
|
7
|
+
Requires-Dist: click>=8.1
|
|
8
|
+
Requires-Dist: pydantic>=2.0
|
|
9
|
+
Requires-Dist: ruamel-yaml>=0.18
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
|
|
12
|
+
# SKM - Skill Manager
|
|
13
|
+
|
|
14
|
+
A CLI tool that manages **global** AI agent skills from GitHub repos or local directories. Clone repos or link local paths, detect skills via `SKILL.md`, and symlink them into agent directories — all driven by a single YAML config.
|
|
15
|
+
|
|
16
|
+
> **Note:** skm manages skills at the user level (e.g. `~/.claude/skills/`), not at the project level. It is not intended for installing skills into project-scoped directories.
|
|
17
|
+
|
|
18
|
+

|
|
19
|
+
|
|
20
|
+
## Install
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
uv tool install git+https://github.com/reorx/skm
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Quick Start
|
|
27
|
+
|
|
28
|
+
1. Create `~/.config/skm/skills.yaml`:
|
|
29
|
+
|
|
30
|
+
```yaml
|
|
31
|
+
packages:
|
|
32
|
+
- repo: https://github.com/vercel-labs/agent-skills
|
|
33
|
+
skills:
|
|
34
|
+
- vercel-react-best-practices
|
|
35
|
+
- vercel-react-native-skills
|
|
36
|
+
- repo: https://github.com/blader/humanizer
|
|
37
|
+
- local_path: ~/Code/my-custom-skills # use a local directory instead of a git repo
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
2. Run install (`skm i` for short):
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
skm install
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Skills are cloned (or symlinked from local paths) into your agent directories (`~/.claude/skills/`, `~/.codex/skills/`, etc.).
|
|
47
|
+
|
|
48
|
+
### Install from a source directly
|
|
49
|
+
|
|
50
|
+
You can also install skills directly from a repo URL or local path — no need to edit `skills.yaml` first:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
# Install from a GitHub repo (interactive skill & agent selection)
|
|
54
|
+
skm install https://github.com/vercel-labs/agent-skills
|
|
55
|
+
|
|
56
|
+
# Install a specific skill by name
|
|
57
|
+
skm install https://github.com/vercel-labs/agent-skills vercel-react-best-practices
|
|
58
|
+
|
|
59
|
+
# Install from a local directory
|
|
60
|
+
skm install ~/Code/my-custom-skills
|
|
61
|
+
|
|
62
|
+
# Skip interactive prompts with --agents-includes / --agents-excludes
|
|
63
|
+
skm install https://github.com/blader/humanizer --agents-includes claude,codex
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
This detects available skills, lets you pick which ones to install (unless a specific skill name is given), and automatically adds the package to your `skills.yaml` config.
|
|
67
|
+
|
|
68
|
+
## Commands
|
|
69
|
+
|
|
70
|
+
| Command | Description |
|
|
71
|
+
|---|---|
|
|
72
|
+
| `skm install` (or `skm i`) | Install all packages from config. Clone repos (or link local paths), detect skills, symlink to agents, write lock file. Idempotent — also removes stale links (see below). |
|
|
73
|
+
| `skm install <source> [skill]` (or `skm i`) | Install directly from a repo URL or local path without editing config. Interactively select skills and agents, then auto-update config. |
|
|
74
|
+
| `skm list` | Show installed skills and their linked paths. |
|
|
75
|
+
| `skm list --all` | Show all skills across all agent directories, marking which are managed by skm. |
|
|
76
|
+
| `skm view <source>` | Browse and preview skills from a repo URL or local path without installing. |
|
|
77
|
+
| `skm check-updates` | Fetch remotes and show available updates (skips `local_path` packages). |
|
|
78
|
+
| `skm update <skill>` | Pull latest for a skill's repo, re-detect, re-link, update lock (skips `local_path` packages). |
|
|
79
|
+
|
|
80
|
+
## Config Format
|
|
81
|
+
|
|
82
|
+
`~/.config/skm/skills.yaml`:
|
|
83
|
+
|
|
84
|
+
```yaml
|
|
85
|
+
agents:
|
|
86
|
+
default: # optional: select which agents are active (omit = all)
|
|
87
|
+
- claude
|
|
88
|
+
- standard
|
|
89
|
+
|
|
90
|
+
packages:
|
|
91
|
+
- repo: https://github.com/vercel-labs/agent-skills
|
|
92
|
+
skills: # optional: install only these skills (omit = all)
|
|
93
|
+
- vercel-react-best-practices
|
|
94
|
+
agents: # optional: further filter agents for this package
|
|
95
|
+
excludes:
|
|
96
|
+
- standard
|
|
97
|
+
|
|
98
|
+
- repo: https://github.com/blader/humanizer # installs all detected skills to default agents
|
|
99
|
+
|
|
100
|
+
- local_path: ~/Code/my-custom-skills # use a local directory as package source
|
|
101
|
+
skills:
|
|
102
|
+
- my-skill
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Each package must specify exactly one of `repo` or `local_path`. Local path packages use the directory directly (no cloning) and are skipped by `check-updates` and `update`.
|
|
106
|
+
|
|
107
|
+
## Install Sync Behavior
|
|
108
|
+
|
|
109
|
+
`skm install` treats `skills.yaml` as a declarative state file. Each run syncs the agent directories to match the config:
|
|
110
|
+
|
|
111
|
+
- **New skills** are linked to agent directories.
|
|
112
|
+
- **Removed skills** (dropped from a package's `skills:` list, or entire package removed) have their links deleted.
|
|
113
|
+
- **Agent config changes** (e.g. adding `excludes: [openclaw]`) remove links from excluded agents while keeping links in others.
|
|
114
|
+
|
|
115
|
+
Only links tracked in `skills-lock.yaml` are affected. Manually created files or skills installed by other tools in agent directories are never touched.
|
|
116
|
+
|
|
117
|
+
## Skill Detection
|
|
118
|
+
|
|
119
|
+
A skill is a directory containing a `SKILL.md` file with YAML frontmatter (`name` field required). Detection order:
|
|
120
|
+
|
|
121
|
+
1. Root `SKILL.md` — the repo itself is a singleton skill
|
|
122
|
+
2. `./skills/` subdirectory exists — scan its children
|
|
123
|
+
3. Otherwise — walk all subdirectories from repo root
|
|
124
|
+
4. Stop descending once `SKILL.md` is found (no nested skills)
|
|
125
|
+
|
|
126
|
+
## Known Agents
|
|
127
|
+
|
|
128
|
+
Skills are symlinked into these directories by default:
|
|
129
|
+
|
|
130
|
+
| Agent | Path |
|
|
131
|
+
|---|---|
|
|
132
|
+
| `standard` | `~/.agents/skills/` |
|
|
133
|
+
| `claude` | `~/.claude/skills/` |
|
|
134
|
+
| `codex` | `~/.codex/skills/` |
|
|
135
|
+
| `openclaw` | `~/.openclaw/skills/` |
|
|
136
|
+
|
|
137
|
+
## CLI Path Overrides
|
|
138
|
+
|
|
139
|
+
Override default paths for testing or custom setups:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
skm --config /tmp/test.yaml \
|
|
143
|
+
--store /tmp/store \
|
|
144
|
+
--lock /tmp/lock.yaml \
|
|
145
|
+
--agents-dir /tmp/agents \
|
|
146
|
+
install
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Key Paths
|
|
150
|
+
|
|
151
|
+
- **Config:** `~/.config/skm/skills.yaml`
|
|
152
|
+
- **Lock:** `~/.config/skm/skills-lock.yaml`
|
|
153
|
+
- **Store:** `~/.local/share/skm/skills/`
|
|
154
|
+
|
|
155
|
+
## Development
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
uv sync
|
|
159
|
+
uv run pytest -v # run tests
|
|
160
|
+
uv run skm --help # run CLI
|
|
161
|
+
```
|
skm_cli-0.1.0/README.md
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# SKM - Skill Manager
|
|
2
|
+
|
|
3
|
+
A CLI tool that manages **global** AI agent skills from GitHub repos or local directories. Clone repos or link local paths, detect skills via `SKILL.md`, and symlink them into agent directories — all driven by a single YAML config.
|
|
4
|
+
|
|
5
|
+
> **Note:** skm manages skills at the user level (e.g. `~/.claude/skills/`), not at the project level. It is not intended for installing skills into project-scoped directories.
|
|
6
|
+
|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
uv tool install git+https://github.com/reorx/skm
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
1. Create `~/.config/skm/skills.yaml`:
|
|
18
|
+
|
|
19
|
+
```yaml
|
|
20
|
+
packages:
|
|
21
|
+
- repo: https://github.com/vercel-labs/agent-skills
|
|
22
|
+
skills:
|
|
23
|
+
- vercel-react-best-practices
|
|
24
|
+
- vercel-react-native-skills
|
|
25
|
+
- repo: https://github.com/blader/humanizer
|
|
26
|
+
- local_path: ~/Code/my-custom-skills # use a local directory instead of a git repo
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
2. Run install (`skm i` for short):
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
skm install
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Skills are cloned (or symlinked from local paths) into your agent directories (`~/.claude/skills/`, `~/.codex/skills/`, etc.).
|
|
36
|
+
|
|
37
|
+
### Install from a source directly
|
|
38
|
+
|
|
39
|
+
You can also install skills directly from a repo URL or local path — no need to edit `skills.yaml` first:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# Install from a GitHub repo (interactive skill & agent selection)
|
|
43
|
+
skm install https://github.com/vercel-labs/agent-skills
|
|
44
|
+
|
|
45
|
+
# Install a specific skill by name
|
|
46
|
+
skm install https://github.com/vercel-labs/agent-skills vercel-react-best-practices
|
|
47
|
+
|
|
48
|
+
# Install from a local directory
|
|
49
|
+
skm install ~/Code/my-custom-skills
|
|
50
|
+
|
|
51
|
+
# Skip interactive prompts with --agents-includes / --agents-excludes
|
|
52
|
+
skm install https://github.com/blader/humanizer --agents-includes claude,codex
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
This detects available skills, lets you pick which ones to install (unless a specific skill name is given), and automatically adds the package to your `skills.yaml` config.
|
|
56
|
+
|
|
57
|
+
## Commands
|
|
58
|
+
|
|
59
|
+
| Command | Description |
|
|
60
|
+
|---|---|
|
|
61
|
+
| `skm install` (or `skm i`) | Install all packages from config. Clone repos (or link local paths), detect skills, symlink to agents, write lock file. Idempotent — also removes stale links (see below). |
|
|
62
|
+
| `skm install <source> [skill]` (or `skm i`) | Install directly from a repo URL or local path without editing config. Interactively select skills and agents, then auto-update config. |
|
|
63
|
+
| `skm list` | Show installed skills and their linked paths. |
|
|
64
|
+
| `skm list --all` | Show all skills across all agent directories, marking which are managed by skm. |
|
|
65
|
+
| `skm view <source>` | Browse and preview skills from a repo URL or local path without installing. |
|
|
66
|
+
| `skm check-updates` | Fetch remotes and show available updates (skips `local_path` packages). |
|
|
67
|
+
| `skm update <skill>` | Pull latest for a skill's repo, re-detect, re-link, update lock (skips `local_path` packages). |
|
|
68
|
+
|
|
69
|
+
## Config Format
|
|
70
|
+
|
|
71
|
+
`~/.config/skm/skills.yaml`:
|
|
72
|
+
|
|
73
|
+
```yaml
|
|
74
|
+
agents:
|
|
75
|
+
default: # optional: select which agents are active (omit = all)
|
|
76
|
+
- claude
|
|
77
|
+
- standard
|
|
78
|
+
|
|
79
|
+
packages:
|
|
80
|
+
- repo: https://github.com/vercel-labs/agent-skills
|
|
81
|
+
skills: # optional: install only these skills (omit = all)
|
|
82
|
+
- vercel-react-best-practices
|
|
83
|
+
agents: # optional: further filter agents for this package
|
|
84
|
+
excludes:
|
|
85
|
+
- standard
|
|
86
|
+
|
|
87
|
+
- repo: https://github.com/blader/humanizer # installs all detected skills to default agents
|
|
88
|
+
|
|
89
|
+
- local_path: ~/Code/my-custom-skills # use a local directory as package source
|
|
90
|
+
skills:
|
|
91
|
+
- my-skill
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Each package must specify exactly one of `repo` or `local_path`. Local path packages use the directory directly (no cloning) and are skipped by `check-updates` and `update`.
|
|
95
|
+
|
|
96
|
+
## Install Sync Behavior
|
|
97
|
+
|
|
98
|
+
`skm install` treats `skills.yaml` as a declarative state file. Each run syncs the agent directories to match the config:
|
|
99
|
+
|
|
100
|
+
- **New skills** are linked to agent directories.
|
|
101
|
+
- **Removed skills** (dropped from a package's `skills:` list, or entire package removed) have their links deleted.
|
|
102
|
+
- **Agent config changes** (e.g. adding `excludes: [openclaw]`) remove links from excluded agents while keeping links in others.
|
|
103
|
+
|
|
104
|
+
Only links tracked in `skills-lock.yaml` are affected. Manually created files or skills installed by other tools in agent directories are never touched.
|
|
105
|
+
|
|
106
|
+
## Skill Detection
|
|
107
|
+
|
|
108
|
+
A skill is a directory containing a `SKILL.md` file with YAML frontmatter (`name` field required). Detection order:
|
|
109
|
+
|
|
110
|
+
1. Root `SKILL.md` — the repo itself is a singleton skill
|
|
111
|
+
2. `./skills/` subdirectory exists — scan its children
|
|
112
|
+
3. Otherwise — walk all subdirectories from repo root
|
|
113
|
+
4. Stop descending once `SKILL.md` is found (no nested skills)
|
|
114
|
+
|
|
115
|
+
## Known Agents
|
|
116
|
+
|
|
117
|
+
Skills are symlinked into these directories by default:
|
|
118
|
+
|
|
119
|
+
| Agent | Path |
|
|
120
|
+
|---|---|
|
|
121
|
+
| `standard` | `~/.agents/skills/` |
|
|
122
|
+
| `claude` | `~/.claude/skills/` |
|
|
123
|
+
| `codex` | `~/.codex/skills/` |
|
|
124
|
+
| `openclaw` | `~/.openclaw/skills/` |
|
|
125
|
+
|
|
126
|
+
## CLI Path Overrides
|
|
127
|
+
|
|
128
|
+
Override default paths for testing or custom setups:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
skm --config /tmp/test.yaml \
|
|
132
|
+
--store /tmp/store \
|
|
133
|
+
--lock /tmp/lock.yaml \
|
|
134
|
+
--agents-dir /tmp/agents \
|
|
135
|
+
install
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Key Paths
|
|
139
|
+
|
|
140
|
+
- **Config:** `~/.config/skm/skills.yaml`
|
|
141
|
+
- **Lock:** `~/.config/skm/skills-lock.yaml`
|
|
142
|
+
- **Store:** `~/.local/share/skm/skills/`
|
|
143
|
+
|
|
144
|
+
## Development
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
uv sync
|
|
148
|
+
uv run pytest -v # run tests
|
|
149
|
+
uv run skm --help # run CLI
|
|
150
|
+
```
|
skm_cli-0.1.0/draft.md
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
build skm, which is a skill manager that manage agent skills by a certral yaml config.
|
|
2
|
+
|
|
3
|
+
skm should be build with uv and python, use python modern packaing best practices. use click library to implement CLI.
|
|
4
|
+
|
|
5
|
+
skm can detect skills from a github repo. follow the patterns:
|
|
6
|
+
- find ./skills dir, if exists, start walk through from ./skills; if not exists, start walk through from ./
|
|
7
|
+
- how to walk through: iterate the sub dirs, if a dir has SKILL.md, it's a skill, stop digging down that dir
|
|
8
|
+
- note that ./ may also contain a SKILL.md, in this case the repo itself is a singleton skill, and no need to start the walk through
|
|
9
|
+
|
|
10
|
+
## Config
|
|
11
|
+
|
|
12
|
+
config path: `~/.config/skm/skills.yaml`
|
|
13
|
+
|
|
14
|
+
see @skills.example.yaml for the config example:
|
|
15
|
+
- repo: github repo url
|
|
16
|
+
- skills: list of skill name to use in this repo. note that this is the name in skill frontmatter, not the skill dir's name.
|
|
17
|
+
- agents: configure which agents to install this skill. either `includes` or `excludes` is configured, by default install to all the known agents.
|
|
18
|
+
|
|
19
|
+
skills should be cloned to a central path `~/.local/share/skm/skills/`, then soft link to agents according to `agents:` option. when linking skills from the central path to the agent's skill dir, you should always use the skill's frontmatter name as the target dir name.
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
## Agents
|
|
23
|
+
|
|
24
|
+
currently support agents:
|
|
25
|
+
- standard dir: `~/.agents/skills`
|
|
26
|
+
- claude: `~/.claude/skills`
|
|
27
|
+
- codex: `~/.codex/skills`
|
|
28
|
+
- openclaw: `~/.openclaw/skills`
|
|
29
|
+
|
|
30
|
+
## CLI
|
|
31
|
+
|
|
32
|
+
- `skm install`: install/remove skills based on config, this command does not update an installed skill. a lock file (~/.config/skm/skills-lock.yaml`) will be generated or updated after install, representing the version (commit), linked pathes, and other states of installed skills.
|
|
33
|
+
- `skm check-updates`: check for each skills' repo to see if there's any updates, list the git log for each skill with new commits, similar to some nvim plugin managers like how lazyvim does
|
|
34
|
+
- `skm update <skill-name>`: update a skill and show changes, reflect on skills-lock.yaml
|
|
35
|
+
- `skm list`: list each installed skill with the pathes they are linked to.
|
|
Binary file
|