sharp-skills 1.0.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/bin/cli.js +93 -0
- package/package.json +22 -0
package/bin/cli.js
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const https = require('https');
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
|
|
7
|
+
const BASE_URL = 'https://raw.githubusercontent.com/sharp-skills/skills/main/skills';
|
|
8
|
+
const API_URL = 'https://api.github.com/repos/sharp-skills/skills/contents/skills';
|
|
9
|
+
|
|
10
|
+
const TOOLS = {
|
|
11
|
+
'claude': { dir: '.claude/skills', label: 'Claude Code' },
|
|
12
|
+
'codex': { dir: '.codex/skills', label: 'OpenAI Codex' },
|
|
13
|
+
'gemini': { dir: '.gemini/skills', label: 'Gemini CLI' },
|
|
14
|
+
'cursor': { dir: '.cursor/skills', label: 'Cursor' },
|
|
15
|
+
'windsurf': { dir: '.windsurf/skills', label: 'Windsurf' },
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
function detectTool() {
|
|
19
|
+
for (const [key, cfg] of Object.entries(TOOLS)) {
|
|
20
|
+
if (fs.existsSync(path.join(process.cwd(), cfg.dir.split('/')[0]))) return key;
|
|
21
|
+
}
|
|
22
|
+
return 'claude';
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function fetchUrl(url) {
|
|
26
|
+
return new Promise((resolve, reject) => {
|
|
27
|
+
const opts = new URL(url);
|
|
28
|
+
https.get({ hostname: opts.hostname, path: opts.pathname + opts.search, headers: { 'User-Agent': 'sharp-skills-cli/1.0.0' } }, (res) => {
|
|
29
|
+
if (res.statusCode === 301 || res.statusCode === 302) return fetchUrl(res.headers.location).then(resolve).catch(reject);
|
|
30
|
+
let data = '';
|
|
31
|
+
res.on('data', chunk => data += chunk);
|
|
32
|
+
res.on('end', () => resolve({ status: res.statusCode, body: data }));
|
|
33
|
+
}).on('error', reject);
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async function install(skillName, toolArg) {
|
|
38
|
+
const tool = toolArg || detectTool();
|
|
39
|
+
const cfg = TOOLS[tool];
|
|
40
|
+
if (!cfg) { console.error('Unknown tool: ' + tool + '. Use: claude|codex|gemini|cursor|windsurf'); process.exit(1); }
|
|
41
|
+
console.log('Installing: ' + skillName + ' -> ' + cfg.label);
|
|
42
|
+
const res = await fetchUrl(BASE_URL + '/' + skillName + '/SKILL.md');
|
|
43
|
+
if (res.status === 404) { console.error('Skill "' + skillName + '" not found.\nBrowse: https://github.com/sharp-skills/skills'); process.exit(1); }
|
|
44
|
+
if (res.status !== 200) { console.error('HTTP ' + res.status); process.exit(1); }
|
|
45
|
+
const destDir = path.join(process.cwd(), cfg.dir);
|
|
46
|
+
fs.mkdirSync(destDir, { recursive: true });
|
|
47
|
+
const destFile = path.join(destDir, skillName + '.md');
|
|
48
|
+
fs.writeFileSync(destFile, res.body, 'utf8');
|
|
49
|
+
console.log('Installed to: ' + destFile);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async function listSkills() {
|
|
53
|
+
console.log('Fetching skills...\n');
|
|
54
|
+
const res = await fetchUrl(API_URL);
|
|
55
|
+
if (res.status !== 200) { console.error('Failed to fetch list'); process.exit(1); }
|
|
56
|
+
const skills = JSON.parse(res.body);
|
|
57
|
+
skills.forEach(s => console.log(' - ' + s.name));
|
|
58
|
+
console.log('\nTotal: ' + skills.length + ' skills');
|
|
59
|
+
console.log('Install: npx sharp-skills install <skill-name>');
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async function main() {
|
|
63
|
+
const [,, cmd, ...args] = process.argv;
|
|
64
|
+
if (cmd === 'install') {
|
|
65
|
+
const name = args[0];
|
|
66
|
+
if (!name) { console.error('Usage: npx sharp-skills install <skill> [--tool=claude|cursor|gemini|codex|windsurf]'); process.exit(1); }
|
|
67
|
+
const toolFlag = (args.find(a => a.startsWith('--tool=')) || '').split('=')[1] || null;
|
|
68
|
+
await install(name, toolFlag);
|
|
69
|
+
} else if (cmd === 'list') {
|
|
70
|
+
await listSkills();
|
|
71
|
+
} else {
|
|
72
|
+
console.log([
|
|
73
|
+
'',
|
|
74
|
+
' SharpSkills CLI v1.0',
|
|
75
|
+
'',
|
|
76
|
+
' Commands:',
|
|
77
|
+
' npx sharp-skills install <skill> Auto-detects your tool',
|
|
78
|
+
' npx sharp-skills install <skill> --tool=cursor',
|
|
79
|
+
' npx sharp-skills list Browse all skills',
|
|
80
|
+
'',
|
|
81
|
+
' Examples:',
|
|
82
|
+
' npx sharp-skills install stripe',
|
|
83
|
+
' npx sharp-skills install docker --tool=cursor',
|
|
84
|
+
' npx sharp-skills install openai --tool=gemini',
|
|
85
|
+
'',
|
|
86
|
+
' Supported tools: claude | codex | gemini | cursor | windsurf',
|
|
87
|
+
' Repo: https://github.com/sharp-skills/skills',
|
|
88
|
+
'',
|
|
89
|
+
].join('\n'));
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
main().catch(err => { console.error('Error:', err.message); process.exit(1); });
|
package/package.json
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "sharp-skills",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Install AI agent skills (SKILL.md) for Claude Code, Cursor, Gemini CLI, Codex",
|
|
5
|
+
"bin": {
|
|
6
|
+
"sharp-skills": "./bin/cli.js"
|
|
7
|
+
},
|
|
8
|
+
"scripts": {
|
|
9
|
+
"test": "node bin/cli.js list"
|
|
10
|
+
},
|
|
11
|
+
"keywords": ["ai", "agent", "skill", "claude-code", "cursor", "gemini", "llm", "skill-md"],
|
|
12
|
+
"author": "sharp-skills",
|
|
13
|
+
"license": "Apache-2.0",
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "https://github.com/sharp-skills/skills"
|
|
17
|
+
},
|
|
18
|
+
"homepage": "https://github.com/sharp-skills/skills",
|
|
19
|
+
"engines": {
|
|
20
|
+
"node": ">=18"
|
|
21
|
+
}
|
|
22
|
+
}
|