agentskillsdk 0.1.1 → 0.1.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentskillsdk",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Install agent skills from agentskills.dk",
5
5
  "type": "module",
6
6
  "bin": {
@@ -3,41 +3,61 @@ import { join } from 'node:path';
3
3
  import { fetchSkill, fetchSkills } from '../lib/api.js';
4
4
  import { detectAgents } from '../lib/detect-agent.js';
5
5
  import { downloadSkill } from '../lib/download.js';
6
+ import { parseGithubSource } from '../lib/parse-source.js';
6
7
 
7
- export async function addCommand(skillName) {
8
+ export async function addCommand(skillName, options) {
8
9
  const cwd = process.cwd();
10
+ const githubSource = parseGithubSource(skillName);
9
11
 
10
- // 1. Look up skill
11
12
  let skill;
12
- try {
13
- skill = await fetchSkill(skillName);
14
- } catch (err) {
15
- console.error(chalk.red(`\n ${err.message}\n`));
16
- process.exit(1);
17
- }
13
+ let installName;
18
14
 
19
- if (!skill) {
20
- let suggestions = [];
15
+ if (githubSource) {
16
+ // GitHub owner/repo source
17
+ const skillPath = options.skill || '';
18
+ installName = skillPath ? skillPath.split('/').pop() : githubSource.repo;
19
+ skill = {
20
+ name: installName,
21
+ githubOwner: githubSource.owner,
22
+ githubRepo: githubSource.repo,
23
+ githubPath: skillPath,
24
+ defaultBranch: 'main',
25
+ };
26
+ console.log(chalk.green(' \u2713') + ` GitHub source: ${chalk.bold(`${githubSource.owner}/${githubSource.repo}`)}` +
27
+ (options.skill ? ` (skill: ${chalk.bold(options.skill)})` : ''));
28
+ } else {
29
+ // Registry source
30
+ installName = skillName;
21
31
  try {
22
- const allSkills = await fetchSkills();
23
- suggestions = allSkills
24
- .filter(s => s.name.includes(skillName) || skillName.includes(s.name))
25
- .slice(0, 3);
26
- } catch {
27
- // If we can't fetch suggestions, just show the not-found message
32
+ skill = await fetchSkill(skillName);
33
+ } catch (err) {
34
+ console.error(chalk.red(`\n ${err.message}\n`));
35
+ process.exit(1);
28
36
  }
29
37
 
30
- console.error(chalk.red(`\n Skill "${skillName}" not found.\n`));
31
- if (suggestions.length > 0) {
32
- console.error(' Did you mean:');
33
- suggestions.forEach(s => console.error(` - ${chalk.bold(s.name)}`));
34
- console.error('');
38
+ if (!skill) {
39
+ let suggestions = [];
40
+ try {
41
+ const allSkills = await fetchSkills();
42
+ suggestions = allSkills
43
+ .filter(s => s.name.includes(skillName) || skillName.includes(s.name))
44
+ .slice(0, 3);
45
+ } catch {
46
+ // If we can't fetch suggestions, just show the not-found message
47
+ }
48
+
49
+ console.error(chalk.red(`\n Skill "${skillName}" not found.\n`));
50
+ if (suggestions.length > 0) {
51
+ console.error(' Did you mean:');
52
+ suggestions.forEach(s => console.error(` - ${chalk.bold(s.name)}`));
53
+ console.error('');
54
+ }
55
+ console.error(` Browse all skills: ${chalk.underline('https://agentskills.dk/skills')}\n`);
56
+ process.exit(1);
35
57
  }
36
- console.error(` Browse all skills: ${chalk.underline('https://agentskills.dk/skills')}\n`);
37
- process.exit(1);
38
- }
39
58
 
40
- console.log(chalk.green(' \u2713') + ` Found skill: ${chalk.bold(skill.name)}`);
59
+ console.log(chalk.green(' \u2713') + ` Found skill: ${chalk.bold(skill.name)}`);
60
+ }
41
61
 
42
62
  // 2. Detect agent
43
63
  const agents = await detectAgents(cwd);
@@ -45,7 +65,7 @@ export async function addCommand(skillName) {
45
65
 
46
66
  // 3. Download + install for each selected agent
47
67
  for (const agent of agents) {
48
- const destDir = join(cwd, agent.path(skillName));
68
+ const destDir = join(cwd, agent.path(installName));
49
69
  try {
50
70
  await downloadSkill(skill, destDir);
51
71
  } catch (err) {
@@ -53,10 +73,14 @@ export async function addCommand(skillName) {
53
73
  console.error(chalk.red(` ${err.message}\n`));
54
74
  process.exit(1);
55
75
  }
56
- console.log(chalk.green(' \u2713') + ` Installed to ${agent.path(skillName)}`);
76
+ console.log(chalk.green(' \u2713') + ` Installed to ${agent.path(installName)}`);
57
77
  }
58
78
 
59
79
  // 4. Done
60
80
  console.log(`\n Skill ready. Start a new ${agents[0].name} session to use it.`);
61
- console.log(` Learn more: ${chalk.underline(`https://agentskills.dk/skills/${skill.namespace}`)}\n`);
81
+ if (!githubSource) {
82
+ console.log(` Learn more: ${chalk.underline(`https://agentskills.dk/skills/${skill.namespace}`)}\n`);
83
+ } else {
84
+ console.log('');
85
+ }
62
86
  }
package/src/index.js CHANGED
@@ -12,7 +12,8 @@ program
12
12
  program
13
13
  .command('add')
14
14
  .description('Install a skill into your project')
15
- .argument('<skill-name>', 'name of the skill to install')
15
+ .argument('<skill-name>', 'name of the skill to install (or owner/repo for GitHub)')
16
+ .option('--skill <path>', 'path within repo, e.g. skills/twitter')
16
17
  .action(addCommand);
17
18
 
18
19
  program
@@ -33,8 +33,18 @@ export async function downloadSkill(skill, destDir) {
33
33
  parts.shift();
34
34
  const relativePath = parts.join('/');
35
35
 
36
- if (header.type === 'file' && relativePath.startsWith(skillPath + '/')) {
37
- const fileRelative = relativePath.slice(skillPath.length + 1);
36
+ let fileRelative;
37
+ if (skillPath === '') {
38
+ if (header.type === 'file' && relativePath) {
39
+ fileRelative = relativePath;
40
+ }
41
+ } else {
42
+ if (header.type === 'file' && relativePath.startsWith(skillPath + '/')) {
43
+ fileRelative = relativePath.slice(skillPath.length + 1);
44
+ }
45
+ }
46
+
47
+ if (fileRelative) {
38
48
  const destPath = join(destDir, fileRelative);
39
49
 
40
50
  mkdirSync(dirname(destPath), { recursive: true });
@@ -0,0 +1,7 @@
1
+ export function parseGithubSource(input) {
2
+ const parts = input.split('/');
3
+ if (parts.length === 2 && parts[0] && parts[1]) {
4
+ return { owner: parts[0], repo: parts[1] };
5
+ }
6
+ return null;
7
+ }