@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 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'