@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.
Files changed (2) hide show
  1. package/index.js +79 -0
  2. 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
+ }