proskills-cli 0.1.0 → 0.2.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 CHANGED
@@ -1,83 +1,99 @@
1
- # proskills-cli
2
-
3
- Install [ProSkills](https://proskills.dev) agent skills in one command, and scan any `SKILL.md` folder in CI.
4
-
5
- Node 18 or newer. One dependency (`jszip`).
6
-
7
- ## Use it
8
-
9
- No install needed:
10
-
11
- ```sh
12
- npx proskills-cli list # every skill, price and scan score
13
- npx proskills-cli add humanizer # install a free skill into this project
14
- npx proskills-cli add grill-me hook-lab # several at once
15
- npx proskills-cli scan # score the skills already in this repo
16
- ```
17
-
18
- Or install it: `npm i -g proskills`.
19
-
20
- ### `proskills list [--collection <slug>]`
21
-
22
- Prints a table of skills with price (or `Free`) and scan score.
23
-
24
- ### `proskills add <skill-id...>`
25
-
26
- | Flag | Meaning |
27
- |---|---|
28
- | `--agent claude\|cursor\|codex\|gemini\|all` | Which agent to install for. Default: `.claude/` found, then Claude Code; else `.agents/` found, then `.agents/skills`; else Claude Code. |
29
- | `--global` | Install for every project (your home folder) instead of this one. |
30
- | `--order <id>` | Order id from your receipt (`cs_live_...`). Also read from env `PROSKILLS_ORDER`. Required for paid skills. |
31
- | `--dir <path>` | Use this folder instead of the current one (instead of your home folder with `--global`). |
32
- | `--force` | Replace a skill folder that already exists. Without it, nothing is overwritten. |
33
- | `--answers file.json` | Send your saved answers so `profile.md` is filled in. Optional. |
34
-
35
- Paid skill without an order id: the command stops and prints the link to buy it (`https://proskills.dev/library/<collection>`).
36
-
37
- ### `proskills scan [paths...] [--min 80] [--json]`
38
-
39
- Scores skill folders against the Agent Skills spec, token budget, clarity and security. A path is a skill folder (has `SKILL.md`) or a folder of skill folders. Default: `.claude/skills` and `.agents/skills`. Exits `1` when any skill is grade F (any critical finding) or scores under `--min`, `2` on usage errors. Scanning runs locally; nothing is uploaded.
40
-
41
- ### Everywhere
42
-
43
- `--base <url>` (or env `PROSKILLS_URL`) points at another host. Default `https://proskills.dev`. `--help`, `--version`.
44
-
45
- ## CI
46
-
47
- Block a pull request that adds a weak or unsafe skill:
48
-
49
- ```yaml
50
- name: skills
51
- on: [pull_request]
52
- jobs:
53
- scan:
54
- runs-on: ubuntu-latest
55
- steps:
56
- - uses: actions/checkout@v4
57
- - uses: actions/setup-node@v4
58
- with: { node-version: 20 }
59
- - run: npx proskills-cli scan --min 80
60
- ```
61
-
62
- Add paths to scan something else: `npx proskills-cli scan ./skills --min 90 --json`.
63
-
64
- ## What it writes, and where
65
-
66
- Each skill becomes one folder, with `SKILL.md`, `profile.md` and any files the skill reads:
67
-
68
- | Agent | This project | With `--global` |
69
- |---|---|---|
70
- | Claude Code | `.claude/skills/<id>/` | `~/.claude/skills/<id>/` |
71
- | Cursor | `.agents/skills/<id>/` | `~/.cursor/skills/<id>/` |
72
- | Codex | `.agents/skills/<id>/` | `~/.agents/skills/<id>/` |
73
- | Gemini CLI | `.agents/skills/<id>/` | `~/.gemini/skills/<id>/` |
74
-
75
- It writes only inside that skills folder. Archive entries with `..`, absolute paths or drive letters are rejected before anything is written. Restart your agent afterwards.
76
-
77
- ## Privacy
78
-
79
- `list` and `add` send only the skill ids you ask for, plus the order id if you give one. Your saved answers are not sent unless you pass `--answers file.json`. No telemetry, no accounts, no other network calls. `scan` makes none at all.
80
-
81
- ## License
82
-
83
- MIT
1
+ # proskills-cli
2
+
3
+ Install [ProSkills](https://proskills.dev) agent skills in one command, and scan any `SKILL.md` folder in CI.
4
+
5
+ Node 18 or newer. One dependency (`jszip`).
6
+
7
+ ## Use it
8
+
9
+ No install needed:
10
+
11
+ ```sh
12
+ npx proskills-cli list # every skill, price and scan score
13
+ npx proskills-cli add humanizer # install a free skill into this project
14
+ npx proskills-cli add grill-me hook-lab # several at once
15
+ npx proskills-cli scan # score the skills already in this repo
16
+ ```
17
+
18
+ Or install it: `npm i -g proskills`.
19
+
20
+ ### `proskills list [--collection <slug>]`
21
+
22
+ Prints a table of skills with price (or `Free`) and scan score.
23
+
24
+ ### `proskills add <skill-id...>`
25
+
26
+ | Flag | Meaning |
27
+ |---|---|
28
+ | `--agent claude\|cursor\|codex\|gemini\|all` | Which agent to install for. Default: `.claude/` found, then Claude Code; else `.agents/` found, then `.agents/skills`; else Claude Code. |
29
+ | `--global` | Install for every project (your home folder) instead of this one. |
30
+ | `--order <id>` | Order id from your receipt (`cs_live_...`). Also read from env `PROSKILLS_ORDER`. Required for paid skills. |
31
+ | `--dir <path>` | Use this folder instead of the current one (instead of your home folder with `--global`). |
32
+ | `--force` | Replace a skill folder that already exists. Without it, nothing is overwritten. |
33
+ | `--answers file.json` | Send your saved answers so `profile.md` is filled in. Optional. |
34
+
35
+ Paid skill without an order id: the command stops and prints the link to buy it (`https://proskills.dev/library/<collection>`).
36
+
37
+ ### `proskills scan [paths...] [--min 80] [--json] [--badge]`
38
+
39
+ Scores skill folders against the Agent Skills spec, token budget, clarity and security. A path is a skill folder (has `SKILL.md`) or a folder of skill folders. Default: `.claude/skills` and `.agents/skills`. Exits `1` when any skill is grade F (any critical finding) or scores under `--min`, `2` on usage errors. `--badge` prints a README badge snippet after the scan, using the lowest score across the scanned skills (with `--json` it is a `badge` field instead). Scanning runs locally; nothing is uploaded.
40
+
41
+ ### Everywhere
42
+
43
+ `--base <url>` (or env `PROSKILLS_URL`) points at another host. Default `https://proskills.dev`. `--help`, `--version`.
44
+
45
+ ## CI
46
+
47
+ Block a pull request that adds a weak or unsafe skill:
48
+
49
+ ```yaml
50
+ name: skills
51
+ on: [pull_request]
52
+ jobs:
53
+ scan:
54
+ runs-on: ubuntu-latest
55
+ steps:
56
+ - uses: actions/checkout@v4
57
+ - uses: actions/setup-node@v4
58
+ with: { node-version: 20 }
59
+ - run: npx proskills-cli scan --min 80
60
+ ```
61
+
62
+ Add paths to scan something else: `npx proskills-cli scan ./skills --min 90 --json`.
63
+
64
+ Or use the GitHub Action from the [public repo](https://github.com/yungprimer/proskills), which also prints the badge in the job summary:
65
+
66
+ ```yaml
67
+ - uses: yungprimer/proskills@v1
68
+ with:
69
+ min: 80
70
+ ```
71
+
72
+ ## Badge
73
+
74
+ `npx proskills-cli scan --badge` prints this for your README (the number is your lowest skill score):
75
+
76
+ ```md
77
+ [![Scanned by ProSkills](https://proskills.dev/badge?score=92)](https://proskills.dev/scan)
78
+ ```
79
+
80
+ ## What it writes, and where
81
+
82
+ Each skill becomes one folder, with `SKILL.md`, `profile.md` and any files the skill reads:
83
+
84
+ | Agent | This project | With `--global` |
85
+ |---|---|---|
86
+ | Claude Code | `.claude/skills/<id>/` | `~/.claude/skills/<id>/` |
87
+ | Cursor | `.agents/skills/<id>/` | `~/.cursor/skills/<id>/` |
88
+ | Codex | `.agents/skills/<id>/` | `~/.agents/skills/<id>/` |
89
+ | Gemini CLI | `.agents/skills/<id>/` | `~/.gemini/skills/<id>/` |
90
+
91
+ It writes only inside that skills folder. Archive entries with `..`, absolute paths or drive letters are rejected before anything is written. Restart your agent afterwards.
92
+
93
+ ## Privacy
94
+
95
+ `list` and `add` send only the skill ids you ask for, plus the order id if you give one. Your saved answers are not sent unless you pass `--answers file.json`. No telemetry, no accounts, no other network calls. `scan` makes none at all.
96
+
97
+ ## License
98
+
99
+ MIT
package/dist/cli.js CHANGED
@@ -5,27 +5,29 @@ import { parseArgs } from "node:util";
5
5
  import { CliError, fetchCatalog } from "./api.js";
6
6
  import { install } from "./install.js";
7
7
  import { pickAgents, resolveTargets } from "./paths.js";
8
- import { DEFAULT_SCAN_DIRS, isFailing, scanDirs } from "./scancmd.js";
8
+ import { DEFAULT_SCAN_DIRS, badgeMarkdown, isFailing, scanDirs } from "./scancmd.js";
9
9
  export const DEFAULT_BASE = "https://proskills.dev";
10
- export const HELP = `proskills - install ProSkills agent skills and scan any skill folder
11
-
12
- Usage
13
- proskills list [--collection <slug>]
14
- proskills add <skill-id...> [--agent claude|cursor|codex|gemini|all] [--global]
15
- [--order <id>] [--dir <path>] [--force] [--answers file.json]
16
- proskills scan [paths...] [--min 80] [--json]
17
-
18
- Options
19
- --base <url> Another host (default ${DEFAULT_BASE}, or env PROSKILLS_URL)
20
- --order <id> Order id from your receipt (or env PROSKILLS_ORDER)
21
- --dir <path> Base folder instead of the current one (home folder with --global)
22
- --help Show this help
23
- --version Show the version
24
-
25
- Examples
26
- npx proskills-cli add humanizer
27
- npx proskills-cli add grill-me --agent all --global
28
- npx proskills-cli scan --min 80
10
+ export const HELP = `proskills - install ProSkills agent skills and scan any skill folder
11
+
12
+ Usage
13
+ proskills list [--collection <slug>]
14
+ proskills add <skill-id...> [--agent claude|cursor|codex|gemini|all] [--global]
15
+ [--order <id>] [--dir <path>] [--force] [--answers file.json]
16
+ proskills scan [paths...] [--min 80] [--json] [--badge]
17
+
18
+ Options
19
+ --base <url> Another host (default ${DEFAULT_BASE}, or env PROSKILLS_URL)
20
+ --order <id> Order id from your receipt (or env PROSKILLS_ORDER)
21
+ --dir <path> Base folder instead of the current one (home folder with --global)
22
+ --badge After a scan, print a README badge snippet using the lowest score
23
+ across the scanned skills (with --json: a "badge" field)
24
+ --help Show this help
25
+ --version Show the version
26
+
27
+ Examples
28
+ npx proskills-cli add humanizer
29
+ npx proskills-cli add grill-me --agent all --global
30
+ npx proskills-cli scan --min 80
29
31
  `;
30
32
  const OPTIONS = {
31
33
  help: { type: "boolean", short: "h" },
@@ -40,6 +42,7 @@ const OPTIONS = {
40
42
  collection: { type: "string" },
41
43
  min: { type: "string" },
42
44
  json: { type: "boolean" },
45
+ badge: { type: "boolean" },
43
46
  };
44
47
  export function parseCli(argv) {
45
48
  const { values, positionals } = parseArgs({ args: argv, options: OPTIONS, allowPositionals: true, strict: true });
@@ -138,7 +141,7 @@ export async function run(argv, io) {
138
141
  throw new CliError(explicit ? "No skill folders (containing SKILL.md) found in the given paths." : `No skills found in ${DEFAULT_SCAN_DIRS.join(" or ")}. Pass a path: proskills scan ./my-skill`, 2);
139
142
  const failed = results.filter((r) => isFailing(r, min));
140
143
  if (values.json) {
141
- io.out(JSON.stringify({ min, ok: failed.length === 0, skills: results.map((r) => ({ dir: r.dir.replace(/\\/g, "/"), failed: isFailing(r, min), ...r.report })) }, null, 2));
144
+ io.out(JSON.stringify({ min, ok: failed.length === 0, ...(values.badge ? { badge: badgeMarkdown(results.map((r) => r.report.score)) } : {}), skills: results.map((r) => ({ dir: r.dir.replace(/\\/g, "/"), failed: isFailing(r, min), ...r.report })) }, null, 2));
142
145
  }
143
146
  else {
144
147
  for (const { dir, report: r } of results) {
@@ -147,6 +150,8 @@ export async function run(argv, io) {
147
150
  io.out(` ${f.severity.padEnd(8)} ${f.rule.padEnd(24)} ${f.file ?? ""}${f.line ? ":" + f.line : ""} ${f.message}`);
148
151
  }
149
152
  io.out(`\n${results.length} skills scanned, ${failed.length} below the gate (min ${min}, grade F always fails).`);
153
+ if (values.badge)
154
+ io.out(`\nREADME badge (lowest score: ${Math.min(...results.map((r) => r.report.score))}):\n${badgeMarkdown(results.map((r) => r.report.score))}`);
150
155
  }
151
156
  return failed.length ? 1 : 0;
152
157
  }
package/dist/scancmd.js CHANGED
@@ -48,3 +48,8 @@ export function scanDirs(roots, cwd) {
48
48
  export function isFailing(r, min) {
49
49
  return r.report.grade === "F" || r.report.score < min;
50
50
  }
51
+ /** README badge for a scan. Uses the lowest score, so one weak skill cannot hide behind a strong one. */
52
+ export function badgeMarkdown(scores) {
53
+ const score = Math.max(0, Math.min(100, Math.round(Math.min(...scores))));
54
+ return `[![Scanned by ProSkills](https://proskills.dev/badge?score=${score})](https://proskills.dev/scan)`;
55
+ }
package/package.json CHANGED
@@ -1,49 +1,49 @@
1
- {
2
- "name": "proskills-cli",
3
- "version": "0.1.0",
4
- "description": "Install ProSkills agent skills in one command and scan any SKILL.md folder in CI.",
5
- "keywords": [
6
- "agent-skills",
7
- "skill.md",
8
- "claude-code",
9
- "cursor",
10
- "codex",
11
- "gemini-cli",
12
- "cli"
13
- ],
14
- "homepage": "https://proskills.dev",
15
- "repository": {
16
- "type": "git",
17
- "url": "git+https://github.com/yungprimer/proskills.git",
18
- "directory": "cli"
19
- },
20
- "bugs": {
21
- "url": "https://github.com/yungprimer/proskills/issues"
22
- },
23
- "author": "ProSkills (https://proskills.dev)",
24
- "license": "MIT",
25
- "type": "module",
26
- "bin": {
27
- "proskills": "dist/index.js"
28
- },
29
- "files": [
30
- "dist",
31
- "README.md"
32
- ],
33
- "engines": {
34
- "node": ">=18"
35
- },
36
- "scripts": {
37
- "prebuild": "node scripts/copy-scan.mjs",
38
- "build": "tsc -p tsconfig.json",
39
- "test": "node --test test/cli.test.mjs",
40
- "prepublishOnly": "npm run build && npm test"
41
- },
42
- "dependencies": {
43
- "jszip": "^3.10.1"
44
- },
45
- "devDependencies": {
46
- "@types/node": "^20",
47
- "typescript": "^5"
48
- }
49
- }
1
+ {
2
+ "name": "proskills-cli",
3
+ "version": "0.2.0",
4
+ "description": "Install ProSkills agent skills in one command and scan any SKILL.md folder in CI.",
5
+ "keywords": [
6
+ "agent-skills",
7
+ "skill.md",
8
+ "claude-code",
9
+ "cursor",
10
+ "codex",
11
+ "gemini-cli",
12
+ "cli"
13
+ ],
14
+ "homepage": "https://proskills.dev",
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "git+https://github.com/yungprimer/proskills.git",
18
+ "directory": "cli"
19
+ },
20
+ "bugs": {
21
+ "url": "https://github.com/yungprimer/proskills/issues"
22
+ },
23
+ "author": "ProSkills (https://proskills.dev)",
24
+ "license": "MIT",
25
+ "type": "module",
26
+ "bin": {
27
+ "proskills": "dist/index.js"
28
+ },
29
+ "files": [
30
+ "dist",
31
+ "README.md"
32
+ ],
33
+ "engines": {
34
+ "node": ">=18"
35
+ },
36
+ "scripts": {
37
+ "prebuild": "node scripts/copy-scan.mjs",
38
+ "build": "tsc -p tsconfig.json",
39
+ "test": "node --test test/cli.test.mjs",
40
+ "prepublishOnly": "npm run build && npm test"
41
+ },
42
+ "dependencies": {
43
+ "jszip": "^3.10.1"
44
+ },
45
+ "devDependencies": {
46
+ "@types/node": "^20",
47
+ "typescript": "^5"
48
+ }
49
+ }