codex-skills-registry 0.1.0 → 0.1.1
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 +12 -1
- package/bin/cli.js +46 -5
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -7,11 +7,18 @@ Install Codex skills from `vadimcomanescu/codex-skills`.
|
|
|
7
7
|
Install one or more skills (recommended):
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
npx codex-skills-registry@latest --skill=
|
|
10
|
+
npx codex-skills-registry@latest --skill=quality/code-reviewer --yes
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
List available skills (category/slug):
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npx codex-skills-registry@latest --list
|
|
11
17
|
```
|
|
12
18
|
|
|
13
19
|
### Options
|
|
14
20
|
|
|
21
|
+
- `--list`: List available skills (category/slug).
|
|
15
22
|
- `--skill=<category>/<slug>`: Skill to install. Repeatable.
|
|
16
23
|
- `--yes`: Skip prompts.
|
|
17
24
|
- `--local`: Install into `<repo>/.codex/skills` instead of `$CODEX_HOME/skills`.
|
|
@@ -19,6 +26,10 @@ npx codex-skills-registry@latest --skill=development/webapp-testing --yes
|
|
|
19
26
|
- `--ref=<git-ref>`: Git ref (default: `main`).
|
|
20
27
|
- `--owner=<owner>` / `--repo=<repo>`: Override GitHub repo (default: `vadimcomanescu/codex-skills`).
|
|
21
28
|
|
|
29
|
+
## Updating an installed skill
|
|
30
|
+
|
|
31
|
+
Re-run the same install command. If the destination already exists, `--yes` overwrites it without prompting.
|
|
32
|
+
|
|
22
33
|
## Install location
|
|
23
34
|
|
|
24
35
|
By default this installs into `$CODEX_HOME/skills`. If `CODEX_HOME` is not set, it uses `~/.codex/skills`.
|
package/bin/cli.js
CHANGED
|
@@ -10,6 +10,12 @@ const DEFAULT_OWNER = "vadimcomanescu";
|
|
|
10
10
|
const DEFAULT_REPO = "codex-skills";
|
|
11
11
|
const DEFAULT_REF = "main";
|
|
12
12
|
|
|
13
|
+
process.stdout.on("error", (err) => {
|
|
14
|
+
if (err && err.code === "EPIPE") {
|
|
15
|
+
process.exit(0);
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
|
|
13
19
|
function formatVersion() {
|
|
14
20
|
try {
|
|
15
21
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
@@ -37,6 +43,7 @@ function printHeader() {
|
|
|
37
43
|
function parseArgs(argv) {
|
|
38
44
|
const out = {
|
|
39
45
|
skills: [],
|
|
46
|
+
list: false,
|
|
40
47
|
yes: false,
|
|
41
48
|
local: false,
|
|
42
49
|
dest: null,
|
|
@@ -48,6 +55,7 @@ function parseArgs(argv) {
|
|
|
48
55
|
|
|
49
56
|
for (const raw of argv) {
|
|
50
57
|
if (raw === "--help" || raw === "-h") out.help = true;
|
|
58
|
+
else if (raw === "--list") out.list = true;
|
|
51
59
|
else if (raw === "--yes" || raw === "-y") out.yes = true;
|
|
52
60
|
else if (raw === "--local") out.local = true;
|
|
53
61
|
else if (raw.startsWith("--dest=")) out.dest = raw.slice("--dest=".length);
|
|
@@ -67,8 +75,10 @@ function printHelp() {
|
|
|
67
75
|
"",
|
|
68
76
|
"Usage:",
|
|
69
77
|
" npx codex-skills-registry@latest --skill=<category>/<slug> [--skill=...] --yes",
|
|
78
|
+
" npx codex-skills-registry@latest --list",
|
|
70
79
|
"",
|
|
71
80
|
"Options:",
|
|
81
|
+
" --list List available skills (category/slug).",
|
|
72
82
|
" --skill=<category>/<slug> Skill to install (repeatable).",
|
|
73
83
|
" --yes, -y Skip prompts.",
|
|
74
84
|
" --local Install into <repo>/.codex/skills.",
|
|
@@ -135,6 +145,24 @@ async function listRepoTree(owner, repo, ref) {
|
|
|
135
145
|
return Array.isArray(data.tree) ? data.tree : [];
|
|
136
146
|
}
|
|
137
147
|
|
|
148
|
+
function listSkillsFromTree(tree) {
|
|
149
|
+
const prefixes = ["skills/.curated/", "skills/.experimental/"];
|
|
150
|
+
const skillRefs = new Set();
|
|
151
|
+
|
|
152
|
+
for (const item of tree) {
|
|
153
|
+
if (item.type !== "blob" || typeof item.path !== "string") continue;
|
|
154
|
+
for (const prefix of prefixes) {
|
|
155
|
+
if (!item.path.startsWith(prefix)) continue;
|
|
156
|
+
const rest = item.path.slice(prefix.length);
|
|
157
|
+
const parts = rest.split("/").filter(Boolean);
|
|
158
|
+
if (parts.length < 2) continue;
|
|
159
|
+
skillRefs.add(`${parts[0]}/${parts[1]}`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return Array.from(skillRefs).sort((a, b) => a.localeCompare(b));
|
|
164
|
+
}
|
|
165
|
+
|
|
138
166
|
function findSkillPrefix(tree, skillRef) {
|
|
139
167
|
const curatedPrefix = `skills/.curated/${skillRef}/`;
|
|
140
168
|
const experimentalPrefix = `skills/.experimental/${skillRef}/`;
|
|
@@ -156,10 +184,14 @@ async function installSkill({ owner, repo, ref, tree, skillRef, installRoot, yes
|
|
|
156
184
|
}
|
|
157
185
|
|
|
158
186
|
const destDir = path.join(installRoot, skillRef);
|
|
159
|
-
if (
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
187
|
+
if (fs.existsSync(destDir)) {
|
|
188
|
+
if (yes) {
|
|
189
|
+
fs.rmSync(destDir, { recursive: true, force: true });
|
|
190
|
+
} else {
|
|
191
|
+
const ok = await confirm(`⚠️ ${destDir} already exists. Overwrite? (y/N) `);
|
|
192
|
+
if (!ok) return { installed: false };
|
|
193
|
+
fs.rmSync(destDir, { recursive: true, force: true });
|
|
194
|
+
}
|
|
163
195
|
}
|
|
164
196
|
|
|
165
197
|
fs.mkdirSync(destDir, { recursive: true });
|
|
@@ -199,12 +231,21 @@ async function main() {
|
|
|
199
231
|
return;
|
|
200
232
|
}
|
|
201
233
|
|
|
202
|
-
if (args.skills.length === 0) {
|
|
234
|
+
if (!args.list && args.skills.length === 0) {
|
|
203
235
|
printHelp();
|
|
204
236
|
process.exitCode = 1;
|
|
205
237
|
return;
|
|
206
238
|
}
|
|
207
239
|
|
|
240
|
+
if (args.list) {
|
|
241
|
+
const tree = await listRepoTree(args.owner, args.repo, args.ref);
|
|
242
|
+
const skills = listSkillsFromTree(tree);
|
|
243
|
+
for (const skillRef of skills) {
|
|
244
|
+
process.stdout.write(`${skillRef}\n`);
|
|
245
|
+
}
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
|
|
208
249
|
printHeader();
|
|
209
250
|
|
|
210
251
|
const installRoot = getInstallRoot({ dest: args.dest, local: args.local });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codex-skills-registry",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Install Codex skills from GitHub into your local Codex setup.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
@@ -8,11 +8,11 @@
|
|
|
8
8
|
"homepage": "https://skillregistry.dev",
|
|
9
9
|
"repository": {
|
|
10
10
|
"type": "git",
|
|
11
|
-
"url": "git+https://github.com/vadimcomanescu/codex-
|
|
11
|
+
"url": "git+https://github.com/vadimcomanescu/codex-skills-registry.git",
|
|
12
12
|
"directory": "packages/codex-skills-registry"
|
|
13
13
|
},
|
|
14
14
|
"bugs": {
|
|
15
|
-
"url": "https://github.com/vadimcomanescu/codex-
|
|
15
|
+
"url": "https://github.com/vadimcomanescu/codex-skills-registry/issues"
|
|
16
16
|
},
|
|
17
17
|
"keywords": ["codex", "openai", "cli", "skills", "installer"],
|
|
18
18
|
"funding": {
|