@harshitj183/ai-skills 2.0.1 → 2.2.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.
@@ -0,0 +1,24 @@
1
+ name: Publish to NPM
2
+
3
+ on:
4
+ release:
5
+ types: [created]
6
+ workflow_dispatch:
7
+
8
+ jobs:
9
+ build:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v4
13
+ - uses: actions/setup-node@v4
14
+ with:
15
+ node-version: '20.x'
16
+ registry-url: 'https://registry.npmjs.org'
17
+
18
+ - name: Install dependencies
19
+ run: npm ci || npm install
20
+
21
+ - name: Publish to NPM
22
+ run: npm publish --access public
23
+ env:
24
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
package/README.md CHANGED
@@ -17,15 +17,21 @@ This library gives your AI agents extreme precision, bypassing general hallucina
17
17
 
18
18
  ---
19
19
 
20
- ## <img src="https://cdn.simpleicons.org/npm" width="24" align="center" /> Quickstart: The Installer
20
+ ## <img src="https://cdn.simpleicons.org/npm" width="24" align="center" /> Quickstart: The Smart CLI
21
21
 
22
- Run our zero-dependency official installer inside any project directory (Next.js, Python, React Native, etc.) to instantly deploy the full library to your workspace.
22
+ Our interactive CLI module gives you absolute control over what skills are deployed and auto-configures your IDE.
23
23
 
24
24
  ```bash
25
- npx @harshitj183/ai-skills init
25
+ npx @harshitj183/ai-skills <command>
26
26
  ```
27
27
 
28
- > **Note for Cursor IDE users:** Move `smart-instructions/SKILL.md` to your project root and rename it to `.cursorrules` to automatically enforce global project rules across all your IDE chats.
28
+ ### Available Commands:
29
+ 1. **`init`** – Installs the full library quietly by default (perfect for letting your AI agent select skills dynamically).
30
+ - `npx @harshitj183/ai-skills init -i` (Interactive picker)
31
+ - `npx @harshitj183/ai-skills init -r frontend_expert.md -s react_best_practices.md` (CLI filtering)
32
+ 2. **`configure`** – Auto-detects and writes the rules file for your specific IDE (`.cursorrules`, `.windsurfrules`, `CLAUDE.md`, etc.).
33
+ 3. **`update`** – Safely pulls the newest official skills from the registry without overwriting your custom skills.
34
+ 4. **`create <skill_name>`** – Scaffolds a new highly-optimized custom Mega-Skill inside `smart-instructions/custom/`.
29
35
 
30
36
  ---
31
37
 
package/bin/cli.js CHANGED
@@ -1,7 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const fs = require('fs');
3
+ const fs = require('fs-extra');
4
4
  const path = require('path');
5
+ const { program } = require('commander');
6
+ const inquirer = require('inquirer');
5
7
 
6
8
  // ANSI Terminal Colors
7
9
  const colors = {
@@ -16,64 +18,251 @@ const colors = {
16
18
 
17
19
  const targetDir = process.cwd();
18
20
  const sourceDir = path.join(__dirname, '..');
21
+ const targetDirBase = path.join(targetDir, 'smart-instructions');
19
22
 
20
- console.log(`${colors.bright}${colors.cyan}Initializing Smart AI Skills Library...${colors.reset}\n`);
23
+ program
24
+ .name('ai-skills')
25
+ .description('The Ultimate AI Skill Library CLI')
26
+ .version('2.0.1');
21
27
 
22
- // Helper function to copy files and directories recursively
23
- function copySync(src, dest) {
24
- if (!fs.existsSync(src)) return;
25
- const stat = fs.statSync(src);
26
- if (stat.isDirectory()) {
27
- if (!fs.existsSync(dest)) fs.mkdirSync(dest, { recursive: true });
28
- fs.readdirSync(src).forEach(file => {
29
- copySync(path.join(src, file), path.join(dest, file));
30
- });
31
- } else {
32
- fs.copyFileSync(src, dest);
33
- }
34
- }
28
+ program
29
+ .command('init')
30
+ .description('Installs the Smart AI Skills Library')
31
+ .option('-i, --interactive', 'Run interactively to select specific roles/skills')
32
+ .option('-r, --roles <roles>', 'Comma-separated list of roles to install')
33
+ .option('-s, --skills <skills>', 'Comma-separated list of skills to install')
34
+ .action(async (options) => {
35
+ console.log(`${colors.bright}${colors.cyan}Initializing Smart AI Skills Library...${colors.reset}\n`);
35
36
 
36
- const targetDirBase = path.join(targetDir, 'smart-instructions');
37
+ const availableRoles = fs.existsSync(path.join(sourceDir, 'roles')) ? fs.readdirSync(path.join(sourceDir, 'roles')) : [];
38
+ const availableSkills = fs.existsSync(path.join(sourceDir, 'skills')) ? fs.readdirSync(path.join(sourceDir, 'skills')) : [];
37
39
 
38
- if (!fs.existsSync(targetDirBase)) {
39
- fs.mkdirSync(targetDirBase, { recursive: true });
40
- }
40
+ let selectedRoles = availableRoles;
41
+ let selectedSkills = availableSkills;
41
42
 
42
- const targetRolesDir = path.join(targetDirBase, 'roles');
43
- const targetSkillsDir = path.join(targetDirBase, 'skills');
44
- const targetSkillMd = path.join(targetDirBase, 'SKILL.md');
45
- const gitignorePath = path.join(targetDir, '.gitignore');
43
+ if (options.interactive) {
44
+ const { installType } = await inquirer.prompt([
45
+ {
46
+ type: 'list',
47
+ name: 'installType',
48
+ message: 'How would you like to install the skills?',
49
+ choices: [
50
+ 'Install Everything (All 8 Roles, 17 Mega-Skills)',
51
+ 'Custom Pick (Select specific roles and skills)'
52
+ ]
53
+ }
54
+ ]);
46
55
 
47
- try {
48
- console.log(`${colors.blue}[+] Initializing 'smart-instructions' workspace...${colors.reset}`);
49
- if (fs.existsSync(path.join(sourceDir, 'SKILL.md'))) {
50
- fs.copyFileSync(path.join(sourceDir, 'SKILL.md'), targetSkillMd);
56
+ if (installType.startsWith('Custom')) {
57
+ const answers = await inquirer.prompt([
58
+ {
59
+ type: 'checkbox',
60
+ name: 'roles',
61
+ message: 'Select the Master Roles you need:',
62
+ choices: availableRoles.filter(f => f.endsWith('.md'))
63
+ },
64
+ {
65
+ type: 'checkbox',
66
+ name: 'skills',
67
+ message: 'Select the Mega-Skills you need:',
68
+ choices: availableSkills.filter(f => f.endsWith('.md'))
69
+ }
70
+ ]);
71
+ selectedRoles = answers.roles;
72
+ selectedSkills = answers.skills;
73
+ }
51
74
  } else {
52
- console.warn(`${colors.yellow}[!] SKILL.md not found in source.${colors.reset}`);
75
+ if (options.roles) {
76
+ const rList = options.roles.split(',').map(r => r.trim());
77
+ selectedRoles = availableRoles.filter(r => rList.includes(r) || rList.includes(r.replace('.md', '')));
78
+ }
79
+ if (options.skills) {
80
+ const sList = options.skills.split(',').map(s => s.trim());
81
+ selectedSkills = availableSkills.filter(s => sList.includes(s) || sList.includes(s.replace('.md', '')));
82
+ }
53
83
  }
54
84
 
55
- console.log(`${colors.blue}[+] Extracting 8 Master Roles...${colors.reset}`);
56
- copySync(path.join(sourceDir, 'roles'), targetRolesDir);
85
+ if (!fs.existsSync(targetDirBase)) {
86
+ fs.mkdirSync(targetDirBase, { recursive: true });
87
+ }
57
88
 
58
- console.log(`${colors.blue}[+] Extracting 17 Mega-Skills...${colors.reset}`);
59
- copySync(path.join(sourceDir, 'skills'), targetSkillsDir);
60
-
61
- console.log(`${colors.blue}[+] Securing source control (.gitignore)...${colors.reset}`);
89
+ console.log(`\n${colors.blue}[+] Securing source control (.gitignore)...${colors.reset}`);
62
90
  const ignoreRules = "\n\n# Smart AI Skills Library (Context Only)\nsmart-instructions/\n";
91
+ const gitignorePath = path.join(targetDir, '.gitignore');
63
92
  if (fs.existsSync(gitignorePath)) {
64
93
  const currentIgnore = fs.readFileSync(gitignorePath, 'utf8');
65
94
  if (!currentIgnore.includes('# Smart AI Skills Library')) {
66
95
  fs.appendFileSync(gitignorePath, ignoreRules);
67
- console.log(` ${colors.cyan}-> Appended rules to existing .gitignore${colors.reset}`);
68
96
  }
69
97
  } else {
70
98
  fs.writeFileSync(gitignorePath, ignoreRules.trim() + "\n");
71
- console.log(` ${colors.cyan}-> Created new .gitignore file${colors.reset}`);
99
+ }
100
+
101
+ console.log(`${colors.blue}[+] Copying SKILL.md Master Rulebook...${colors.reset}`);
102
+ const targetSkillMd = path.join(targetDirBase, 'SKILL.md');
103
+ if (fs.existsSync(path.join(sourceDir, 'SKILL.md'))) {
104
+ fs.copyFileSync(path.join(sourceDir, 'SKILL.md'), targetSkillMd);
105
+ }
106
+
107
+ if (selectedRoles.length > 0) {
108
+ console.log(`${colors.blue}[+] Extracting ${selectedRoles.length} Master Roles...${colors.reset}`);
109
+ fs.ensureDirSync(path.join(targetDirBase, 'roles'));
110
+ selectedRoles.forEach(role => {
111
+ fs.copyFileSync(path.join(sourceDir, 'roles', role), path.join(targetDirBase, 'roles', role));
112
+ });
113
+ }
114
+
115
+ if (selectedSkills.length > 0) {
116
+ console.log(`${colors.blue}[+] Extracting ${selectedSkills.length} Mega-Skills...${colors.reset}`);
117
+ fs.ensureDirSync(path.join(targetDirBase, 'skills'));
118
+ selectedSkills.forEach(skill => {
119
+ fs.copyFileSync(path.join(sourceDir, 'skills', skill), path.join(targetDirBase, 'skills', skill));
120
+ });
72
121
  }
73
122
 
74
123
  console.log(`\n${colors.bright}${colors.green}[Success] The 'smart-instructions' folder has been added to your project!${colors.reset}`);
75
- console.log(`${colors.yellow}Notice for Cursor IDE:${colors.reset} Move 'smart-instructions/SKILL.md' to the root of your project and rename it to '.cursorrules'\n`);
124
+ console.log(`${colors.yellow}Tip: Let your AI Agent pick skills natively, or run 'npx ai-skills configure' to setup your IDE!${colors.reset}\n`);
125
+ });
126
+
127
+ program
128
+ .command('configure')
129
+ .description('Auto-configures your IDE to use the skills')
130
+ .action(async () => {
131
+ console.log(`${colors.bright}${colors.cyan}IDE Auto-Configuration${colors.reset}\n`);
132
+
133
+ const targetSkillMd = path.join(targetDir, 'smart-instructions', 'SKILL.md');
134
+ if (!fs.existsSync(targetSkillMd)) {
135
+ console.error(`${colors.red}[Error] 'smart-instructions/SKILL.md' not found. Please run 'npx ai-skills init' first.${colors.reset}`);
136
+ return;
137
+ }
138
+
139
+ const { ideSelection } = await inquirer.prompt([
140
+ {
141
+ type: 'list',
142
+ name: 'ideSelection',
143
+ message: 'Which AI IDE or tool are you using?',
144
+ choices: [
145
+ 'Cursor (.cursorrules)',
146
+ 'Windsurf (.windsurfrules)',
147
+ 'Claude Code (CLAUDE.md)',
148
+ 'GitHub Copilot (.github/copilot-instructions.md)',
149
+ 'Cline (.clinerules)',
150
+ 'Cancel'
151
+ ]
152
+ }
153
+ ]);
154
+
155
+ let destPath = '';
156
+ if (ideSelection.startsWith('Cursor')) destPath = '.cursorrules';
157
+ else if (ideSelection.startsWith('Windsurf')) destPath = '.windsurfrules';
158
+ else if (ideSelection.startsWith('Claude')) destPath = 'CLAUDE.md';
159
+ else if (ideSelection.startsWith('GitHub')) destPath = '.github/copilot-instructions.md';
160
+ else if (ideSelection.startsWith('Cline')) destPath = '.clinerules';
161
+ else {
162
+ console.log(`${colors.yellow}Configuration cancelled.${colors.reset}`);
163
+ return;
164
+ }
165
+
166
+ const fullDestPath = path.join(targetDir, destPath);
167
+ if (destPath.includes('/')) {
168
+ fs.ensureDirSync(path.dirname(fullDestPath));
169
+ }
170
+
171
+ const ruleContent = fs.readFileSync(targetSkillMd, 'utf8');
172
+
173
+ if (fs.existsSync(fullDestPath)) {
174
+ const { overwrite } = await inquirer.prompt([
175
+ {
176
+ type: 'confirm',
177
+ name: 'overwrite',
178
+ message: `${destPath} already exists. Do you want to overwrite it?`,
179
+ default: false
180
+ }
181
+ ]);
182
+ if (!overwrite) {
183
+ console.log(`${colors.yellow}Configuration skipped.${colors.reset}`);
184
+ return;
185
+ }
186
+ }
187
+
188
+ fs.writeFileSync(fullDestPath, ruleContent);
189
+ console.log(`\n${colors.bright}${colors.green}[Success] ${destPath} has been successfully configured!${colors.reset}\n`);
190
+ });
191
+
192
+ program
193
+ .command('create <skill_name>')
194
+ .description('Scaffolds a new custom Mega-Skill')
195
+ .action(async (skillName) => {
196
+ console.log(`${colors.bright}${colors.cyan}Custom Skill Scaffolding${colors.reset}\n`);
76
197
 
77
- } catch (error) {
78
- console.error(`\n${colors.red}[Error] Failed to construct library structure: ${error.message}${colors.reset}\n`);
198
+ const { audience, format } = await inquirer.prompt([
199
+ {
200
+ type: 'input',
201
+ name: 'audience',
202
+ message: 'Who is this skill for? (e.g., Frontend React Devs, Backend Node Devs):',
203
+ },
204
+ {
205
+ type: 'confirm',
206
+ name: 'format',
207
+ message: 'Include strict JSON formatting rules?',
208
+ default: true
209
+ }
210
+ ]);
211
+
212
+ const customDir = path.join(targetDir, 'smart-instructions', 'custom');
213
+ fs.ensureDirSync(customDir);
214
+
215
+ const destFile = path.join(customDir, `${skillName.replace('.md', '')}.md`);
216
+
217
+ const template = `# ${skillName} Mega-Skill\n\n## Objective\nProvide expert-level instructions for ${audience}.\n\n## Rules\n- Always prioritize clarity and performance.\n- Write modern, maintainable code.\n${format ? '- ALWAYS output responses in strict JSON format when requested.\n' : ''}\n## Architecture Guidelines\n1. Keep functions small and focused.\n2. Ensure rigorous error handling.\n`;
218
+
219
+ fs.writeFileSync(destFile, template);
220
+ console.log(`\n${colors.bright}${colors.green}[Success] Scaffolded new custom skill at ${destFile}!${colors.reset}\n`);
221
+ });
222
+
223
+ program
224
+ .command('update')
225
+ .description('Updates the official skills without overwriting custom ones in /custom/')
226
+ .action(async () => {
227
+ console.log(`${colors.bright}${colors.cyan}Updating Official Skills${colors.reset}\n`);
228
+ const { proceed } = await inquirer.prompt([
229
+ {
230
+ type: 'confirm',
231
+ name: 'proceed',
232
+ message: 'This will safely copy the latest official skills into smart-instructions/ overriding existing ones. Custom folders will be preserved. Proceed?',
233
+ default: true
234
+ }
235
+ ]);
236
+
237
+ if (!proceed) {
238
+ console.log(`${colors.yellow}Update cancelled.${colors.reset}`);
239
+ return;
240
+ }
241
+
242
+ try {
243
+ fs.ensureDirSync(path.join(targetDir, 'smart-instructions', 'roles'));
244
+ fs.ensureDirSync(path.join(targetDir, 'smart-instructions', 'skills'));
245
+
246
+ const rDir = path.join(sourceDir, 'roles');
247
+ if (fs.existsSync(rDir)) fs.copySync(rDir, path.join(targetDir, 'smart-instructions', 'roles'));
248
+
249
+ const sDir = path.join(sourceDir, 'skills');
250
+ if (fs.existsSync(sDir)) fs.copySync(sDir, path.join(targetDir, 'smart-instructions', 'skills'));
251
+
252
+ const targetSkillMd = path.join(targetDir, 'smart-instructions', 'SKILL.md');
253
+ if (fs.existsSync(path.join(sourceDir, 'SKILL.md'))) {
254
+ fs.copyFileSync(path.join(sourceDir, 'SKILL.md'), targetSkillMd);
255
+ }
256
+
257
+ console.log(`\n${colors.bright}${colors.green}[Success] Official library updated!${colors.reset}\n`);
258
+ } catch (e) {
259
+ console.error(`${colors.red}[Error] Update failed: ${e.message}${colors.reset}`);
260
+ }
261
+ });
262
+
263
+ // Handle no arguments gracefully
264
+ if (process.argv.length === 2) {
265
+ process.argv.push('--help');
79
266
  }
267
+
268
+ program.parse(process.argv);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@harshitj183/ai-skills",
3
- "version": "2.0.1",
3
+ "version": "2.2.0",
4
4
  "description": "The Ultimate 17 Mega-Skills & 8 Roles Library for AI Agents (Cursor, Claude Code, Copilot, Antigravity)",
5
5
  "main": "bin/cli.js",
6
6
  "bin": {
@@ -38,5 +38,10 @@
38
38
  },
39
39
  "bugs": {
40
40
  "url": "https://github.com/harshitj183/ai-skills/issues"
41
+ },
42
+ "dependencies": {
43
+ "commander": "^14.0.3",
44
+ "fs-extra": "^11.3.4",
45
+ "inquirer": "^8.2.7"
41
46
  }
42
- }
47
+ }