agentskillsdk 0.3.1 → 0.4.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/package.json +1 -1
- package/src/commands/add.js +22 -18
- package/src/commands/list.js +4 -4
- package/src/index.js +7 -7
- package/src/lib/detect-agent.js +19 -0
- package/src/lib/download.js +2 -2
- package/src/lib/prompt.js +12 -5
- package/src/lib/ui.js +13 -13
package/package.json
CHANGED
package/src/commands/add.js
CHANGED
|
@@ -16,7 +16,7 @@ export async function addCommand(skillName, options) {
|
|
|
16
16
|
|
|
17
17
|
// --- resolve scope flags ---
|
|
18
18
|
if (options.global && options.project) {
|
|
19
|
-
error('
|
|
19
|
+
error('kan ikke bruge både --global og --project. vælg én.');
|
|
20
20
|
process.exit(1);
|
|
21
21
|
}
|
|
22
22
|
|
|
@@ -38,17 +38,17 @@ export async function addCommand(skillName, options) {
|
|
|
38
38
|
(options.skill ? ` (skill: ${chalk.bold(options.skill)})` : ''));
|
|
39
39
|
} else {
|
|
40
40
|
installName = skillName;
|
|
41
|
-
const spinner = ora({ text: `
|
|
41
|
+
const spinner = ora({ text: `søger efter ${chalk.bold(skillName)}...`, indent: 2 }).start();
|
|
42
42
|
try {
|
|
43
43
|
skill = await fetchSkill(skillName);
|
|
44
44
|
} catch (err) {
|
|
45
|
-
spinner.fail('
|
|
45
|
+
spinner.fail('opslag i registret fejlede');
|
|
46
46
|
error(err.message);
|
|
47
47
|
process.exit(1);
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
if (!skill) {
|
|
51
|
-
spinner.fail(`
|
|
51
|
+
spinner.fail(`skill "${skillName}" ikke fundet`);
|
|
52
52
|
|
|
53
53
|
let suggestions = [];
|
|
54
54
|
try {
|
|
@@ -61,14 +61,14 @@ export async function addCommand(skillName, options) {
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
if (suggestions.length > 0) {
|
|
64
|
-
console.error('\n
|
|
64
|
+
console.error('\n mente du:');
|
|
65
65
|
suggestions.forEach(s => console.error(` - ${chalk.bold(s.name)}`));
|
|
66
66
|
}
|
|
67
|
-
console.error(`\n
|
|
67
|
+
console.error(`\n se alle skills: ${chalk.underline('https://agentskills.dk/skills')}\n`);
|
|
68
68
|
process.exit(1);
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
spinner.succeed(`
|
|
71
|
+
spinner.succeed(`fundet skill: ${chalk.bold(skill.name)}`);
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
// --- agent selection + scope prompt (with back navigation) ---
|
|
@@ -84,9 +84,13 @@ export async function addCommand(skillName, options) {
|
|
|
84
84
|
agents = detected;
|
|
85
85
|
} else if (detected.length > 1) {
|
|
86
86
|
// Prompt: all detected vs choose specific
|
|
87
|
-
const choice = await selectPrompt('
|
|
88
|
-
{
|
|
89
|
-
|
|
87
|
+
const choice = await selectPrompt('hvordan vil du installere?', [
|
|
88
|
+
{
|
|
89
|
+
label: 'alle fundne agenter',
|
|
90
|
+
descriptionLines: detected.map(a => a.name),
|
|
91
|
+
value: 'all',
|
|
92
|
+
},
|
|
93
|
+
{ label: 'vælg specifikke agenter', value: 'choose' },
|
|
90
94
|
]);
|
|
91
95
|
|
|
92
96
|
if (choice === null) {
|
|
@@ -99,14 +103,14 @@ export async function addCommand(skillName, options) {
|
|
|
99
103
|
} else {
|
|
100
104
|
// Checkbox from detected agents
|
|
101
105
|
const choices = detected.map(a => ({ label: a.name, value: a }));
|
|
102
|
-
const selected = await checkboxPrompt('
|
|
106
|
+
const selected = await checkboxPrompt('vælg agenter:', choices);
|
|
103
107
|
if (selected === null) continue agentSelection; // Esc → back to all/choose
|
|
104
108
|
agents = selected;
|
|
105
109
|
}
|
|
106
110
|
} else {
|
|
107
111
|
// No agents detected — show checkbox of all known agents
|
|
108
112
|
const choices = AGENTS.map(a => ({ label: a.name, value: a }));
|
|
109
|
-
const selected = await checkboxPrompt('
|
|
113
|
+
const selected = await checkboxPrompt('vælg agenter:', choices);
|
|
110
114
|
if (selected === null) {
|
|
111
115
|
// Esc with no detected agents → cancel
|
|
112
116
|
process.exit(0);
|
|
@@ -122,9 +126,9 @@ export async function addCommand(skillName, options) {
|
|
|
122
126
|
} else {
|
|
123
127
|
// Build hint using first agent (representative)
|
|
124
128
|
const a = agents[0];
|
|
125
|
-
const result = await selectPrompt('
|
|
126
|
-
{ label: '
|
|
127
|
-
{ label: '
|
|
129
|
+
const result = await selectPrompt('installationsomfang:', [
|
|
130
|
+
{ label: 'projekt', hint: `(lokalt ${a.folder}/skills/)`, value: 'project' },
|
|
131
|
+
{ label: 'globalt', hint: `(~/${a.globalFolder}/skills/)`, value: 'global' },
|
|
128
132
|
]);
|
|
129
133
|
|
|
130
134
|
if (result === null) {
|
|
@@ -146,18 +150,18 @@ export async function addCommand(skillName, options) {
|
|
|
146
150
|
}
|
|
147
151
|
|
|
148
152
|
// --- download to each agent ---
|
|
149
|
-
const spinner = ora({ text: '
|
|
153
|
+
const spinner = ora({ text: 'downloader skill-filer...', indent: 2 }).start();
|
|
150
154
|
try {
|
|
151
155
|
for (const agent of agents) {
|
|
152
156
|
const destDir = agent.path(installName, { cwd, scope });
|
|
153
157
|
await downloadSkill(skill, destDir);
|
|
154
158
|
}
|
|
155
159
|
} catch (err) {
|
|
156
|
-
spinner.fail('
|
|
160
|
+
spinner.fail('download fejlede');
|
|
157
161
|
error(err.message);
|
|
158
162
|
process.exit(1);
|
|
159
163
|
}
|
|
160
|
-
spinner.succeed('
|
|
164
|
+
spinner.succeed('skill-filer downloadet');
|
|
161
165
|
|
|
162
166
|
// --- completion summary ---
|
|
163
167
|
printCompletionSummary({
|
package/src/commands/list.js
CHANGED
|
@@ -13,11 +13,11 @@ export async function listCommand() {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
if (skills.length === 0) {
|
|
16
|
-
console.log('\n
|
|
16
|
+
console.log('\n ingen skills tilgængelige endnu.\n');
|
|
17
17
|
return;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
console.log(chalk.bold('\n
|
|
20
|
+
console.log(chalk.bold('\n tilgængelige skills:\n'));
|
|
21
21
|
|
|
22
22
|
const maxName = Math.max(...skills.map(s => s.name.length));
|
|
23
23
|
|
|
@@ -25,6 +25,6 @@ export async function listCommand() {
|
|
|
25
25
|
console.log(` ${chalk.cyan(skill.name.padEnd(maxName + 2))} ${skill.description}`);
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
console.log(`\n
|
|
29
|
-
console.log(`
|
|
28
|
+
console.log(`\n installer: ${chalk.bold('npx agentskillsdk add <skill-name>')}`);
|
|
29
|
+
console.log(` gennemse: ${chalk.underline('https://agentskills.dk/skills')}\n`);
|
|
30
30
|
}
|
package/src/index.js
CHANGED
|
@@ -10,21 +10,21 @@ const program = new Command();
|
|
|
10
10
|
|
|
11
11
|
program
|
|
12
12
|
.name('agentskillsdk')
|
|
13
|
-
.description('
|
|
13
|
+
.description('installer agent-skills fra agentskills.dk')
|
|
14
14
|
.version(pkg.version);
|
|
15
15
|
|
|
16
16
|
program
|
|
17
17
|
.command('add')
|
|
18
|
-
.description('
|
|
19
|
-
.argument('<skill-name>', '
|
|
20
|
-
.option('--skill <path>', '
|
|
21
|
-
.option('-g, --global', '
|
|
22
|
-
.option('-p, --project', '
|
|
18
|
+
.description('installer en skill i dit projekt')
|
|
19
|
+
.argument('<skill-name>', 'navn på skill (eller owner/repo for GitHub)')
|
|
20
|
+
.option('--skill <path>', 'sti i repo, f.eks. skills/twitter')
|
|
21
|
+
.option('-g, --global', 'installer globalt i ~/.claude/skills/')
|
|
22
|
+
.option('-p, --project', 'installer i projekt .claude/skills/ (standard)')
|
|
23
23
|
.action(addCommand);
|
|
24
24
|
|
|
25
25
|
program
|
|
26
26
|
.command('list')
|
|
27
|
-
.description('
|
|
27
|
+
.description('vis alle tilgængelige skills')
|
|
28
28
|
.action(listCommand);
|
|
29
29
|
|
|
30
30
|
program.parse();
|
package/src/lib/detect-agent.js
CHANGED
|
@@ -22,13 +22,32 @@ function makeAgent(name, folder, { globalFolder, detectFolder } = {}) {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
export const AGENTS = [
|
|
25
|
+
makeAgent('Cline', '.cline'),
|
|
25
26
|
makeAgent('Claude Code', '.claude'),
|
|
27
|
+
makeAgent('CodeBuddy', '.codebuddy'),
|
|
26
28
|
makeAgent('Codex CLI', '.agents', { globalFolder: '.codex' }),
|
|
29
|
+
makeAgent('Command Code', '.commandcode'),
|
|
30
|
+
makeAgent('Continue', '.continue'),
|
|
31
|
+
makeAgent('Crush', '.crush'),
|
|
27
32
|
makeAgent('Cursor', '.cursor'),
|
|
28
33
|
makeAgent('Droid', '.factory'),
|
|
29
34
|
makeAgent('GitHub Copilot', '.github', { detectFolder: '.github/skills' }),
|
|
35
|
+
makeAgent('Goose', '.goose'),
|
|
36
|
+
makeAgent('Kilo Code', '.kilocode'),
|
|
37
|
+
makeAgent('Kiro CLI', '.kiro'),
|
|
38
|
+
makeAgent('MCPJam', '.mcpjam'),
|
|
39
|
+
makeAgent('Mux', '.mux'),
|
|
40
|
+
makeAgent('Neovate', '.neovate'),
|
|
30
41
|
makeAgent('OpenClaw', '.openclaw'),
|
|
31
42
|
makeAgent('OpenCode', '.opencode'),
|
|
43
|
+
makeAgent('OpenHands', '.openhands'),
|
|
44
|
+
makeAgent('Pi', '.pi'),
|
|
45
|
+
makeAgent('Qoder', '.qoder'),
|
|
46
|
+
makeAgent('Qwen Code', '.qwen'),
|
|
47
|
+
makeAgent('Roo Code', '.roo'),
|
|
48
|
+
makeAgent('Trae', '.trae'),
|
|
49
|
+
makeAgent('Windsurf', '.windsurf'),
|
|
50
|
+
makeAgent('Zencoder', '.zencoder'),
|
|
32
51
|
];
|
|
33
52
|
|
|
34
53
|
export function detectAgents(cwd) {
|
package/src/lib/download.js
CHANGED
|
@@ -17,10 +17,10 @@ export async function downloadSkill(skill, destDir) {
|
|
|
17
17
|
redirect: 'follow',
|
|
18
18
|
});
|
|
19
19
|
} catch {
|
|
20
|
-
throw new Error('
|
|
20
|
+
throw new Error('kunne ikke downloade skill-filer. tjek din internetforbindelse.');
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
if (!res.ok) throw new Error(`GitHub download
|
|
23
|
+
if (!res.ok) throw new Error(`GitHub download fejlede: ${res.status}`);
|
|
24
24
|
|
|
25
25
|
const extract = tar.extract();
|
|
26
26
|
const skillPath = skill.githubPath;
|
package/src/lib/prompt.js
CHANGED
|
@@ -34,14 +34,21 @@ export function selectPrompt(question, choices, { defaultIndex = 0 } = {}) {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
function render() {
|
|
37
|
-
const lines =
|
|
37
|
+
const lines = [];
|
|
38
|
+
for (let i = 0; i < choices.length; i++) {
|
|
39
|
+
const c = choices[i];
|
|
38
40
|
const marker = i === selected ? chalk.cyan('\u276f') : ' ';
|
|
39
41
|
const label = i === selected ? chalk.cyan(c.label) : c.label;
|
|
40
42
|
const hint = c.hint ? chalk.dim(` ${c.hint}`) : '';
|
|
41
|
-
|
|
42
|
-
|
|
43
|
+
lines.push(` ${marker} ${label}${hint}`);
|
|
44
|
+
if (c.descriptionLines) {
|
|
45
|
+
for (const dl of c.descriptionLines) {
|
|
46
|
+
lines.push(chalk.dim(` ${dl}`));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
43
50
|
lines.push('');
|
|
44
|
-
lines.push(chalk.dim(' ↑↓
|
|
51
|
+
lines.push(chalk.dim(' ↑↓ naviger · enter vælg · esc tilbage'));
|
|
45
52
|
return lines;
|
|
46
53
|
}
|
|
47
54
|
|
|
@@ -155,7 +162,7 @@ export function checkboxPrompt(question, choices) {
|
|
|
155
162
|
return ` ${box} ${label}`;
|
|
156
163
|
});
|
|
157
164
|
lines.push('');
|
|
158
|
-
lines.push(chalk.dim(' ↑↓
|
|
165
|
+
lines.push(chalk.dim(' ↑↓ naviger · space skift · enter bekræft · esc tilbage'));
|
|
159
166
|
return lines;
|
|
160
167
|
}
|
|
161
168
|
|
package/src/lib/ui.js
CHANGED
|
@@ -36,7 +36,7 @@ export function box(lines, { borderColor, padding = 2 } = {}) {
|
|
|
36
36
|
export function printBanner() {
|
|
37
37
|
const lines = [
|
|
38
38
|
`${chalk.bold('agentskillsdk')} ${chalk.dim(`v${pkg.version}`)}`,
|
|
39
|
-
chalk.dim('
|
|
39
|
+
chalk.dim('installer skills til AI-agenter'),
|
|
40
40
|
];
|
|
41
41
|
console.log('');
|
|
42
42
|
console.log(box(lines));
|
|
@@ -47,26 +47,26 @@ export function printBanner() {
|
|
|
47
47
|
|
|
48
48
|
export function printCompletionSummary({ skillName, scope, agents, isGithub, namespace }) {
|
|
49
49
|
const scopeLabel = scope === 'global'
|
|
50
|
-
? '
|
|
51
|
-
: '
|
|
50
|
+
? 'globalt (alle projekter)'
|
|
51
|
+
: 'projekt (lokalt)';
|
|
52
52
|
|
|
53
53
|
const isSingle = agents.length === 1;
|
|
54
54
|
const agentNames = agents.map(a => a.name).join(', ');
|
|
55
55
|
const paths = agents.map(a => a.displayPath(skillName, scope));
|
|
56
56
|
|
|
57
57
|
const lines = [
|
|
58
|
-
chalk.bold.green('
|
|
58
|
+
chalk.bold.green('skill installeret!'),
|
|
59
59
|
'',
|
|
60
|
-
` ${chalk.dim('
|
|
61
|
-
` ${chalk.dim('
|
|
60
|
+
` ${chalk.dim('skill:')} ${skillName}`,
|
|
61
|
+
` ${chalk.dim('omfang:')} ${scopeLabel}`,
|
|
62
62
|
];
|
|
63
63
|
|
|
64
64
|
if (isSingle) {
|
|
65
|
-
lines.push(` ${chalk.dim('
|
|
66
|
-
lines.push(` ${chalk.dim('
|
|
65
|
+
lines.push(` ${chalk.dim('agent:')} ${agentNames}`);
|
|
66
|
+
lines.push(` ${chalk.dim('sti:')} ${paths[0]}`);
|
|
67
67
|
} else {
|
|
68
|
-
lines.push(` ${chalk.dim('
|
|
69
|
-
lines.push(` ${chalk.dim('
|
|
68
|
+
lines.push(` ${chalk.dim('agenter:')} ${agentNames}`);
|
|
69
|
+
lines.push(` ${chalk.dim('stier:')} ${paths[0]}`);
|
|
70
70
|
for (let i = 1; i < paths.length; i++) {
|
|
71
71
|
lines.push(` ${paths[i]}`);
|
|
72
72
|
}
|
|
@@ -74,13 +74,13 @@ export function printCompletionSummary({ skillName, scope, agents, isGithub, nam
|
|
|
74
74
|
|
|
75
75
|
lines.push('');
|
|
76
76
|
if (isSingle) {
|
|
77
|
-
lines.push(`
|
|
77
|
+
lines.push(`start en ny ${agents[0].name}-session for at bruge den.`);
|
|
78
78
|
} else {
|
|
79
|
-
lines.push('
|
|
79
|
+
lines.push('start en ny session i en af disse agenter for at bruge den.');
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
if (!isGithub && namespace) {
|
|
83
|
-
lines.push(`
|
|
83
|
+
lines.push(`læs mere: ${chalk.underline(`https://agentskills.dk/skills/${namespace}`)}`);
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
console.log('');
|