skillscout-cli 0.1.0__tar.gz → 0.3.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.
- skillscout_cli-0.3.0/PKG-INFO +238 -0
- skillscout_cli-0.3.0/README.md +210 -0
- {skillscout_cli-0.1.0 → skillscout_cli-0.3.0}/pyproject.toml +3 -3
- skillscout_cli-0.3.0/skillscout/cli.py +204 -0
- skillscout_cli-0.3.0/skillscout/core.py +467 -0
- {skillscout_cli-0.1.0 → skillscout_cli-0.3.0}/skillscout/github.py +6 -5
- skillscout_cli-0.3.0/skillscout/history.py +153 -0
- skillscout_cli-0.3.0/skillscout/index.py +89 -0
- skillscout_cli-0.3.0/skillscout/persona.py +98 -0
- {skillscout_cli-0.1.0 → skillscout_cli-0.3.0}/skillscout/profile.example.toml +23 -2
- {skillscout_cli-0.1.0 → skillscout_cli-0.3.0}/skillscout/scan.py +5 -4
- {skillscout_cli-0.1.0 → skillscout_cli-0.3.0}/skillscout/schedule.py +1 -1
- {skillscout_cli-0.1.0 → skillscout_cli-0.3.0}/skillscout/score.py +26 -3
- {skillscout_cli-0.1.0 → skillscout_cli-0.3.0}/skillscout/skill.py +16 -6
- skillscout_cli-0.3.0/skillscout_cli.egg-info/PKG-INFO +238 -0
- {skillscout_cli-0.1.0 → skillscout_cli-0.3.0}/skillscout_cli.egg-info/SOURCES.txt +3 -0
- {skillscout_cli-0.1.0 → skillscout_cli-0.3.0}/tests/test_skillscout.py +264 -26
- skillscout_cli-0.1.0/PKG-INFO +0 -183
- skillscout_cli-0.1.0/README.md +0 -155
- skillscout_cli-0.1.0/skillscout/cli.py +0 -97
- skillscout_cli-0.1.0/skillscout/core.py +0 -293
- skillscout_cli-0.1.0/skillscout_cli.egg-info/PKG-INFO +0 -183
- {skillscout_cli-0.1.0 → skillscout_cli-0.3.0}/LICENSE +0 -0
- {skillscout_cli-0.1.0 → skillscout_cli-0.3.0}/setup.cfg +0 -0
- {skillscout_cli-0.1.0 → skillscout_cli-0.3.0}/skillscout/__init__.py +0 -0
- {skillscout_cli-0.1.0 → skillscout_cli-0.3.0}/skillscout_cli.egg-info/dependency_links.txt +0 -0
- {skillscout_cli-0.1.0 → skillscout_cli-0.3.0}/skillscout_cli.egg-info/entry_points.txt +0 -0
- {skillscout_cli-0.1.0 → skillscout_cli-0.3.0}/skillscout_cli.egg-info/requires.txt +0 -0
- {skillscout_cli-0.1.0 → skillscout_cli-0.3.0}/skillscout_cli.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: skillscout-cli
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: Keep your agent's skills current for each kind of work you do: weekly index, personas, scans, pinned installs
|
|
5
|
+
Author: Akshit Gupta
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://akshit9162.github.io/skillscout
|
|
8
|
+
Project-URL: Source, https://github.com/akshit9162/skillscout
|
|
9
|
+
Project-URL: Issues, https://github.com/akshit9162/skillscout/issues
|
|
10
|
+
Project-URL: Report, https://akshit9162.github.io/skillscout/report.html
|
|
11
|
+
Keywords: claude,claude-code,agent-skills,personas,subagents,security,supply-chain,llm
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Topic :: Security
|
|
21
|
+
Classifier: Topic :: Software Development
|
|
22
|
+
Requires-Python: >=3.11
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
Provides-Extra: dev
|
|
26
|
+
Requires-Dist: pytest; extra == "dev"
|
|
27
|
+
Dynamic: license-file
|
|
28
|
+
|
|
29
|
+
<p align="center">
|
|
30
|
+
<img src="https://raw.githubusercontent.com/akshit9162/skillscout/main/docs/assets/header.svg" width="760" alt="skillscout: keep your agent's skills current, safely" />
|
|
31
|
+
</p>
|
|
32
|
+
|
|
33
|
+
<p align="center">
|
|
34
|
+
<a href="https://akshit9162.github.io/skillscout">Website</a>  · 
|
|
35
|
+
<a href="https://akshit9162.github.io/skillscout/report.html">Report: what's inside 6,726 skills</a>  · 
|
|
36
|
+
<a href="#install">Install</a>  · 
|
|
37
|
+
<a href="#personas">Personas</a>  · 
|
|
38
|
+
<a href="#a-week-with-skillscout">A week with it</a>  · 
|
|
39
|
+
<a href="#how-it-works">How it works</a>  · 
|
|
40
|
+
<a href="#what-gets-flagged">What gets flagged</a>
|
|
41
|
+
</p>
|
|
42
|
+
|
|
43
|
+
<p align="center">
|
|
44
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="MIT licence" /></a>
|
|
45
|
+
<a href="https://github.com/akshit9162/skillscout/actions/workflows/ci.yml"><img src="https://github.com/akshit9162/skillscout/actions/workflows/ci.yml/badge.svg" alt="CI" /></a>
|
|
46
|
+
<img src="https://img.shields.io/badge/python-3.11%2B-blue.svg" alt="Python 3.11+" />
|
|
47
|
+
<img src="https://img.shields.io/badge/dependencies-0-brightgreen.svg" alt="No dependencies" />
|
|
48
|
+
</p>
|
|
49
|
+
|
|
50
|
+
<p align="center">
|
|
51
|
+
<img src="https://raw.githubusercontent.com/akshit9162/skillscout/main/docs/assets/demo.svg" width="760" alt="Terminal demo: init drafts keywords from one line; persona add creates a brand persona; discover scores 23,865 skills with a section for the brand persona; persona build writes its agent; claude --agent brand starts it" />
|
|
52
|
+
</p>
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
claude plugin marketplace add akshit9162/skillscout && claude plugin install skillscout@skillscout
|
|
56
|
+
# or the CLI on its own
|
|
57
|
+
pipx install skillscout-cli
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
AI tooling moves weekly. New skills, plugins and agent workflows land on GitHub every day, the ones you
|
|
61
|
+
installed keep changing upstream, and last month's best practice is already stale. Nobody has time to
|
|
62
|
+
watch hundreds of repos.
|
|
63
|
+
|
|
64
|
+
**skillscout keeps your agent current, for each kind of work you do.** Every week a shared index of every
|
|
65
|
+
public skill it can find (23,865 from 1,092 repos at the last build) is rebuilt. skillscout scores it on your
|
|
66
|
+
machine against what *you* work on, tells you what's new and worth having, and shows you exactly what
|
|
67
|
+
changed in the skills you already use.
|
|
68
|
+
|
|
69
|
+
You probably don't do one kind of work. Coding on Monday, a landing page on Tuesday, investor emails on
|
|
70
|
+
Friday. So skillscout keeps **personas**: one per kind of work, each with its own search and its own Claude
|
|
71
|
+
Code agent, loaded with the best skills for that work and kept up to date as better ones appear.
|
|
72
|
+
|
|
73
|
+
Keeping up fast is only useful if it's safe. A skill is a set of instructions your agent follows
|
|
74
|
+
**with your permissions**, so skillscout scans every file for dangerous patterns, installs nothing without
|
|
75
|
+
your approval, pins each install to an exact commit, and re-scans every update before it can replace anything.
|
|
76
|
+
|
|
77
|
+
In a hand-checked run on 27 Oct 2026 over **6,726 skills in 95 repos**, 198 had at least one high-risk flag,
|
|
78
|
+
mostly `sudo` and `curl | sh` install steps, plus prompt-injection-style text and hidden Unicode.
|
|
79
|
+
The [report](https://akshit9162.github.io/skillscout/report.html) reads every one of the scariest flags: they were defenders.
|
|
80
|
+
|
|
81
|
+
It's a zero-dependency Python CLI, and it also ships as a skill, so your agent can run the whole loop for you
|
|
82
|
+
and still ask before every install.
|
|
83
|
+
|
|
84
|
+
## Personas
|
|
85
|
+
|
|
86
|
+
A persona is one side of your work, in your words. skillscout doesn't ship any: yours might be "builder",
|
|
87
|
+
"brand" and "outreach", someone else's "trading" and "thesis".
|
|
88
|
+
|
|
89
|
+
```text
|
|
90
|
+
You "set up personas for me" (in Claude Code, with the plugin)
|
|
91
|
+
Agent reads your recent sessions on this machine, with your OK (skillscout history)
|
|
92
|
+
→ proposes: builder · brand · outreach, each with the sessions it came from
|
|
93
|
+
You keep brand and builder, rename outreach to launches
|
|
94
|
+
Agent skillscout persona add brand --about "D2C marketing: ad copy, landing pages, Instagram reels"
|
|
95
|
+
→ keywords drafted from terms skills actually use: instagram reels, ad copy, landing pages...
|
|
96
|
+
skillscout discover → a "For your brand work" section in the report
|
|
97
|
+
skillscout persona build brand → ~/.claude/agents/brand.md, skills: copy, landing-page-design, script...
|
|
98
|
+
You claude --agent brand
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
From then on, each weekly report has a section per persona, and `persona build` swaps in a better skill when
|
|
102
|
+
one arrives (after you've read and approved it). `persona build` only ever rewrites the agent's `skills:` list:
|
|
103
|
+
its prompt, tone, tools, model and memory are yours.
|
|
104
|
+
|
|
105
|
+
The CLI works without the agent too:
|
|
106
|
+
|
|
107
|
+
```sh
|
|
108
|
+
skillscout persona add brand --about "D2C marketing: ad copy, landing pages, Instagram reels"
|
|
109
|
+
skillscout persona list # keywords, best installed skills, what's worth installing
|
|
110
|
+
skillscout persona build --all # write or update ~/.claude/agents/<name>.md
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
**Your history stays on your machine.** `skillscout history` reads `~/.claude/projects` only when you run it,
|
|
114
|
+
keeps only what you typed (no tool output, no pasted blocks, no links) and sends nothing anywhere. Grouping
|
|
115
|
+
sessions into personas is left to you or the agent in your own session: counting words can't tell short chat
|
|
116
|
+
messages apart reliably, and a wrong persona is worse than none.
|
|
117
|
+
|
|
118
|
+
## A week with skillscout
|
|
119
|
+
|
|
120
|
+
Example session (counts vary week to week):
|
|
121
|
+
|
|
122
|
+
```text
|
|
123
|
+
Monday 10:00 skillscout discover --notify (weekly, via schedule)
|
|
124
|
+
→ "23 recommended for you (4 new this run), 11 relevant but flagged high-risk"
|
|
125
|
+
→ plus a section per persona: "For your brand work", "For your builder work"
|
|
126
|
+
You skillscout show github/awesome-copilot:eval-driven-dev
|
|
127
|
+
→ flags with file:line, the full SKILL.md, overlaps with what you have
|
|
128
|
+
You skillscout approve eval-driven-dev → copied, pinned to its commit
|
|
129
|
+
Later skillscout updates → upstream changed it; here's the diff
|
|
130
|
+
You skillscout approve eval-driven-dev --update → re-scanned, then replaced
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Install
|
|
134
|
+
|
|
135
|
+
### As a Claude Code plugin (the agent drives it)
|
|
136
|
+
|
|
137
|
+
```sh
|
|
138
|
+
claude plugin marketplace add akshit9162/skillscout
|
|
139
|
+
claude plugin install skillscout@skillscout
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Then ask: *"find me skills for my Python and React work"*, or *"set up personas for me"*. The agent installs the CLI, runs the search,
|
|
143
|
+
summarises the report and shows you each skill's flags before asking to install it.
|
|
144
|
+
|
|
145
|
+
### As a CLI
|
|
146
|
+
|
|
147
|
+
```sh
|
|
148
|
+
pipx install skillscout-cli # or: uv tool install skillscout-cli
|
|
149
|
+
skillscout init --about "backend in Python, code review, RL evals, Postgres"
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
`init` writes `~/.skillscout/profile.toml` and drafts `[keywords]` from your line, using only terms that skills
|
|
153
|
+
actually use. Check them, then:
|
|
154
|
+
|
|
155
|
+
```sh
|
|
156
|
+
skillscout discover # score this week's index; writes ~/.skillscout/reports/<date>.md
|
|
157
|
+
skillscout list # ranked; REC = recommended
|
|
158
|
+
skillscout show <id> # every flag plus the full SKILL.md, before you decide
|
|
159
|
+
skillscout approve <id> # copy into ~/.claude/skills and pin the commit
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
`<id>` is `owner/repo:skill-name`. The bare skill name works when it's unique. If one repo has two skills with the same name, the second is `owner/repo:path/to/skill`.
|
|
163
|
+
|
|
164
|
+
## How it works
|
|
165
|
+
|
|
166
|
+
The crawl is the same for everyone, so it runs once a week in this repo's [index workflow](.github/workflows/index.yml) and is published as `index.json.gz`. `skillscout discover` downloads that one file (seconds, no GitHub token, your keywords never leave your machine) and scores it locally. `show` and `approve` fetch the skill and scan it again on your machine, so nothing is installed on the index's word. `discover --local` runs the whole crawl yourself instead.
|
|
167
|
+
|
|
168
|
+
Each published index carries a signed [build attestation](https://docs.github.com/en/actions/security-for-github-actions/using-artifact-attestations): proof that this repo's index workflow built that exact file. Check one with `gh attestation verify ~/.skillscout/index.json.gz --repo akshit9162/skillscout`, or set `verify = true` under `[index]` and `discover` checks every download and refuses one that fails.
|
|
169
|
+
|
|
170
|
+
| Step | What happens |
|
|
171
|
+
|---|---|
|
|
172
|
+
| **Discover** (weekly job, or `--local`) | Runs your GitHub searches (topics like `claude-skills`, `agent-skills`) plus your trusted repos, then follows every repo linked from curated lists (your `lists`, plus any `awesome-*` repo it finds). Drops archived, stale (no push in a year), unpopular and huge repos. |
|
|
173
|
+
| **Clone** | Sparse, shallow clones: only folders that contain a `SKILL.md`, minus media and archives, 16 repos at a time. Repos with no push since the last run aren't fetched again. Repo code is never run. |
|
|
174
|
+
| **Scan** | Static checks on every file in the skill, reported with file and line ([below](#what-gets-flagged)). A skill whose folder (git tree hash) and the scanner's rules are both unchanged keeps its last result instead of being read again. |
|
|
175
|
+
| **Score** (your machine) | 65% relevance to your keywords (phrases match in order, singular or plural), 20% stars, 15% freshness, plus a bonus for trusted repos. |
|
|
176
|
+
| **Conflicts** | Compared against your `~/.claude/skills` and plugin skills: same name, or a description close enough that both would fire on the same prompt. |
|
|
177
|
+
| **Report** | What's new since your last run, recommended skills, and relevant ones that are blocked and why. |
|
|
178
|
+
| **Approve** | You pick one. It's fetched and scanned again on your machine (that scan decides), then copied (symlinks dropped) and pinned in `~/.skillscout/skills.lock.json` with its commit and a content hash. |
|
|
179
|
+
| **Update** | `skillscout updates` diffs each pinned skill against upstream and applies nothing. Taking an update re-runs the scan, builds the new copy beside the old one and swaps them; if any step fails, the old copy and its pin stay. `skillscout rollback <id>` puts back the version an update replaced. |
|
|
180
|
+
|
|
181
|
+
## What gets flagged
|
|
182
|
+
|
|
183
|
+
| Level | Patterns |
|
|
184
|
+
|---|---|
|
|
185
|
+
| **High**, blocks install | Download piped into a shell · `sudo` · broad `rm -rf` · reading SSH keys or the keychain · decode-and-execute · uploading local files · hidden or direction-changing Unicode · "ignore previous instructions" · "don't tell the user" |
|
|
186
|
+
| **Medium** | Reading `.env` or API keys · force pushes · editing shell profiles or Claude settings · skipping permission prompts · hooks · scripts that make network calls · symlinks · binaries |
|
|
187
|
+
| **Low** | Other bundled scripts · no licence |
|
|
188
|
+
|
|
189
|
+
High-risk skills need `--accept-risk`, which the bundled skill tells the agent never to pass on its own.
|
|
190
|
+
|
|
191
|
+
## Safety rails
|
|
192
|
+
|
|
193
|
+
- Nothing installs without an explicit `approve`.
|
|
194
|
+
- `approve` never overwrites a folder skillscout didn't install, and never follows symlinks.
|
|
195
|
+
- A skill can't name its way out of the skills folder: a `name:` like `../../x` falls back to the folder's own name, and a path that leads outside its repo is refused. The install name comes from the `SKILL.md` fetched on your machine, not from the index.
|
|
196
|
+
- Every install is pinned to a commit and a content hash.
|
|
197
|
+
- Updates are a diff first, and re-scanned before they replace anything. The test suite includes an upstream
|
|
198
|
+
update that slips in `sudo rm -rf /`, and checks that re-approval refuses it.
|
|
199
|
+
|
|
200
|
+
## Every command
|
|
201
|
+
|
|
202
|
+
| Command | Does |
|
|
203
|
+
|---|---|
|
|
204
|
+
| `skillscout init` | Copy the example profile to `~/.skillscout/profile.toml` |
|
|
205
|
+
| `skillscout discover [--local [--full]] [--notify]` | Score the weekly index against your profile and write the report. `--local` crawls and scans GitHub on your machine instead; `--full` then ignores the caches; `--notify` sends a desktop notification (macOS, or Linux with `notify-send`) |
|
|
206
|
+
| `skillscout index [--out FILE]` | Crawl and scan the ecosystem and write the shared index (what the weekly job runs) |
|
|
207
|
+
| `skillscout list [--all] [-n N]` | Ranked candidates |
|
|
208
|
+
| `skillscout show <id>` | Flags, conflicts and the full SKILL.md |
|
|
209
|
+
| `skillscout approve <id> [--update] [--accept-risk] [--to DIR]` | Install and pin. `--to`, or `dir` under `[install]` in your profile, installs into another agent's skills folder |
|
|
210
|
+
| `skillscout installed` · `skillscout remove <id>` · `skillscout rollback <id>` | Pinned skills · uninstall · undo the last update |
|
|
211
|
+
| `skillscout updates` | Diff pinned skills against upstream |
|
|
212
|
+
| `skillscout init [--about "..."]` | Write the profile; `--about` drafts your keywords from one line |
|
|
213
|
+
| `skillscout history [--days N]` | A local digest of your recent Claude Code sessions, to draft personas from |
|
|
214
|
+
| `skillscout persona add <name> --about "..." [--keywords "a=3,b=2"]` | Add a persona; keywords drafted from the line unless given |
|
|
215
|
+
| `skillscout persona list` | Each persona: keywords, best installed skills, what's worth installing |
|
|
216
|
+
| `skillscout persona build <name> \| --all [--dry-run]` | Write `~/.claude/agents/<name>.md`, or update only its `skills:` list |
|
|
217
|
+
| `skillscout schedule` | Set up weekly discovery: launchd on macOS, a systemd timer on Linux (cron line without systemd), a `schtasks` command on Windows. It prints the one command that turns it on |
|
|
218
|
+
|
|
219
|
+
With the index, `discover` makes no GitHub API calls at all. For `--local` and `index`, set `GITHUB_TOKEN`, or just be logged in with the GitHub CLI (`gh auth login`), for higher API rate limits (5,000 requests an hour instead of 60). Following lists costs one lookup per linked repo: up to 1,500 a run with a token, 40 without; links not yet checked go first, so later runs reach the rest. A token is optional: without it, a rate limit means waiting rather than failing. A weekly run with few upstream changes takes about 25 seconds; the first run takes a few minutes. Scheduled jobs don't see your shell's environment, so add the token to the job if you want it there.
|
|
220
|
+
|
|
221
|
+
## Limits
|
|
222
|
+
|
|
223
|
+
- The scanner catches known patterns. It can't prove a skill is safe, so read `show` before you approve.
|
|
224
|
+
- Relevance is keyword matching against your profile, not semantic search. Tune the weights.
|
|
225
|
+
- The scanner is pattern rules, deliberately: a skill is text written to steer a model, so a model judging it can be steered by it. The rules make you read; they don't decide.
|
|
226
|
+
- Every installed skill's description loads into every agent session. Keep the total to a few dozen.
|
|
227
|
+
- A persona's `skills:` load in full when its agent starts. `max_skills` (default 5) keeps that small.
|
|
228
|
+
|
|
229
|
+
## Development
|
|
230
|
+
|
|
231
|
+
```sh
|
|
232
|
+
python3 -m venv .venv && .venv/bin/pip install -e ".[dev]"
|
|
233
|
+
.venv/bin/python -m pytest -q
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
## License
|
|
237
|
+
|
|
238
|
+
MIT
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/akshit9162/skillscout/main/docs/assets/header.svg" width="760" alt="skillscout: keep your agent's skills current, safely" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<a href="https://akshit9162.github.io/skillscout">Website</a>  · 
|
|
7
|
+
<a href="https://akshit9162.github.io/skillscout/report.html">Report: what's inside 6,726 skills</a>  · 
|
|
8
|
+
<a href="#install">Install</a>  · 
|
|
9
|
+
<a href="#personas">Personas</a>  · 
|
|
10
|
+
<a href="#a-week-with-skillscout">A week with it</a>  · 
|
|
11
|
+
<a href="#how-it-works">How it works</a>  · 
|
|
12
|
+
<a href="#what-gets-flagged">What gets flagged</a>
|
|
13
|
+
</p>
|
|
14
|
+
|
|
15
|
+
<p align="center">
|
|
16
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="MIT licence" /></a>
|
|
17
|
+
<a href="https://github.com/akshit9162/skillscout/actions/workflows/ci.yml"><img src="https://github.com/akshit9162/skillscout/actions/workflows/ci.yml/badge.svg" alt="CI" /></a>
|
|
18
|
+
<img src="https://img.shields.io/badge/python-3.11%2B-blue.svg" alt="Python 3.11+" />
|
|
19
|
+
<img src="https://img.shields.io/badge/dependencies-0-brightgreen.svg" alt="No dependencies" />
|
|
20
|
+
</p>
|
|
21
|
+
|
|
22
|
+
<p align="center">
|
|
23
|
+
<img src="https://raw.githubusercontent.com/akshit9162/skillscout/main/docs/assets/demo.svg" width="760" alt="Terminal demo: init drafts keywords from one line; persona add creates a brand persona; discover scores 23,865 skills with a section for the brand persona; persona build writes its agent; claude --agent brand starts it" />
|
|
24
|
+
</p>
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
claude plugin marketplace add akshit9162/skillscout && claude plugin install skillscout@skillscout
|
|
28
|
+
# or the CLI on its own
|
|
29
|
+
pipx install skillscout-cli
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
AI tooling moves weekly. New skills, plugins and agent workflows land on GitHub every day, the ones you
|
|
33
|
+
installed keep changing upstream, and last month's best practice is already stale. Nobody has time to
|
|
34
|
+
watch hundreds of repos.
|
|
35
|
+
|
|
36
|
+
**skillscout keeps your agent current, for each kind of work you do.** Every week a shared index of every
|
|
37
|
+
public skill it can find (23,865 from 1,092 repos at the last build) is rebuilt. skillscout scores it on your
|
|
38
|
+
machine against what *you* work on, tells you what's new and worth having, and shows you exactly what
|
|
39
|
+
changed in the skills you already use.
|
|
40
|
+
|
|
41
|
+
You probably don't do one kind of work. Coding on Monday, a landing page on Tuesday, investor emails on
|
|
42
|
+
Friday. So skillscout keeps **personas**: one per kind of work, each with its own search and its own Claude
|
|
43
|
+
Code agent, loaded with the best skills for that work and kept up to date as better ones appear.
|
|
44
|
+
|
|
45
|
+
Keeping up fast is only useful if it's safe. A skill is a set of instructions your agent follows
|
|
46
|
+
**with your permissions**, so skillscout scans every file for dangerous patterns, installs nothing without
|
|
47
|
+
your approval, pins each install to an exact commit, and re-scans every update before it can replace anything.
|
|
48
|
+
|
|
49
|
+
In a hand-checked run on 27 Oct 2026 over **6,726 skills in 95 repos**, 198 had at least one high-risk flag,
|
|
50
|
+
mostly `sudo` and `curl | sh` install steps, plus prompt-injection-style text and hidden Unicode.
|
|
51
|
+
The [report](https://akshit9162.github.io/skillscout/report.html) reads every one of the scariest flags: they were defenders.
|
|
52
|
+
|
|
53
|
+
It's a zero-dependency Python CLI, and it also ships as a skill, so your agent can run the whole loop for you
|
|
54
|
+
and still ask before every install.
|
|
55
|
+
|
|
56
|
+
## Personas
|
|
57
|
+
|
|
58
|
+
A persona is one side of your work, in your words. skillscout doesn't ship any: yours might be "builder",
|
|
59
|
+
"brand" and "outreach", someone else's "trading" and "thesis".
|
|
60
|
+
|
|
61
|
+
```text
|
|
62
|
+
You "set up personas for me" (in Claude Code, with the plugin)
|
|
63
|
+
Agent reads your recent sessions on this machine, with your OK (skillscout history)
|
|
64
|
+
→ proposes: builder · brand · outreach, each with the sessions it came from
|
|
65
|
+
You keep brand and builder, rename outreach to launches
|
|
66
|
+
Agent skillscout persona add brand --about "D2C marketing: ad copy, landing pages, Instagram reels"
|
|
67
|
+
→ keywords drafted from terms skills actually use: instagram reels, ad copy, landing pages...
|
|
68
|
+
skillscout discover → a "For your brand work" section in the report
|
|
69
|
+
skillscout persona build brand → ~/.claude/agents/brand.md, skills: copy, landing-page-design, script...
|
|
70
|
+
You claude --agent brand
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
From then on, each weekly report has a section per persona, and `persona build` swaps in a better skill when
|
|
74
|
+
one arrives (after you've read and approved it). `persona build` only ever rewrites the agent's `skills:` list:
|
|
75
|
+
its prompt, tone, tools, model and memory are yours.
|
|
76
|
+
|
|
77
|
+
The CLI works without the agent too:
|
|
78
|
+
|
|
79
|
+
```sh
|
|
80
|
+
skillscout persona add brand --about "D2C marketing: ad copy, landing pages, Instagram reels"
|
|
81
|
+
skillscout persona list # keywords, best installed skills, what's worth installing
|
|
82
|
+
skillscout persona build --all # write or update ~/.claude/agents/<name>.md
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**Your history stays on your machine.** `skillscout history` reads `~/.claude/projects` only when you run it,
|
|
86
|
+
keeps only what you typed (no tool output, no pasted blocks, no links) and sends nothing anywhere. Grouping
|
|
87
|
+
sessions into personas is left to you or the agent in your own session: counting words can't tell short chat
|
|
88
|
+
messages apart reliably, and a wrong persona is worse than none.
|
|
89
|
+
|
|
90
|
+
## A week with skillscout
|
|
91
|
+
|
|
92
|
+
Example session (counts vary week to week):
|
|
93
|
+
|
|
94
|
+
```text
|
|
95
|
+
Monday 10:00 skillscout discover --notify (weekly, via schedule)
|
|
96
|
+
→ "23 recommended for you (4 new this run), 11 relevant but flagged high-risk"
|
|
97
|
+
→ plus a section per persona: "For your brand work", "For your builder work"
|
|
98
|
+
You skillscout show github/awesome-copilot:eval-driven-dev
|
|
99
|
+
→ flags with file:line, the full SKILL.md, overlaps with what you have
|
|
100
|
+
You skillscout approve eval-driven-dev → copied, pinned to its commit
|
|
101
|
+
Later skillscout updates → upstream changed it; here's the diff
|
|
102
|
+
You skillscout approve eval-driven-dev --update → re-scanned, then replaced
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Install
|
|
106
|
+
|
|
107
|
+
### As a Claude Code plugin (the agent drives it)
|
|
108
|
+
|
|
109
|
+
```sh
|
|
110
|
+
claude plugin marketplace add akshit9162/skillscout
|
|
111
|
+
claude plugin install skillscout@skillscout
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Then ask: *"find me skills for my Python and React work"*, or *"set up personas for me"*. The agent installs the CLI, runs the search,
|
|
115
|
+
summarises the report and shows you each skill's flags before asking to install it.
|
|
116
|
+
|
|
117
|
+
### As a CLI
|
|
118
|
+
|
|
119
|
+
```sh
|
|
120
|
+
pipx install skillscout-cli # or: uv tool install skillscout-cli
|
|
121
|
+
skillscout init --about "backend in Python, code review, RL evals, Postgres"
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
`init` writes `~/.skillscout/profile.toml` and drafts `[keywords]` from your line, using only terms that skills
|
|
125
|
+
actually use. Check them, then:
|
|
126
|
+
|
|
127
|
+
```sh
|
|
128
|
+
skillscout discover # score this week's index; writes ~/.skillscout/reports/<date>.md
|
|
129
|
+
skillscout list # ranked; REC = recommended
|
|
130
|
+
skillscout show <id> # every flag plus the full SKILL.md, before you decide
|
|
131
|
+
skillscout approve <id> # copy into ~/.claude/skills and pin the commit
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
`<id>` is `owner/repo:skill-name`. The bare skill name works when it's unique. If one repo has two skills with the same name, the second is `owner/repo:path/to/skill`.
|
|
135
|
+
|
|
136
|
+
## How it works
|
|
137
|
+
|
|
138
|
+
The crawl is the same for everyone, so it runs once a week in this repo's [index workflow](.github/workflows/index.yml) and is published as `index.json.gz`. `skillscout discover` downloads that one file (seconds, no GitHub token, your keywords never leave your machine) and scores it locally. `show` and `approve` fetch the skill and scan it again on your machine, so nothing is installed on the index's word. `discover --local` runs the whole crawl yourself instead.
|
|
139
|
+
|
|
140
|
+
Each published index carries a signed [build attestation](https://docs.github.com/en/actions/security-for-github-actions/using-artifact-attestations): proof that this repo's index workflow built that exact file. Check one with `gh attestation verify ~/.skillscout/index.json.gz --repo akshit9162/skillscout`, or set `verify = true` under `[index]` and `discover` checks every download and refuses one that fails.
|
|
141
|
+
|
|
142
|
+
| Step | What happens |
|
|
143
|
+
|---|---|
|
|
144
|
+
| **Discover** (weekly job, or `--local`) | Runs your GitHub searches (topics like `claude-skills`, `agent-skills`) plus your trusted repos, then follows every repo linked from curated lists (your `lists`, plus any `awesome-*` repo it finds). Drops archived, stale (no push in a year), unpopular and huge repos. |
|
|
145
|
+
| **Clone** | Sparse, shallow clones: only folders that contain a `SKILL.md`, minus media and archives, 16 repos at a time. Repos with no push since the last run aren't fetched again. Repo code is never run. |
|
|
146
|
+
| **Scan** | Static checks on every file in the skill, reported with file and line ([below](#what-gets-flagged)). A skill whose folder (git tree hash) and the scanner's rules are both unchanged keeps its last result instead of being read again. |
|
|
147
|
+
| **Score** (your machine) | 65% relevance to your keywords (phrases match in order, singular or plural), 20% stars, 15% freshness, plus a bonus for trusted repos. |
|
|
148
|
+
| **Conflicts** | Compared against your `~/.claude/skills` and plugin skills: same name, or a description close enough that both would fire on the same prompt. |
|
|
149
|
+
| **Report** | What's new since your last run, recommended skills, and relevant ones that are blocked and why. |
|
|
150
|
+
| **Approve** | You pick one. It's fetched and scanned again on your machine (that scan decides), then copied (symlinks dropped) and pinned in `~/.skillscout/skills.lock.json` with its commit and a content hash. |
|
|
151
|
+
| **Update** | `skillscout updates` diffs each pinned skill against upstream and applies nothing. Taking an update re-runs the scan, builds the new copy beside the old one and swaps them; if any step fails, the old copy and its pin stay. `skillscout rollback <id>` puts back the version an update replaced. |
|
|
152
|
+
|
|
153
|
+
## What gets flagged
|
|
154
|
+
|
|
155
|
+
| Level | Patterns |
|
|
156
|
+
|---|---|
|
|
157
|
+
| **High**, blocks install | Download piped into a shell · `sudo` · broad `rm -rf` · reading SSH keys or the keychain · decode-and-execute · uploading local files · hidden or direction-changing Unicode · "ignore previous instructions" · "don't tell the user" |
|
|
158
|
+
| **Medium** | Reading `.env` or API keys · force pushes · editing shell profiles or Claude settings · skipping permission prompts · hooks · scripts that make network calls · symlinks · binaries |
|
|
159
|
+
| **Low** | Other bundled scripts · no licence |
|
|
160
|
+
|
|
161
|
+
High-risk skills need `--accept-risk`, which the bundled skill tells the agent never to pass on its own.
|
|
162
|
+
|
|
163
|
+
## Safety rails
|
|
164
|
+
|
|
165
|
+
- Nothing installs without an explicit `approve`.
|
|
166
|
+
- `approve` never overwrites a folder skillscout didn't install, and never follows symlinks.
|
|
167
|
+
- A skill can't name its way out of the skills folder: a `name:` like `../../x` falls back to the folder's own name, and a path that leads outside its repo is refused. The install name comes from the `SKILL.md` fetched on your machine, not from the index.
|
|
168
|
+
- Every install is pinned to a commit and a content hash.
|
|
169
|
+
- Updates are a diff first, and re-scanned before they replace anything. The test suite includes an upstream
|
|
170
|
+
update that slips in `sudo rm -rf /`, and checks that re-approval refuses it.
|
|
171
|
+
|
|
172
|
+
## Every command
|
|
173
|
+
|
|
174
|
+
| Command | Does |
|
|
175
|
+
|---|---|
|
|
176
|
+
| `skillscout init` | Copy the example profile to `~/.skillscout/profile.toml` |
|
|
177
|
+
| `skillscout discover [--local [--full]] [--notify]` | Score the weekly index against your profile and write the report. `--local` crawls and scans GitHub on your machine instead; `--full` then ignores the caches; `--notify` sends a desktop notification (macOS, or Linux with `notify-send`) |
|
|
178
|
+
| `skillscout index [--out FILE]` | Crawl and scan the ecosystem and write the shared index (what the weekly job runs) |
|
|
179
|
+
| `skillscout list [--all] [-n N]` | Ranked candidates |
|
|
180
|
+
| `skillscout show <id>` | Flags, conflicts and the full SKILL.md |
|
|
181
|
+
| `skillscout approve <id> [--update] [--accept-risk] [--to DIR]` | Install and pin. `--to`, or `dir` under `[install]` in your profile, installs into another agent's skills folder |
|
|
182
|
+
| `skillscout installed` · `skillscout remove <id>` · `skillscout rollback <id>` | Pinned skills · uninstall · undo the last update |
|
|
183
|
+
| `skillscout updates` | Diff pinned skills against upstream |
|
|
184
|
+
| `skillscout init [--about "..."]` | Write the profile; `--about` drafts your keywords from one line |
|
|
185
|
+
| `skillscout history [--days N]` | A local digest of your recent Claude Code sessions, to draft personas from |
|
|
186
|
+
| `skillscout persona add <name> --about "..." [--keywords "a=3,b=2"]` | Add a persona; keywords drafted from the line unless given |
|
|
187
|
+
| `skillscout persona list` | Each persona: keywords, best installed skills, what's worth installing |
|
|
188
|
+
| `skillscout persona build <name> \| --all [--dry-run]` | Write `~/.claude/agents/<name>.md`, or update only its `skills:` list |
|
|
189
|
+
| `skillscout schedule` | Set up weekly discovery: launchd on macOS, a systemd timer on Linux (cron line without systemd), a `schtasks` command on Windows. It prints the one command that turns it on |
|
|
190
|
+
|
|
191
|
+
With the index, `discover` makes no GitHub API calls at all. For `--local` and `index`, set `GITHUB_TOKEN`, or just be logged in with the GitHub CLI (`gh auth login`), for higher API rate limits (5,000 requests an hour instead of 60). Following lists costs one lookup per linked repo: up to 1,500 a run with a token, 40 without; links not yet checked go first, so later runs reach the rest. A token is optional: without it, a rate limit means waiting rather than failing. A weekly run with few upstream changes takes about 25 seconds; the first run takes a few minutes. Scheduled jobs don't see your shell's environment, so add the token to the job if you want it there.
|
|
192
|
+
|
|
193
|
+
## Limits
|
|
194
|
+
|
|
195
|
+
- The scanner catches known patterns. It can't prove a skill is safe, so read `show` before you approve.
|
|
196
|
+
- Relevance is keyword matching against your profile, not semantic search. Tune the weights.
|
|
197
|
+
- The scanner is pattern rules, deliberately: a skill is text written to steer a model, so a model judging it can be steered by it. The rules make you read; they don't decide.
|
|
198
|
+
- Every installed skill's description loads into every agent session. Keep the total to a few dozen.
|
|
199
|
+
- A persona's `skills:` load in full when its agent starts. `max_skills` (default 5) keeps that small.
|
|
200
|
+
|
|
201
|
+
## Development
|
|
202
|
+
|
|
203
|
+
```sh
|
|
204
|
+
python3 -m venv .venv && .venv/bin/pip install -e ".[dev]"
|
|
205
|
+
.venv/bin/python -m pytest -q
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## License
|
|
209
|
+
|
|
210
|
+
MIT
|
|
@@ -4,14 +4,14 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "skillscout-cli"
|
|
7
|
-
version = "0.
|
|
8
|
-
description = "Keep your agent's skills current: weekly
|
|
7
|
+
version = "0.3.0"
|
|
8
|
+
description = "Keep your agent's skills current for each kind of work you do: weekly index, personas, scans, pinned installs"
|
|
9
9
|
requires-python = ">=3.11"
|
|
10
10
|
readme = "README.md"
|
|
11
11
|
license = "MIT"
|
|
12
12
|
license-files = ["LICENSE"]
|
|
13
13
|
authors = [{ name = "Akshit Gupta" }]
|
|
14
|
-
keywords = ["claude", "claude-code", "agent-skills", "security", "supply-chain", "llm"]
|
|
14
|
+
keywords = ["claude", "claude-code", "agent-skills", "personas", "subagents", "security", "supply-chain", "llm"]
|
|
15
15
|
classifiers = [
|
|
16
16
|
"Development Status :: 4 - Beta",
|
|
17
17
|
"Environment :: Console",
|