skillbin 0.1.0 → 0.1.2
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/bin/skillbin.js +59 -18
- package/package.json +1 -1
package/bin/skillbin.js
CHANGED
|
@@ -88,20 +88,24 @@ async function install(ref, opts) {
|
|
|
88
88
|
throw new Error('Skill has no files');
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
let
|
|
92
|
-
if (
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
91
|
+
let destDir;
|
|
92
|
+
if (opts.dir) {
|
|
93
|
+
destDir = path.resolve(opts.dir);
|
|
94
|
+
} else {
|
|
95
|
+
let scope = opts.scope;
|
|
96
|
+
if (getFormatConfig(format).hasScope && !scope) {
|
|
97
|
+
if (process.stdin.isTTY) {
|
|
98
|
+
console.error(`\nInstall "${skillName}" (${format}) to:`);
|
|
99
|
+
console.error(' 1) Global (~/.claude/skills/)');
|
|
100
|
+
console.error(' 2) Project (.claude/skills/ in current directory)\n');
|
|
101
|
+
const choice = await promptUser('Choice (1 or 2, default 1): ');
|
|
102
|
+
scope = choice === '2' ? 'project' : 'global';
|
|
103
|
+
} else {
|
|
104
|
+
scope = 'global';
|
|
105
|
+
}
|
|
101
106
|
}
|
|
107
|
+
destDir = resolveInstallDir(skillName, scope, format);
|
|
102
108
|
}
|
|
103
|
-
|
|
104
|
-
const destDir = resolveInstallDir(skillName, scope, format);
|
|
105
109
|
fs.mkdirSync(destDir, { recursive: true });
|
|
106
110
|
|
|
107
111
|
for (const file of files) {
|
|
@@ -188,10 +192,44 @@ async function upload(filePath, opts) {
|
|
|
188
192
|
if (fs.existsSync(cwdSkill)) {
|
|
189
193
|
skills.push({ name: path.basename(process.cwd()), dir: process.cwd(), format: 'claude' });
|
|
190
194
|
} else {
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
+
const discovered = discoverSkills();
|
|
196
|
+
if (discovered.length === 0) {
|
|
197
|
+
console.error('No skills found. Supported locations:');
|
|
198
|
+
console.error(' Claude: .claude/skills/*/SKILL.md');
|
|
199
|
+
console.error(' Cursor: .cursor/rules/*.mdc');
|
|
200
|
+
console.error(' Windsurf: .windsurf/rules/*.md');
|
|
201
|
+
console.error(' Copilot: .github/instructions/*.instructions.md');
|
|
202
|
+
console.error(' Codex: AGENTS.md');
|
|
203
|
+
console.error(' Cline: .clinerules/*.md');
|
|
204
|
+
process.exit(1);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
console.error(`\nFound ${discovered.length} skill(s):\n`);
|
|
208
|
+
discovered.forEach((s, i) => {
|
|
209
|
+
console.error(` ${i + 1}) ${s.name} [${s.format}]`);
|
|
210
|
+
});
|
|
211
|
+
console.error('');
|
|
212
|
+
|
|
213
|
+
if (!process.stdin.isTTY) {
|
|
214
|
+
console.error('Error: no terminal available. Pass a path or use --all.');
|
|
215
|
+
process.exit(1);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
const selection = await promptUser(`Upload which? (1-${discovered.length}, space-separated, or "all"): `);
|
|
219
|
+
let indices;
|
|
220
|
+
if (selection.trim() === 'all') {
|
|
221
|
+
indices = discovered.map((_, i) => i);
|
|
222
|
+
} else {
|
|
223
|
+
indices = selection.trim().split(/\s+/).map(n => parseInt(n, 10) - 1)
|
|
224
|
+
.filter(i => i >= 0 && i < discovered.length);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
if (indices.length === 0) {
|
|
228
|
+
console.error('No skills selected.');
|
|
229
|
+
process.exit(0);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
skills = indices.map(i => discovered[i]);
|
|
195
233
|
}
|
|
196
234
|
}
|
|
197
235
|
|
|
@@ -367,6 +405,7 @@ Usage:
|
|
|
367
405
|
Options:
|
|
368
406
|
--global Install to ~/.claude/skills/ (default for claude format)
|
|
369
407
|
--project Install to .claude/skills/ in current directory
|
|
408
|
+
--dir=<path> Install to a custom directory (overrides --global/--project)
|
|
370
409
|
--token=<token> API token for auth
|
|
371
410
|
--all Upload all local skills (all formats)
|
|
372
411
|
--help, -h Show this help
|
|
@@ -382,6 +421,7 @@ Supported formats:
|
|
|
382
421
|
Examples:
|
|
383
422
|
npx skillbin https://skillb.in/s/abc123
|
|
384
423
|
npx skillbin install abc123 --project
|
|
424
|
+
npx skillbin install abc123 --dir=./my-skills/
|
|
385
425
|
npx skillbin upload ./my-skill/
|
|
386
426
|
npx skillbin upload .cursor/rules/my-rule.mdc
|
|
387
427
|
npx skillbin upload --all --token=abc123
|
|
@@ -401,6 +441,7 @@ async function main() {
|
|
|
401
441
|
|
|
402
442
|
const token = flags.token || process.env.SKILLBIN_TOKEN || '';
|
|
403
443
|
const scope = flags.project ? 'project' : flags.global ? 'global' : '';
|
|
444
|
+
const dir = flags.dir || '';
|
|
404
445
|
|
|
405
446
|
const command = args[0];
|
|
406
447
|
|
|
@@ -415,7 +456,7 @@ async function main() {
|
|
|
415
456
|
console.error('Usage: skillbin install <url-or-id>');
|
|
416
457
|
process.exit(1);
|
|
417
458
|
}
|
|
418
|
-
await install(args[1], { token, scope });
|
|
459
|
+
await install(args[1], { token, scope, dir });
|
|
419
460
|
} else if (command === 'upload') {
|
|
420
461
|
await upload(args[1], { token, all: flags.all });
|
|
421
462
|
} else if (command === 'info') {
|
|
@@ -428,7 +469,7 @@ async function main() {
|
|
|
428
469
|
} else if (command === 'help') {
|
|
429
470
|
printHelp();
|
|
430
471
|
} else {
|
|
431
|
-
await install(command, { token, scope });
|
|
472
|
+
await install(command, { token, scope, dir });
|
|
432
473
|
}
|
|
433
474
|
} catch (err) {
|
|
434
475
|
console.error(`Error: ${err.message}`);
|