sk-get 1.0.1 → 1.0.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.
@@ -0,0 +1,72 @@
1
+ import fs from 'fs-extra';
2
+ import path from 'path';
3
+ import chalk from 'chalk';
4
+ import { syncRepo, getAvailableSkills } from '../utils/git.js';
5
+ import { getLocalCursorSkillsDir, getGlobalCursorSkillsDir, getLocalClaudeSkillsDir, getGlobalClaudeSkillsDir, getVscodeInstructionsPath, } from '../utils/paths.js';
6
+ export async function installCommand(skillName, platform, options) {
7
+ try {
8
+ const cacheDir = await syncRepo();
9
+ const availableSkills = await getAvailableSkills(cacheDir);
10
+ if (!availableSkills.includes(skillName)) {
11
+ console.error(chalk.red(`Error: Skill "${skillName}" not found.`));
12
+ return;
13
+ }
14
+ const sourceDir = path.join(cacheDir, 'skills', skillName);
15
+ let targetDir = '';
16
+ let isVscode = false;
17
+ switch (platform.toLowerCase()) {
18
+ case 'cursor':
19
+ targetDir = options.global
20
+ ? getGlobalCursorSkillsDir()
21
+ : getLocalCursorSkillsDir();
22
+ break;
23
+ case 'claude':
24
+ targetDir = options.global
25
+ ? getGlobalClaudeSkillsDir()
26
+ : getLocalClaudeSkillsDir();
27
+ break;
28
+ case 'vscode':
29
+ isVscode = true;
30
+ if (options.global) {
31
+ console.warn(chalk.yellow('Warning: VSCode does not support global instructions via skill-get yet. Installing to local .github/copilot-instructions.md'));
32
+ }
33
+ break;
34
+ default:
35
+ console.error(chalk.red(`Error: Unsupported platform "${platform}". Use cursor, claude, or vscode.`));
36
+ return;
37
+ }
38
+ if (isVscode) {
39
+ const vscodePath = getVscodeInstructionsPath();
40
+ const skillMdPath = path.join(sourceDir, 'SKILL.md');
41
+ if (!(await fs.pathExists(skillMdPath))) {
42
+ console.error(chalk.red(`Error: SKILL.md not found in skill "${skillName}".`));
43
+ return;
44
+ }
45
+ const skillContent = await fs.readFile(skillMdPath, 'utf8');
46
+ await fs.ensureDir(path.dirname(vscodePath));
47
+ let existingContent = '';
48
+ if (await fs.pathExists(vscodePath)) {
49
+ existingContent = await fs.readFile(vscodePath, 'utf8');
50
+ }
51
+ if (existingContent.includes(skillContent)) {
52
+ console.log(chalk.yellow(`Skill "${skillName}" is already installed in VSCode instructions.`));
53
+ }
54
+ else {
55
+ const newContent = existingContent
56
+ ? `${existingContent}\n\n--- \n\n# Skill: ${skillName}\n${skillContent}`
57
+ : `# Skill: ${skillName}\n${skillContent}`;
58
+ await fs.writeFile(vscodePath, newContent);
59
+ console.log(chalk.green(`Successfully installed skill "${skillName}" to ${vscodePath}`));
60
+ }
61
+ }
62
+ else {
63
+ const targetSkillDir = path.join(targetDir, skillName);
64
+ await fs.ensureDir(targetDir);
65
+ await fs.copy(sourceDir, targetSkillDir);
66
+ console.log(chalk.green(`Successfully installed skill "${skillName}" to ${targetSkillDir}`));
67
+ }
68
+ }
69
+ catch (error) {
70
+ console.error(chalk.red(`Error: ${error.message}`));
71
+ }
72
+ }
@@ -0,0 +1,19 @@
1
+ import chalk from 'chalk';
2
+ import { syncRepo, getAvailableSkills } from '../utils/git.js';
3
+ export async function listCommand() {
4
+ try {
5
+ const cacheDir = await syncRepo();
6
+ const skills = await getAvailableSkills(cacheDir);
7
+ if (skills.length === 0) {
8
+ console.log(chalk.yellow('No skills found in the repository.'));
9
+ return;
10
+ }
11
+ console.log(chalk.green('Available skills:'));
12
+ skills.forEach((skill) => {
13
+ console.log(` - ${skill}`);
14
+ });
15
+ }
16
+ catch (error) {
17
+ console.error(chalk.red(`Error: ${error.message}`));
18
+ }
19
+ }
package/dist/index.js ADDED
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import { listCommand } from './commands/list.js';
4
+ import { installCommand } from './commands/install.js';
5
+ import { setRepoUrl, getRepoUrl } from './utils/config.js';
6
+ import chalk from 'chalk';
7
+ const program = new Command();
8
+ program
9
+ .name('sk-get')
10
+ .description('CLI tool to manage AI Agent Skills')
11
+ .version('1.0.0');
12
+ program
13
+ .command('ls')
14
+ .description('List all available skills from the repository')
15
+ .action(listCommand);
16
+ program
17
+ .command('install')
18
+ .description('Install a skill to a specific platform')
19
+ .argument('<skill-name>', 'Name of the skill to install')
20
+ .argument('<platform>', 'Target platform (cursor, claude, vscode)')
21
+ .option('-g, --global', 'Install to global directory instead of local', false)
22
+ .action((skillName, platform, options) => {
23
+ installCommand(skillName, platform, options);
24
+ });
25
+ program
26
+ .command('config')
27
+ .description('Manage configuration')
28
+ .command('set-repo')
29
+ .argument('<url>', 'Repository URL')
30
+ .action((url) => {
31
+ setRepoUrl(url);
32
+ console.log(chalk.green(`Repository URL set to: ${url}`));
33
+ });
34
+ program
35
+ .command('get-repo')
36
+ .description('Show current repository URL')
37
+ .action(() => {
38
+ console.log(chalk.blue(`Current repository URL: ${getRepoUrl()}`));
39
+ });
40
+ program.parse(process.argv);
@@ -0,0 +1,10 @@
1
+ import Conf from 'conf';
2
+ const config = new Conf({
3
+ projectName: 'sk-get',
4
+ defaults: {
5
+ repoUrl: 'https://github.com/yxl/skiil.git'
6
+ }
7
+ });
8
+ export const getRepoUrl = () => config.get('repoUrl');
9
+ export const setRepoUrl = (url) => config.set('repoUrl', url);
10
+ export default config;
@@ -0,0 +1,39 @@
1
+ import { simpleGit } from 'simple-git';
2
+ import fs from 'fs-extra';
3
+ import { getCacheDir } from './paths.js';
4
+ import { getRepoUrl } from './config.js';
5
+ import chalk from 'chalk';
6
+ export async function syncRepo() {
7
+ const cacheDir = getCacheDir();
8
+ const repoUrl = getRepoUrl();
9
+ if (!repoUrl) {
10
+ throw new Error('Repository URL not configured. Use `skill-get config repoUrl <url>` to set it.');
11
+ }
12
+ if (!(await fs.pathExists(cacheDir))) {
13
+ console.log(chalk.blue(`Cloning repository ${repoUrl}...`));
14
+ await fs.ensureDir(cacheDir);
15
+ const git = simpleGit();
16
+ await git.clone(repoUrl, cacheDir);
17
+ }
18
+ else {
19
+ // console.log(chalk.blue('Updating repository...'));
20
+ const git = simpleGit(cacheDir);
21
+ try {
22
+ await git.pull();
23
+ }
24
+ catch (error) {
25
+ console.warn(chalk.yellow('Failed to pull updates, using cached version.'));
26
+ }
27
+ }
28
+ return cacheDir;
29
+ }
30
+ export async function getAvailableSkills(cacheDir) {
31
+ const skillsDir = `${cacheDir}/skills`;
32
+ if (!(await fs.pathExists(skillsDir))) {
33
+ return [];
34
+ }
35
+ const entries = await fs.readdir(skillsDir, { withFileTypes: true });
36
+ return entries
37
+ .filter((entry) => entry.isDirectory())
38
+ .map((entry) => entry.name);
39
+ }
@@ -1,16 +1,9 @@
1
1
  import path from 'path';
2
2
  import os from 'os';
3
-
4
3
  export const getHomeDir = () => os.homedir();
5
-
6
4
  export const getGlobalCursorSkillsDir = () => path.join(getHomeDir(), '.cursor', 'skills');
7
-
8
- export const getLocalCursorSkillsDir = (cwd: string = process.cwd()) => path.join(cwd, '.cursor', 'skills');
9
-
10
- export const getLocalClaudeSkillsDir = (cwd: string = process.cwd()) => path.join(cwd, '.claude', 'skills');
11
-
5
+ export const getLocalCursorSkillsDir = (cwd = process.cwd()) => path.join(cwd, '.cursor', 'skills');
6
+ export const getLocalClaudeSkillsDir = (cwd = process.cwd()) => path.join(cwd, '.claude', 'skills');
12
7
  export const getGlobalClaudeSkillsDir = () => path.join(getHomeDir(), '.claude', 'skills');
13
-
14
- export const getVscodeInstructionsPath = (cwd: string = process.cwd()) => path.join(cwd, '.github', 'copilot-instructions.md');
15
-
8
+ export const getVscodeInstructionsPath = (cwd = process.cwd()) => path.join(cwd, '.github', 'copilot-instructions.md');
16
9
  export const getCacheDir = () => path.join(getHomeDir(), '.cache', 'sk-get');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sk-get",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "sk-get": "./bin/skill-get.js",
@@ -1,96 +0,0 @@
1
- import fs from 'fs-extra';
2
- import path from 'path';
3
- import chalk from 'chalk';
4
- import { syncRepo, getAvailableSkills } from '../utils/git.js';
5
- import {
6
- getLocalCursorSkillsDir,
7
- getGlobalCursorSkillsDir,
8
- getLocalClaudeSkillsDir,
9
- getGlobalClaudeSkillsDir,
10
- getVscodeInstructionsPath,
11
- } from '../utils/paths.js';
12
-
13
- export async function installCommand(
14
- skillName: string,
15
- platform: string,
16
- options: { global: boolean }
17
- ) {
18
- try {
19
- const cacheDir = await syncRepo();
20
- const availableSkills = await getAvailableSkills(cacheDir);
21
-
22
- if (!availableSkills.includes(skillName)) {
23
- console.error(chalk.red(`Error: Skill "${skillName}" not found.`));
24
- return;
25
- }
26
-
27
- const sourceDir = path.join(cacheDir, 'skills', skillName);
28
- let targetDir = '';
29
- let isVscode = false;
30
-
31
- switch (platform.toLowerCase()) {
32
- case 'cursor':
33
- targetDir = options.global
34
- ? getGlobalCursorSkillsDir()
35
- : getLocalCursorSkillsDir();
36
- break;
37
- case 'claude':
38
- targetDir = options.global
39
- ? getGlobalClaudeSkillsDir()
40
- : getLocalClaudeSkillsDir();
41
- break;
42
- case 'vscode':
43
- isVscode = true;
44
- if (options.global) {
45
- console.warn(
46
- chalk.yellow(
47
- 'Warning: VSCode does not support global instructions via skill-get yet. Installing to local .github/copilot-instructions.md'
48
- )
49
- );
50
- }
51
- break;
52
- default:
53
- console.error(
54
- chalk.red(
55
- `Error: Unsupported platform "${platform}". Use cursor, claude, or vscode.`
56
- )
57
- );
58
- return;
59
- }
60
-
61
- if (isVscode) {
62
- const vscodePath = getVscodeInstructionsPath();
63
- const skillMdPath = path.join(sourceDir, 'SKILL.md');
64
-
65
- if (!(await fs.pathExists(skillMdPath))) {
66
- console.error(chalk.red(`Error: SKILL.md not found in skill "${skillName}".`));
67
- return;
68
- }
69
-
70
- const skillContent = await fs.readFile(skillMdPath, 'utf8');
71
- await fs.ensureDir(path.dirname(vscodePath));
72
-
73
- let existingContent = '';
74
- if (await fs.pathExists(vscodePath)) {
75
- existingContent = await fs.readFile(vscodePath, 'utf8');
76
- }
77
-
78
- if (existingContent.includes(skillContent)) {
79
- console.log(chalk.yellow(`Skill "${skillName}" is already installed in VSCode instructions.`));
80
- } else {
81
- const newContent = existingContent
82
- ? `${existingContent}\n\n--- \n\n# Skill: ${skillName}\n${skillContent}`
83
- : `# Skill: ${skillName}\n${skillContent}`;
84
- await fs.writeFile(vscodePath, newContent);
85
- console.log(chalk.green(`Successfully installed skill "${skillName}" to ${vscodePath}`));
86
- }
87
- } else {
88
- const targetSkillDir = path.join(targetDir, skillName);
89
- await fs.ensureDir(targetDir);
90
- await fs.copy(sourceDir, targetSkillDir);
91
- console.log(chalk.green(`Successfully installed skill "${skillName}" to ${targetSkillDir}`));
92
- }
93
- } catch (error: any) {
94
- console.error(chalk.red(`Error: ${error.message}`));
95
- }
96
- }
@@ -1,21 +0,0 @@
1
- import chalk from 'chalk';
2
- import { syncRepo, getAvailableSkills } from '../utils/git.js';
3
-
4
- export async function listCommand() {
5
- try {
6
- const cacheDir = await syncRepo();
7
- const skills = await getAvailableSkills(cacheDir);
8
-
9
- if (skills.length === 0) {
10
- console.log(chalk.yellow('No skills found in the repository.'));
11
- return;
12
- }
13
-
14
- console.log(chalk.green('Available skills:'));
15
- skills.forEach((skill) => {
16
- console.log(` - ${skill}`);
17
- });
18
- } catch (error: any) {
19
- console.error(chalk.red(`Error: ${error.message}`));
20
- }
21
- }
package/src/index.ts DELETED
@@ -1,48 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { Command } from 'commander';
4
- import { listCommand } from './commands/list.js';
5
- import { installCommand } from './commands/install.js';
6
- import { setRepoUrl, getRepoUrl } from './utils/config.js';
7
- import chalk from 'chalk';
8
-
9
- const program = new Command();
10
-
11
- program
12
- .name('sk-get')
13
- .description('CLI tool to manage AI Agent Skills')
14
- .version('1.0.0');
15
-
16
- program
17
- .command('ls')
18
- .description('List all available skills from the repository')
19
- .action(listCommand);
20
-
21
- program
22
- .command('install')
23
- .description('Install a skill to a specific platform')
24
- .argument('<skill-name>', 'Name of the skill to install')
25
- .argument('<platform>', 'Target platform (cursor, claude, vscode)')
26
- .option('-g, --global', 'Install to global directory instead of local', false)
27
- .action((skillName, platform, options) => {
28
- installCommand(skillName, platform, options);
29
- });
30
-
31
- program
32
- .command('config')
33
- .description('Manage configuration')
34
- .command('set-repo')
35
- .argument('<url>', 'Repository URL')
36
- .action((url) => {
37
- setRepoUrl(url);
38
- console.log(chalk.green(`Repository URL set to: ${url}`));
39
- });
40
-
41
- program
42
- .command('get-repo')
43
- .description('Show current repository URL')
44
- .action(() => {
45
- console.log(chalk.blue(`Current repository URL: ${getRepoUrl()}`));
46
- });
47
-
48
- program.parse(process.argv);
@@ -1,12 +0,0 @@
1
- import Conf from 'conf';
2
-
3
- const config = new Conf({
4
- projectName: 'sk-get',
5
- defaults: {
6
- repoUrl: 'https://github.com/yxl/skiil.git'
7
- }
8
- });
9
-
10
- export const getRepoUrl = () => config.get('repoUrl') as string;
11
- export const setRepoUrl = (url: string) => config.set('repoUrl', url);
12
- export default config;
package/src/utils/git.ts DELETED
@@ -1,42 +0,0 @@
1
- import { simpleGit, SimpleGit } from 'simple-git';
2
- import fs from 'fs-extra';
3
- import { getCacheDir } from './paths.js';
4
- import { getRepoUrl } from './config.js';
5
- import chalk from 'chalk';
6
-
7
- export async function syncRepo(): Promise<string> {
8
- const cacheDir = getCacheDir();
9
- const repoUrl = getRepoUrl();
10
-
11
- if (!repoUrl) {
12
- throw new Error('Repository URL not configured. Use `skill-get config repoUrl <url>` to set it.');
13
- }
14
-
15
- if (!(await fs.pathExists(cacheDir))) {
16
- console.log(chalk.blue(`Cloning repository ${repoUrl}...`));
17
- await fs.ensureDir(cacheDir);
18
- const git: SimpleGit = simpleGit();
19
- await git.clone(repoUrl, cacheDir);
20
- } else {
21
- // console.log(chalk.blue('Updating repository...'));
22
- const git: SimpleGit = simpleGit(cacheDir);
23
- try {
24
- await git.pull();
25
- } catch (error) {
26
- console.warn(chalk.yellow('Failed to pull updates, using cached version.'));
27
- }
28
- }
29
-
30
- return cacheDir;
31
- }
32
-
33
- export async function getAvailableSkills(cacheDir: string): Promise<string[]> {
34
- const skillsDir = `${cacheDir}/skills`;
35
- if (!(await fs.pathExists(skillsDir))) {
36
- return [];
37
- }
38
- const entries = await fs.readdir(skillsDir, { withFileTypes: true });
39
- return entries
40
- .filter((entry) => entry.isDirectory())
41
- .map((entry) => entry.name);
42
- }
package/tsconfig.json DELETED
@@ -1,15 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ESNext",
4
- "module": "ESNext",
5
- "moduleResolution": "Node",
6
- "rootDir": "./src",
7
- "outDir": "./dist",
8
- "esModuleInterop": true,
9
- "forceConsistentCasingInFileNames": true,
10
- "strict": true,
11
- "skipLibCheck": true,
12
- "resolveJsonModule": true
13
- },
14
- "include": ["src/**/*"]
15
- }