@divyanshgoel/add-skill 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/index.js +79 -0
- package/package.json +23 -0
package/index.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const https = require('https');
|
|
5
|
+
const AdmZip = require('adm-zip');
|
|
6
|
+
|
|
7
|
+
const skillName = process.argv[2];
|
|
8
|
+
|
|
9
|
+
if (!skillName) {
|
|
10
|
+
console.error("ā Error: Please provide a skill name!");
|
|
11
|
+
console.error("š Example: npx @divyanshgoel/add-skill chief-of-staff");
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
console.log(`⨠Fetching skill bundle: ${skillName}...`);
|
|
16
|
+
|
|
17
|
+
// Use the API route that streams the zip file dynamically
|
|
18
|
+
const API_URL = `https://skills-anthropic.vercel.app/api/download/${skillName}`;
|
|
19
|
+
|
|
20
|
+
// Core Logic Strategy: Check for existing .claude folder
|
|
21
|
+
const currentDir = process.cwd();
|
|
22
|
+
const hasClaudeFolder = fs.existsSync(path.join(currentDir, '.claude'));
|
|
23
|
+
|
|
24
|
+
// If .claude exists, put skills inside .claude/skills. Otherwise just put it in /skills.
|
|
25
|
+
const targetBaseDir = hasClaudeFolder
|
|
26
|
+
? path.join(currentDir, '.claude', 'skills')
|
|
27
|
+
: path.join(currentDir, 'skills');
|
|
28
|
+
|
|
29
|
+
if (!fs.existsSync(targetBaseDir)) {
|
|
30
|
+
fs.mkdirSync(targetBaseDir, { recursive: true });
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Ensure the specific skill directory name exists
|
|
34
|
+
const targetDir = path.join(targetBaseDir, skillName);
|
|
35
|
+
|
|
36
|
+
if (!fs.existsSync(targetDir)) {
|
|
37
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const tempZipPath = path.join(currentDir, `${skillName}-temp.zip`);
|
|
41
|
+
|
|
42
|
+
const request = https.get(API_URL, (response) => {
|
|
43
|
+
if (response.statusCode === 404) {
|
|
44
|
+
console.error(`ā Skill '${skillName}' not found. Please verify the exact name on the directory.`);
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (response.statusCode !== 200) {
|
|
49
|
+
console.error(`ā Failed to download skill. Server responded with status: ${response.statusCode}`);
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const fileStream = fs.createWriteStream(tempZipPath);
|
|
54
|
+
response.pipe(fileStream);
|
|
55
|
+
|
|
56
|
+
fileStream.on('finish', () => {
|
|
57
|
+
fileStream.close();
|
|
58
|
+
|
|
59
|
+
try {
|
|
60
|
+
console.log(`š¦ Unpacking files into: ${path.relative(currentDir, targetDir)}/ ...`);
|
|
61
|
+
|
|
62
|
+
const zip = new AdmZip(tempZipPath);
|
|
63
|
+
// Extract the payload directly into the target folder
|
|
64
|
+
zip.extractAllTo(targetDir, true);
|
|
65
|
+
|
|
66
|
+
// Delete temporary zip
|
|
67
|
+
fs.unlinkSync(tempZipPath);
|
|
68
|
+
|
|
69
|
+
console.log(`\nā
Successfully installed '${skillName}'!`);
|
|
70
|
+
console.log(`š Location: ${path.relative(currentDir, targetDir)}`);
|
|
71
|
+
console.log(`š” Tip: You can now review the SKILL.md and raw scripts locally.`);
|
|
72
|
+
} catch (err) {
|
|
73
|
+
console.error(`ā Error extracting skill: ${err.message}`);
|
|
74
|
+
if(fs.existsSync(tempZipPath)) fs.unlinkSync(tempZipPath);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
}).on('error', (err) => {
|
|
78
|
+
console.error(`ā Error connecting to server: ${err.message}`);
|
|
79
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@divyanshgoel/add-skill",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "CLI tool to download and install AI agent skills directly into your workspace.",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"add-skill": "./index.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [
|
|
13
|
+
"ai",
|
|
14
|
+
"skills",
|
|
15
|
+
"agents",
|
|
16
|
+
"claude"
|
|
17
|
+
],
|
|
18
|
+
"author": "",
|
|
19
|
+
"license": "ISC",
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"adm-zip": "^0.5.10"
|
|
22
|
+
}
|
|
23
|
+
}
|