@mcowger/skillfu 0.1.0
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.
- package/README.md +221 -0
- package/completions/_skillfu +83 -0
- package/completions/skillfu.bash +71 -0
- package/completions/skillfu.fish +35 -0
- package/dist/skillfu-cli.mjs +10583 -0
- package/package.json +54 -0
package/README.md
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
# skillfu
|
|
2
|
+
|
|
3
|
+
A minimal CLI for installing agent skills. Symlink-only, lockfile-driven.
|
|
4
|
+
|
|
5
|
+
**skillfu** gives your agents new capabilities instantly — _"I know kung fu."_
|
|
6
|
+
|
|
7
|
+
It's a focused replacement for the Vercel `skills` CLI — it does one thing well: install, track, and update skills via symlinks with a lockfile as the source of truth.
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# npm
|
|
13
|
+
npm install -g @mcowger/skillfu
|
|
14
|
+
|
|
15
|
+
# From source
|
|
16
|
+
git clone <repo-url> skillfu && cd skillfu
|
|
17
|
+
bun install
|
|
18
|
+
bun run build
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Commands
|
|
22
|
+
|
|
23
|
+
### `skillfu add <source>`
|
|
24
|
+
|
|
25
|
+
Install skills from a GitHub repo or local path.
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
# Install all skills from a repo (global)
|
|
29
|
+
skillfu add vercel-labs/agent-skills
|
|
30
|
+
|
|
31
|
+
# Install specific skills
|
|
32
|
+
skillfu add vercel-labs/agent-skills --skill frontend-design --skill skill-creator
|
|
33
|
+
|
|
34
|
+
# Install to project directory (local scope)
|
|
35
|
+
skillfu add vercel-labs/agent-skills --skill frontend-design -l
|
|
36
|
+
|
|
37
|
+
# Install from a local path
|
|
38
|
+
skillfu add ./my-skills
|
|
39
|
+
|
|
40
|
+
# Install from a specific branch
|
|
41
|
+
skillfu add vercel-labs/agent-skills --ref develop --skill frontend-design
|
|
42
|
+
|
|
43
|
+
# Shorthand: @skill-name filter
|
|
44
|
+
skillfu add vercel-labs/agent-skills@frontend-design
|
|
45
|
+
|
|
46
|
+
# Shorthand: #branch reference
|
|
47
|
+
skillfu add vercel-labs/agent-skills#develop
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
| Option | Description |
|
|
51
|
+
|---|---|
|
|
52
|
+
| `-s, --skill <name>` | Install specific skill(s) by name. Repeatable. |
|
|
53
|
+
| `-l, --local` | Install to project directory (`.agents/skills/`) |
|
|
54
|
+
| `-y, --yes` | Skip confirmation prompts |
|
|
55
|
+
| `--ref <branch>` | Git branch or tag to install from |
|
|
56
|
+
|
|
57
|
+
### `skillfu remove <skill-name>...`
|
|
58
|
+
|
|
59
|
+
Remove installed skills.
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
skillfu remove frontend-design
|
|
63
|
+
skillfu remove frontend-design skill-creator
|
|
64
|
+
skillfu remove frontend-design -l # from project scope
|
|
65
|
+
skillfu remove frontend-design -y # skip confirmation
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
| Option | Description |
|
|
69
|
+
|---|---|
|
|
70
|
+
| `-l, --local` | Remove from project scope |
|
|
71
|
+
| `-y, --yes` | Skip confirmation prompts |
|
|
72
|
+
|
|
73
|
+
### `skillfu install`
|
|
74
|
+
|
|
75
|
+
Ensure installed skills match the lockfile. Idempotent — safe to run repeatedly (like `npm ci`).
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
skillfu install # restore global skills from lockfile
|
|
79
|
+
skillfu install -l # restore project skills from lockfile
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
| Option | Description |
|
|
83
|
+
|---|---|
|
|
84
|
+
| `-l, --local` | Install from project lockfile |
|
|
85
|
+
|
|
86
|
+
This is the primary command for:
|
|
87
|
+
- Setting up a new machine after cloning a repo (with `.agents/skills.lock` committed)
|
|
88
|
+
- Recovering from accidentally deleted symlinks
|
|
89
|
+
- CI/CD environments
|
|
90
|
+
- Removing orphaned skills not tracked in the lockfile
|
|
91
|
+
|
|
92
|
+
### `skillfu update`
|
|
93
|
+
|
|
94
|
+
Check for and install updated versions of skills.
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
skillfu update # update all global skills
|
|
98
|
+
skillfu update -l # update all project skills
|
|
99
|
+
skillfu update --skill frontend-design # update a specific skill
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
| Option | Description |
|
|
103
|
+
|---|---|
|
|
104
|
+
| `-l, --local` | Update project-scoped skills |
|
|
105
|
+
| `-s, --skill <name>` | Update only specific skill(s) |
|
|
106
|
+
| `-y, --yes` | Skip confirmation prompts |
|
|
107
|
+
|
|
108
|
+
Update detection uses the [skills.sh API](https://skills.sh/docs/api) for hash comparison, falling back to the GitHub Trees API when unavailable. Local path skills cannot be updated remotely.
|
|
109
|
+
|
|
110
|
+
### `skillfu completions <shell>`
|
|
111
|
+
|
|
112
|
+
Output shell completion script.
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
# bash
|
|
116
|
+
skillfu completions bash > ~/.local/share/bash-completion/completions/skillfu
|
|
117
|
+
|
|
118
|
+
# zsh
|
|
119
|
+
skillfu completions zsh > ~/.zfunc/_skillfu
|
|
120
|
+
|
|
121
|
+
# fish
|
|
122
|
+
skillfu completions fish > ~/.config/fish/completions/skillfu.fish
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Storage
|
|
126
|
+
|
|
127
|
+
### Global scope (default)
|
|
128
|
+
|
|
129
|
+
```
|
|
130
|
+
~/.config/skillfu/
|
|
131
|
+
├── skills.lock # Lockfile
|
|
132
|
+
└── skills/ # Canonical skill files
|
|
133
|
+
└── frontend-design/
|
|
134
|
+
└── SKILL.md
|
|
135
|
+
|
|
136
|
+
~/.agents/skills/ # Symlinks (where agents look)
|
|
137
|
+
└── frontend-design → ~/.config/skillfu/skills/frontend-design/
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Local scope (`-l` flag)
|
|
141
|
+
|
|
142
|
+
```
|
|
143
|
+
<project>/
|
|
144
|
+
├── .agents/
|
|
145
|
+
│ ├── skills.lock # Project lockfile (commit this!)
|
|
146
|
+
│ └── skills/ # Skill files (no symlinks needed)
|
|
147
|
+
│ └── frontend-design/
|
|
148
|
+
│ └── SKILL.md
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Any agent that reads from `~/.agents/skills/` (global) or `.agents/skills/` (local) picks up installed skills automatically — no agent-specific configuration needed.
|
|
152
|
+
|
|
153
|
+
## Source Formats
|
|
154
|
+
|
|
155
|
+
| Format | Example |
|
|
156
|
+
|---|---|
|
|
157
|
+
| GitHub shorthand | `vercel-labs/agent-skills` |
|
|
158
|
+
| Shorthand with skill filter | `vercel-labs/agent-skills@frontend-design` |
|
|
159
|
+
| Shorthand with branch | `vercel-labs/agent-skills#develop` |
|
|
160
|
+
| Shorthand with branch + skill | `vercel-labs/agent-skills#develop@frontend-design` |
|
|
161
|
+
| Full GitHub URL | `https://github.com/vercel-labs/agent-skills` |
|
|
162
|
+
| GitHub URL with branch/path | `https://github.com/vercel-labs/agent-skills/tree/main/skills/design` |
|
|
163
|
+
| Local path | `./my-skills` or `/absolute/path` |
|
|
164
|
+
|
|
165
|
+
## Lockfile
|
|
166
|
+
|
|
167
|
+
Skills are tracked in a lockfile that serves as the source of truth:
|
|
168
|
+
|
|
169
|
+
- **Global**: `~/.config/skillfu/skills.lock`
|
|
170
|
+
- **Project**: `.agents/skills.lock`
|
|
171
|
+
|
|
172
|
+
The project lockfile is designed to be committed to version control. Skills are sorted alphabetically and timestamps are omitted to minimize merge conflicts — two branches adding different skills produce non-overlapping JSON keys that git can auto-merge.
|
|
173
|
+
|
|
174
|
+
## What Are Agent Skills?
|
|
175
|
+
|
|
176
|
+
Agent skills are reusable instruction sets that extend your coding agent's capabilities. They're defined in `SKILL.md` files with YAML frontmatter:
|
|
177
|
+
|
|
178
|
+
```markdown
|
|
179
|
+
---
|
|
180
|
+
name: my-skill
|
|
181
|
+
description: What this skill does and when to use it
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
# My Skill
|
|
185
|
+
|
|
186
|
+
Instructions for the agent to follow when this skill is activated.
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
Discover more skills at [skills.sh](https://skills.sh).
|
|
190
|
+
|
|
191
|
+
## Environment Variables
|
|
192
|
+
|
|
193
|
+
| Variable | Description |
|
|
194
|
+
|---|---|
|
|
195
|
+
| `SKILLFU_CONFIG_DIR` | Override config directory (`~/.config/skillfu/`) |
|
|
196
|
+
| `SKILLFU_CLONE_TIMEOUT_MS` | Git clone timeout in ms (default: 300000) |
|
|
197
|
+
| `GITHUB_TOKEN` / `GH_TOKEN` | GitHub API token for higher rate limits |
|
|
198
|
+
| `INSTALL_INTERNAL_SKILLS` | Set to `1` to include skills marked `internal: true` |
|
|
199
|
+
| `SKILLFU_SKILLS_SH_KEY` | API key for skills.sh (higher rate limits) |
|
|
200
|
+
|
|
201
|
+
## Differences from Vercel `skills`
|
|
202
|
+
|
|
203
|
+
| | `skills` | `skillfu` |
|
|
204
|
+
|---|---|---|
|
|
205
|
+
| Scope | 50+ agents with per-agent symlinks | Single target: `~/.agents/skills` or `.agents/skills` |
|
|
206
|
+
| Install methods | Symlink or copy | Symlink only |
|
|
207
|
+
| Discovery | `find`, `list`, search API | None |
|
|
208
|
+
| Lockfile | Global only, separate format per scope | Separate lockfiles per scope, co-located |
|
|
209
|
+
| Update detection | GitHub Trees API | skills.sh API with Trees API fallback |
|
|
210
|
+
| Source formats | GitHub, GitLab, well-known, git URLs, local | GitHub, GitHub URLs, local paths |
|
|
211
|
+
| Agent detection | Auto-detects 50+ agents | No agent detection |
|
|
212
|
+
| Telemetry | Anonymous usage tracking | None |
|
|
213
|
+
|
|
214
|
+
## Development
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
bun install # Install dependencies
|
|
218
|
+
bun run dev add ... # Run locally
|
|
219
|
+
bun test # Run tests
|
|
220
|
+
bun run build # Compile to dist/skillfu
|
|
221
|
+
```
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
#compdef skillfu
|
|
2
|
+
# skillfu shell completions for zsh
|
|
3
|
+
# Install: skillfu completions zsh > ~/.zfunc/_skillfu
|
|
4
|
+
# Then: add ~/.zfunc to your fpath in ~/.zshrc
|
|
5
|
+
|
|
6
|
+
_skillfu() {
|
|
7
|
+
local -a commands
|
|
8
|
+
commands=(
|
|
9
|
+
'add:Install skills from a GitHub repo or local path'
|
|
10
|
+
'remove:Remove installed skills'
|
|
11
|
+
'install:Ensure installed skills match the lockfile'
|
|
12
|
+
'update:Update skills to their latest versions'
|
|
13
|
+
'completions:Output shell completion script'
|
|
14
|
+
'help:Display help for a command'
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
_arguments -C \
|
|
18
|
+
'1:command:->command' \
|
|
19
|
+
'*::arg:->args'
|
|
20
|
+
|
|
21
|
+
case $state in
|
|
22
|
+
command)
|
|
23
|
+
_describe 'command' commands
|
|
24
|
+
;;
|
|
25
|
+
args)
|
|
26
|
+
case ${words[1]} in
|
|
27
|
+
add)
|
|
28
|
+
_arguments \
|
|
29
|
+
'-s+[Install specific skill(s) by name]:skill:' \
|
|
30
|
+
'--skill+[Install specific skill(s) by name]:skill:' \
|
|
31
|
+
'-l[Install to project directory]' \
|
|
32
|
+
'--local[Install to project directory]' \
|
|
33
|
+
'-y[Skip confirmation prompts]' \
|
|
34
|
+
'--yes[Skip confirmation prompts]' \
|
|
35
|
+
'--ref+[Git branch or tag to install from]:branch:' \
|
|
36
|
+
'1:source:_files'
|
|
37
|
+
;;
|
|
38
|
+
remove)
|
|
39
|
+
local -a installed_skills
|
|
40
|
+
local lockfile="$HOME/.config/skillfu/skills.lock"
|
|
41
|
+
if [[ -f "$lockfile" ]]; then
|
|
42
|
+
installed_skills=(${(f)"$(grep -o '"[a-z0-9-]*":' "$lockfile" | tr -d '":' | grep -v version)"})
|
|
43
|
+
fi
|
|
44
|
+
_arguments \
|
|
45
|
+
'-l[Remove from project scope]' \
|
|
46
|
+
'--local[Remove from project scope]' \
|
|
47
|
+
'-y[Skip confirmation prompts]' \
|
|
48
|
+
'--yes[Skip confirmation prompts]' \
|
|
49
|
+
'*:skill:->skills'
|
|
50
|
+
|
|
51
|
+
if [[ $state == skills ]]; then
|
|
52
|
+
_describe 'installed skill' installed_skills
|
|
53
|
+
fi
|
|
54
|
+
;;
|
|
55
|
+
install)
|
|
56
|
+
_arguments \
|
|
57
|
+
'-l[Install from project lockfile]' \
|
|
58
|
+
'--local[Install from project lockfile]'
|
|
59
|
+
;;
|
|
60
|
+
update)
|
|
61
|
+
local -a installed_skills
|
|
62
|
+
local lockfile="$HOME/.config/skillfu/skills.lock"
|
|
63
|
+
if [[ -f "$lockfile" ]]; then
|
|
64
|
+
installed_skills=(${(f)"$(grep -o '"[a-z0-9-]*":' "$lockfile" | tr -d '":' | grep -v version)"})
|
|
65
|
+
fi
|
|
66
|
+
_arguments \
|
|
67
|
+
'-l[Update project-scoped skills]' \
|
|
68
|
+
'--local[Update project-scoped skills]' \
|
|
69
|
+
'-s+[Update only specific skill(s)]:skill:' \
|
|
70
|
+
'--skill+[Update only specific skill(s)]:skill:' \
|
|
71
|
+
'-y[Skip confirmation prompts]' \
|
|
72
|
+
'--yes[Skip confirmation prompts]'
|
|
73
|
+
;;
|
|
74
|
+
completions)
|
|
75
|
+
_arguments \
|
|
76
|
+
'1:shell:(bash zsh fish)'
|
|
77
|
+
;;
|
|
78
|
+
esac
|
|
79
|
+
;;
|
|
80
|
+
esac
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
_skillfu "$@"
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# skillfu shell completions for bash
|
|
3
|
+
# Install: skillfu completions bash > ~/.local/share/bash-completion/completions/skillfu
|
|
4
|
+
# Or: skillfu completions bash > /etc/bash_completion.d/skillfu
|
|
5
|
+
|
|
6
|
+
_skillfu_completions() {
|
|
7
|
+
local cur prev words cword
|
|
8
|
+
_init_completion || return
|
|
9
|
+
|
|
10
|
+
# If completing the first word after 'skillfu', offer subcommands
|
|
11
|
+
if [[ ${#words[@]} -eq 2 ]]; then
|
|
12
|
+
COMPREPLY=($(compgen -W "add remove install update completions help" -- "${cur}"))
|
|
13
|
+
return
|
|
14
|
+
fi
|
|
15
|
+
|
|
16
|
+
local cmd="${words[1]}"
|
|
17
|
+
|
|
18
|
+
case "${cmd}" in
|
|
19
|
+
add)
|
|
20
|
+
# Complete options
|
|
21
|
+
case "${prev}" in
|
|
22
|
+
-s|--skill)
|
|
23
|
+
# No dynamic skill completion available
|
|
24
|
+
return
|
|
25
|
+
;;
|
|
26
|
+
--ref)
|
|
27
|
+
return
|
|
28
|
+
;;
|
|
29
|
+
esac
|
|
30
|
+
|
|
31
|
+
if [[ "${cur}" == -* ]]; then
|
|
32
|
+
COMPREPLY=($(compgen -W "-s --skill -l --local -y --yes --ref" -- "${cur}"))
|
|
33
|
+
fi
|
|
34
|
+
;;
|
|
35
|
+
remove)
|
|
36
|
+
if [[ "${cur}" == -* ]]; then
|
|
37
|
+
COMPREPLY=($(compgen -W "-l --local -y --yes" -- "${cur}"))
|
|
38
|
+
else
|
|
39
|
+
# Offer installed skill names from lockfile
|
|
40
|
+
local lockfile="$HOME/.config/skillfu/skills.lock"
|
|
41
|
+
if [[ -f "${lockfile}" ]]; then
|
|
42
|
+
local skills=$(grep -o '"[a-z0-9-]*":' "${lockfile}" | tr -d '":' | grep -v version)
|
|
43
|
+
COMPREPLY=($(compgen -W "${skills}" -- "${cur}"))
|
|
44
|
+
fi
|
|
45
|
+
fi
|
|
46
|
+
;;
|
|
47
|
+
install)
|
|
48
|
+
COMPREPLY=($(compgen -W "-l --local" -- "${cur}"))
|
|
49
|
+
;;
|
|
50
|
+
update)
|
|
51
|
+
if [[ "${cur}" == -* ]]; then
|
|
52
|
+
COMPREPLY=($(compgen -W "-l --local -s --skill -y --yes" -- "${cur}"))
|
|
53
|
+
else
|
|
54
|
+
case "${prev}" in
|
|
55
|
+
-s|--skill)
|
|
56
|
+
local lockfile="$HOME/.config/skillfu/skills.lock"
|
|
57
|
+
if [[ -f "${lockfile}" ]]; then
|
|
58
|
+
local skills=$(grep -o '"[a-z0-9-]*":' "${lockfile}" | tr -d '":' | grep -v version)
|
|
59
|
+
COMPREPLY=($(compgen -W "${skills}" -- "${cur}"))
|
|
60
|
+
fi
|
|
61
|
+
;;
|
|
62
|
+
esac
|
|
63
|
+
fi
|
|
64
|
+
;;
|
|
65
|
+
completions)
|
|
66
|
+
COMPREPLY=($(compgen -W "bash zsh fish" -- "${cur}"))
|
|
67
|
+
;;
|
|
68
|
+
esac
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
complete -F _skillfu_completions skillfu
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# skillfu shell completions for fish
|
|
2
|
+
# Install: skillfu completions fish > ~/.config/fish/completions/skillfu.fish
|
|
3
|
+
|
|
4
|
+
# Disable file completions by default
|
|
5
|
+
complete -c skillfu -f
|
|
6
|
+
|
|
7
|
+
# Top-level subcommands
|
|
8
|
+
complete -c skillfu -n __fish_use_subcommand -a add -d 'Install skills from a GitHub repo or local path'
|
|
9
|
+
complete -c skillfu -n __fish_use_subcommand -a remove -d 'Remove installed skills'
|
|
10
|
+
complete -c skillfu -n __fish_use_subcommand -a install -d 'Ensure installed skills match the lockfile'
|
|
11
|
+
complete -c skillfu -n __fish_use_subcommand -a update -d 'Update skills to their latest versions'
|
|
12
|
+
complete -c skillfu -n __fish_use_subcommand -a completions -d 'Output shell completion script'
|
|
13
|
+
|
|
14
|
+
# add command
|
|
15
|
+
complete -c skillfu -n '__fish_seen_subcommand_from add' -s s -l skill -d 'Install specific skill(s) by name' -r
|
|
16
|
+
complete -c skillfu -n '__fish_seen_subcommand_from add' -s l -l local -d 'Install to project directory'
|
|
17
|
+
complete -c skillfu -n '__fish_seen_subcommand_from add' -s y -l yes -d 'Skip confirmation prompts'
|
|
18
|
+
complete -c skillfu -n '__fish_seen_subcommand_from add' -l ref -d 'Git branch or tag' -r
|
|
19
|
+
|
|
20
|
+
# remove command
|
|
21
|
+
complete -c skillfu -n '__fish_seen_subcommand_from remove' -s l -l local -d 'Remove from project scope'
|
|
22
|
+
complete -c skillfu -n '__fish_seen_subcommand_from remove' -s y -l yes -d 'Skip confirmation prompts'
|
|
23
|
+
# Offer installed skill names
|
|
24
|
+
complete -c skillfu -n '__fish_seen_subcommand_from remove' -a '(grep -o \'"[a-z0-9-]*":\' ~/.config/skillfu/skills.lock 2>/dev/null | tr -d \'\":\' | grep -v version)'
|
|
25
|
+
|
|
26
|
+
# install command
|
|
27
|
+
complete -c skillfu -n '__fish_seen_subcommand_from install' -s l -l local -d 'Install from project lockfile'
|
|
28
|
+
|
|
29
|
+
# update command
|
|
30
|
+
complete -c skillfu -n '__fish_seen_subcommand_from update' -s l -l local -d 'Update project-scoped skills'
|
|
31
|
+
complete -c skillfu -n '__fish_seen_subcommand_from update' -s s -l skill -d 'Update only specific skill(s)' -r
|
|
32
|
+
complete -c skillfu -n '__fish_seen_subcommand_from update' -s y -l yes -d 'Skip confirmation prompts'
|
|
33
|
+
|
|
34
|
+
# completions command
|
|
35
|
+
complete -c skillfu -n '__fish_seen_subcommand_from completions' -a 'bash zsh fish'
|