@skillkit/agents 1.3.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/LICENSE +190 -0
- package/dist/index.d.ts +209 -0
- package/dist/index.js +1190 -0
- package/dist/index.js.map +1 -0
- package/package.json +36 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1190 @@
|
|
|
1
|
+
// src/claude-code.ts
|
|
2
|
+
import { existsSync } from "fs";
|
|
3
|
+
import { join } from "path";
|
|
4
|
+
import { homedir } from "os";
|
|
5
|
+
|
|
6
|
+
// src/base.ts
|
|
7
|
+
function createSkillXml(skill) {
|
|
8
|
+
return `<skill>
|
|
9
|
+
<name>${skill.name}</name>
|
|
10
|
+
<description>${escapeXml(skill.description)}</description>
|
|
11
|
+
<location>${skill.location}</location>
|
|
12
|
+
</skill>`;
|
|
13
|
+
}
|
|
14
|
+
function escapeXml(text) {
|
|
15
|
+
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// src/claude-code.ts
|
|
19
|
+
var ClaudeCodeAdapter = class {
|
|
20
|
+
type = "claude-code";
|
|
21
|
+
name = "Claude Code";
|
|
22
|
+
skillsDir = ".claude/skills";
|
|
23
|
+
configFile = "AGENTS.md";
|
|
24
|
+
generateConfig(skills) {
|
|
25
|
+
const enabledSkills = skills.filter((s) => s.enabled);
|
|
26
|
+
if (enabledSkills.length === 0) {
|
|
27
|
+
return "";
|
|
28
|
+
}
|
|
29
|
+
const skillsXml = enabledSkills.map(createSkillXml).join("\n\n");
|
|
30
|
+
return `<skills_system priority="1">
|
|
31
|
+
|
|
32
|
+
## Available Skills
|
|
33
|
+
|
|
34
|
+
<!-- SKILLS_TABLE_START -->
|
|
35
|
+
<usage>
|
|
36
|
+
When users ask you to perform tasks, check if any of the available skills below can help complete the task more effectively. Skills provide specialized capabilities and domain knowledge.
|
|
37
|
+
|
|
38
|
+
How to use skills:
|
|
39
|
+
- Invoke: \`skillkit read <skill-name>\` or \`npx skillkit read <skill-name>\`
|
|
40
|
+
- The skill content will load with detailed instructions on how to complete the task
|
|
41
|
+
- Base directory provided in output for resolving bundled resources (references/, scripts/, assets/)
|
|
42
|
+
|
|
43
|
+
Usage notes:
|
|
44
|
+
- Only use skills listed in <available_skills> below
|
|
45
|
+
- Do not invoke a skill that is already loaded in your context
|
|
46
|
+
- Each skill invocation is stateless
|
|
47
|
+
</usage>
|
|
48
|
+
|
|
49
|
+
<available_skills>
|
|
50
|
+
|
|
51
|
+
${skillsXml}
|
|
52
|
+
|
|
53
|
+
</available_skills>
|
|
54
|
+
<!-- SKILLS_TABLE_END -->
|
|
55
|
+
|
|
56
|
+
</skills_system>`;
|
|
57
|
+
}
|
|
58
|
+
parseConfig(content) {
|
|
59
|
+
const skillNames = [];
|
|
60
|
+
const skillRegex = /<name>([^<]+)<\/name>/g;
|
|
61
|
+
let match;
|
|
62
|
+
while ((match = skillRegex.exec(content)) !== null) {
|
|
63
|
+
skillNames.push(match[1].trim());
|
|
64
|
+
}
|
|
65
|
+
return skillNames;
|
|
66
|
+
}
|
|
67
|
+
getInvokeCommand(skillName) {
|
|
68
|
+
return `skillkit read ${skillName}`;
|
|
69
|
+
}
|
|
70
|
+
async isDetected() {
|
|
71
|
+
const projectClaude = join(process.cwd(), ".claude");
|
|
72
|
+
const globalClaude = join(homedir(), ".claude");
|
|
73
|
+
const claudeMd = join(process.cwd(), "CLAUDE.md");
|
|
74
|
+
return existsSync(projectClaude) || existsSync(globalClaude) || existsSync(claudeMd);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
// src/cursor.ts
|
|
79
|
+
import { existsSync as existsSync2 } from "fs";
|
|
80
|
+
import { join as join2 } from "path";
|
|
81
|
+
var CursorAdapter = class {
|
|
82
|
+
type = "cursor";
|
|
83
|
+
name = "Cursor";
|
|
84
|
+
skillsDir = ".cursor/skills";
|
|
85
|
+
configFile = ".cursorrules";
|
|
86
|
+
generateConfig(skills) {
|
|
87
|
+
const enabledSkills = skills.filter((s) => s.enabled);
|
|
88
|
+
if (enabledSkills.length === 0) {
|
|
89
|
+
return "";
|
|
90
|
+
}
|
|
91
|
+
const skillsList = enabledSkills.map((s) => `- **${s.name}**: ${s.description}`).join("\n");
|
|
92
|
+
const skillsXml = enabledSkills.map(createSkillXml).join("\n\n");
|
|
93
|
+
return `# Skills System
|
|
94
|
+
|
|
95
|
+
You have access to specialized skills that can help complete tasks. Use the skillkit CLI to load skill instructions when needed.
|
|
96
|
+
|
|
97
|
+
## Available Skills
|
|
98
|
+
|
|
99
|
+
${skillsList}
|
|
100
|
+
|
|
101
|
+
## How to Use Skills
|
|
102
|
+
|
|
103
|
+
When a task matches a skill's description, load it with:
|
|
104
|
+
\`\`\`bash
|
|
105
|
+
skillkit read <skill-name>
|
|
106
|
+
\`\`\`
|
|
107
|
+
|
|
108
|
+
The skill will provide detailed instructions for completing the task.
|
|
109
|
+
|
|
110
|
+
<!-- SKILLS_DATA_START -->
|
|
111
|
+
${skillsXml}
|
|
112
|
+
<!-- SKILLS_DATA_END -->
|
|
113
|
+
`;
|
|
114
|
+
}
|
|
115
|
+
parseConfig(content) {
|
|
116
|
+
const skillNames = [];
|
|
117
|
+
const skillRegex = /<name>([^<]+)<\/name>/g;
|
|
118
|
+
let match;
|
|
119
|
+
while ((match = skillRegex.exec(content)) !== null) {
|
|
120
|
+
skillNames.push(match[1].trim());
|
|
121
|
+
}
|
|
122
|
+
return skillNames;
|
|
123
|
+
}
|
|
124
|
+
getInvokeCommand(skillName) {
|
|
125
|
+
return `skillkit read ${skillName}`;
|
|
126
|
+
}
|
|
127
|
+
async isDetected() {
|
|
128
|
+
const cursorRules = join2(process.cwd(), ".cursorrules");
|
|
129
|
+
const cursorDir = join2(process.cwd(), ".cursor");
|
|
130
|
+
return existsSync2(cursorRules) || existsSync2(cursorDir);
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
// src/codex.ts
|
|
135
|
+
import { existsSync as existsSync3 } from "fs";
|
|
136
|
+
import { join as join3 } from "path";
|
|
137
|
+
import { homedir as homedir2 } from "os";
|
|
138
|
+
var CodexAdapter = class {
|
|
139
|
+
type = "codex";
|
|
140
|
+
name = "OpenAI Codex CLI";
|
|
141
|
+
skillsDir = ".codex/skills";
|
|
142
|
+
configFile = "AGENTS.md";
|
|
143
|
+
generateConfig(skills) {
|
|
144
|
+
const enabledSkills = skills.filter((s) => s.enabled);
|
|
145
|
+
if (enabledSkills.length === 0) {
|
|
146
|
+
return "";
|
|
147
|
+
}
|
|
148
|
+
const skillsList = enabledSkills.map((s) => `| ${s.name} | ${s.description} | \`skillkit read ${s.name}\` |`).join("\n");
|
|
149
|
+
return `# Skills
|
|
150
|
+
|
|
151
|
+
You have access to specialized skills for completing complex tasks.
|
|
152
|
+
|
|
153
|
+
| Skill | Description | Command |
|
|
154
|
+
|-------|-------------|---------|
|
|
155
|
+
${skillsList}
|
|
156
|
+
|
|
157
|
+
## Usage
|
|
158
|
+
|
|
159
|
+
When a task matches a skill's capability, run the command to load detailed instructions:
|
|
160
|
+
|
|
161
|
+
\`\`\`bash
|
|
162
|
+
skillkit read <skill-name>
|
|
163
|
+
\`\`\`
|
|
164
|
+
|
|
165
|
+
Skills are loaded on-demand to keep context clean. Only load skills when relevant to the current task.
|
|
166
|
+
`;
|
|
167
|
+
}
|
|
168
|
+
parseConfig(content) {
|
|
169
|
+
const skillNames = [];
|
|
170
|
+
const tableRegex = /^\|\s*([a-z0-9-]+)\s*\|/gm;
|
|
171
|
+
let match;
|
|
172
|
+
while ((match = tableRegex.exec(content)) !== null) {
|
|
173
|
+
const name = match[1].trim();
|
|
174
|
+
if (name && name !== "Skill" && name !== "-------") {
|
|
175
|
+
skillNames.push(name);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return skillNames;
|
|
179
|
+
}
|
|
180
|
+
getInvokeCommand(skillName) {
|
|
181
|
+
return `skillkit read ${skillName}`;
|
|
182
|
+
}
|
|
183
|
+
async isDetected() {
|
|
184
|
+
const codexDir = join3(process.cwd(), ".codex");
|
|
185
|
+
const globalCodex = join3(homedir2(), ".codex");
|
|
186
|
+
return existsSync3(codexDir) || existsSync3(globalCodex);
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
// src/gemini-cli.ts
|
|
191
|
+
import { existsSync as existsSync4 } from "fs";
|
|
192
|
+
import { join as join4 } from "path";
|
|
193
|
+
import { homedir as homedir3 } from "os";
|
|
194
|
+
var GeminiCliAdapter = class {
|
|
195
|
+
type = "gemini-cli";
|
|
196
|
+
name = "Gemini CLI";
|
|
197
|
+
skillsDir = ".gemini/skills";
|
|
198
|
+
configFile = "GEMINI.md";
|
|
199
|
+
generateConfig(skills) {
|
|
200
|
+
const enabledSkills = skills.filter((s) => s.enabled);
|
|
201
|
+
if (enabledSkills.length === 0) {
|
|
202
|
+
return "";
|
|
203
|
+
}
|
|
204
|
+
const skillsJson = enabledSkills.map((s) => ({
|
|
205
|
+
name: s.name,
|
|
206
|
+
description: s.description,
|
|
207
|
+
invoke: `skillkit read ${s.name}`,
|
|
208
|
+
location: s.location
|
|
209
|
+
}));
|
|
210
|
+
return `# Skills Configuration
|
|
211
|
+
|
|
212
|
+
You have access to specialized skills that extend your capabilities.
|
|
213
|
+
|
|
214
|
+
## Available Skills
|
|
215
|
+
|
|
216
|
+
${enabledSkills.map((s) => `### ${s.name}
|
|
217
|
+
${s.description}
|
|
218
|
+
|
|
219
|
+
Invoke: \`skillkit read ${s.name}\``).join("\n\n")}
|
|
220
|
+
|
|
221
|
+
## Skills Data
|
|
222
|
+
|
|
223
|
+
\`\`\`json
|
|
224
|
+
${JSON.stringify(skillsJson, null, 2)}
|
|
225
|
+
\`\`\`
|
|
226
|
+
|
|
227
|
+
## Usage Instructions
|
|
228
|
+
|
|
229
|
+
1. When a task matches a skill's description, load it using the invoke command
|
|
230
|
+
2. Skills provide step-by-step instructions for complex tasks
|
|
231
|
+
3. Each skill is self-contained with its own resources
|
|
232
|
+
`;
|
|
233
|
+
}
|
|
234
|
+
parseConfig(content) {
|
|
235
|
+
const skillNames = [];
|
|
236
|
+
const jsonMatch = content.match(/```json\s*([\s\S]*?)```/);
|
|
237
|
+
if (jsonMatch) {
|
|
238
|
+
try {
|
|
239
|
+
const skills = JSON.parse(jsonMatch[1]);
|
|
240
|
+
if (Array.isArray(skills)) {
|
|
241
|
+
skills.forEach((s) => {
|
|
242
|
+
if (s.name) skillNames.push(s.name);
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
} catch {
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
if (skillNames.length === 0) {
|
|
249
|
+
const headerRegex = /^### ([a-z0-9-]+)$/gm;
|
|
250
|
+
let match;
|
|
251
|
+
while ((match = headerRegex.exec(content)) !== null) {
|
|
252
|
+
skillNames.push(match[1].trim());
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return skillNames;
|
|
256
|
+
}
|
|
257
|
+
getInvokeCommand(skillName) {
|
|
258
|
+
return `skillkit read ${skillName}`;
|
|
259
|
+
}
|
|
260
|
+
async isDetected() {
|
|
261
|
+
const geminiMd = join4(process.cwd(), "GEMINI.md");
|
|
262
|
+
const geminiDir = join4(process.cwd(), ".gemini");
|
|
263
|
+
const globalGemini = join4(homedir3(), ".gemini");
|
|
264
|
+
return existsSync4(geminiMd) || existsSync4(geminiDir) || existsSync4(globalGemini);
|
|
265
|
+
}
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
// src/opencode.ts
|
|
269
|
+
import { existsSync as existsSync5 } from "fs";
|
|
270
|
+
import { join as join5 } from "path";
|
|
271
|
+
import { homedir as homedir4 } from "os";
|
|
272
|
+
var OpenCodeAdapter = class {
|
|
273
|
+
type = "opencode";
|
|
274
|
+
name = "OpenCode";
|
|
275
|
+
skillsDir = ".opencode/skills";
|
|
276
|
+
configFile = "AGENTS.md";
|
|
277
|
+
generateConfig(skills) {
|
|
278
|
+
const enabledSkills = skills.filter((s) => s.enabled);
|
|
279
|
+
if (enabledSkills.length === 0) {
|
|
280
|
+
return "";
|
|
281
|
+
}
|
|
282
|
+
const skillsXml = enabledSkills.map(createSkillXml).join("\n\n");
|
|
283
|
+
return `<!-- SKILLKIT_START -->
|
|
284
|
+
# Skills
|
|
285
|
+
|
|
286
|
+
The following skills are available to help complete tasks:
|
|
287
|
+
|
|
288
|
+
<skills>
|
|
289
|
+
${skillsXml}
|
|
290
|
+
</skills>
|
|
291
|
+
|
|
292
|
+
## How to Use
|
|
293
|
+
|
|
294
|
+
When a task matches a skill's description:
|
|
295
|
+
|
|
296
|
+
\`\`\`bash
|
|
297
|
+
skillkit read <skill-name>
|
|
298
|
+
\`\`\`
|
|
299
|
+
|
|
300
|
+
This loads the skill's instructions into context.
|
|
301
|
+
|
|
302
|
+
<!-- SKILLKIT_END -->`;
|
|
303
|
+
}
|
|
304
|
+
parseConfig(content) {
|
|
305
|
+
const skillNames = [];
|
|
306
|
+
const skillRegex = /<name>([^<]+)<\/name>/g;
|
|
307
|
+
let match;
|
|
308
|
+
while ((match = skillRegex.exec(content)) !== null) {
|
|
309
|
+
skillNames.push(match[1].trim());
|
|
310
|
+
}
|
|
311
|
+
return skillNames;
|
|
312
|
+
}
|
|
313
|
+
getInvokeCommand(skillName) {
|
|
314
|
+
return `skillkit read ${skillName}`;
|
|
315
|
+
}
|
|
316
|
+
async isDetected() {
|
|
317
|
+
const opencodeDir = join5(process.cwd(), ".opencode");
|
|
318
|
+
const globalOpencode = join5(homedir4(), ".opencode");
|
|
319
|
+
return existsSync5(opencodeDir) || existsSync5(globalOpencode);
|
|
320
|
+
}
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
// src/antigravity.ts
|
|
324
|
+
import { existsSync as existsSync6 } from "fs";
|
|
325
|
+
import { join as join6 } from "path";
|
|
326
|
+
import { homedir as homedir5 } from "os";
|
|
327
|
+
var AntigravityAdapter = class {
|
|
328
|
+
type = "antigravity";
|
|
329
|
+
name = "Antigravity";
|
|
330
|
+
skillsDir = ".antigravity/skills";
|
|
331
|
+
configFile = "AGENTS.md";
|
|
332
|
+
generateConfig(skills) {
|
|
333
|
+
const enabledSkills = skills.filter((s) => s.enabled);
|
|
334
|
+
if (enabledSkills.length === 0) {
|
|
335
|
+
return "";
|
|
336
|
+
}
|
|
337
|
+
const skillsYaml = enabledSkills.map((s) => ` - name: ${s.name}
|
|
338
|
+
description: "${s.description}"
|
|
339
|
+
invoke: skillkit read ${s.name}`).join("\n");
|
|
340
|
+
return `# Antigravity Skills Configuration
|
|
341
|
+
|
|
342
|
+
<!-- skills:
|
|
343
|
+
${skillsYaml}
|
|
344
|
+
-->
|
|
345
|
+
|
|
346
|
+
## Available Skills
|
|
347
|
+
|
|
348
|
+
${enabledSkills.map((s) => `### ${s.name}
|
|
349
|
+
|
|
350
|
+
${s.description}
|
|
351
|
+
|
|
352
|
+
**Usage:** \`skillkit read ${s.name}\`
|
|
353
|
+
`).join("\n")}
|
|
354
|
+
|
|
355
|
+
## How Skills Work
|
|
356
|
+
|
|
357
|
+
1. Skills provide specialized knowledge for specific tasks
|
|
358
|
+
2. Load a skill when the current task matches its description
|
|
359
|
+
3. Skills are loaded on-demand to preserve context window
|
|
360
|
+
`;
|
|
361
|
+
}
|
|
362
|
+
parseConfig(content) {
|
|
363
|
+
const skillNames = [];
|
|
364
|
+
const yamlMatch = content.match(/<!-- skills:\s*([\s\S]*?)-->/);
|
|
365
|
+
if (yamlMatch) {
|
|
366
|
+
const nameRegex = /name:\s*([a-z0-9-]+)/g;
|
|
367
|
+
let match;
|
|
368
|
+
while ((match = nameRegex.exec(yamlMatch[1])) !== null) {
|
|
369
|
+
skillNames.push(match[1].trim());
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
if (skillNames.length === 0) {
|
|
373
|
+
const headerRegex = /^### ([a-z0-9-]+)$/gm;
|
|
374
|
+
let match;
|
|
375
|
+
while ((match = headerRegex.exec(content)) !== null) {
|
|
376
|
+
skillNames.push(match[1].trim());
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
return skillNames;
|
|
380
|
+
}
|
|
381
|
+
getInvokeCommand(skillName) {
|
|
382
|
+
return `skillkit read ${skillName}`;
|
|
383
|
+
}
|
|
384
|
+
async isDetected() {
|
|
385
|
+
const agDir = join6(process.cwd(), ".antigravity");
|
|
386
|
+
const globalAg = join6(homedir5(), ".antigravity");
|
|
387
|
+
return existsSync6(agDir) || existsSync6(globalAg);
|
|
388
|
+
}
|
|
389
|
+
};
|
|
390
|
+
|
|
391
|
+
// src/amp.ts
|
|
392
|
+
import { existsSync as existsSync7 } from "fs";
|
|
393
|
+
import { join as join7 } from "path";
|
|
394
|
+
import { homedir as homedir6 } from "os";
|
|
395
|
+
var AmpAdapter = class {
|
|
396
|
+
type = "amp";
|
|
397
|
+
name = "Amp";
|
|
398
|
+
skillsDir = ".agents/skills";
|
|
399
|
+
configFile = "AGENTS.md";
|
|
400
|
+
generateConfig(skills) {
|
|
401
|
+
const enabledSkills = skills.filter((s) => s.enabled);
|
|
402
|
+
if (enabledSkills.length === 0) {
|
|
403
|
+
return "";
|
|
404
|
+
}
|
|
405
|
+
const skillsXml = enabledSkills.map(createSkillXml).join("\n\n");
|
|
406
|
+
return `<skills_system priority="1">
|
|
407
|
+
|
|
408
|
+
## Available Skills
|
|
409
|
+
|
|
410
|
+
<!-- SKILLS_TABLE_START -->
|
|
411
|
+
<usage>
|
|
412
|
+
When users ask you to perform tasks, check if any of the available skills below can help complete the task more effectively. Skills provide specialized capabilities and domain knowledge.
|
|
413
|
+
|
|
414
|
+
How to use skills:
|
|
415
|
+
- Invoke: \`skillkit read <skill-name>\` or \`npx skillkit read <skill-name>\`
|
|
416
|
+
- The skill content will load with detailed instructions on how to complete the task
|
|
417
|
+
- Base directory provided in output for resolving bundled resources (references/, scripts/, assets/)
|
|
418
|
+
|
|
419
|
+
Usage notes:
|
|
420
|
+
- Only use skills listed in <available_skills> below
|
|
421
|
+
- Do not invoke a skill that is already loaded in your context
|
|
422
|
+
- Each skill invocation is stateless
|
|
423
|
+
</usage>
|
|
424
|
+
|
|
425
|
+
<available_skills>
|
|
426
|
+
|
|
427
|
+
${skillsXml}
|
|
428
|
+
|
|
429
|
+
</available_skills>
|
|
430
|
+
<!-- SKILLS_TABLE_END -->
|
|
431
|
+
|
|
432
|
+
</skills_system>`;
|
|
433
|
+
}
|
|
434
|
+
parseConfig(content) {
|
|
435
|
+
const skillNames = [];
|
|
436
|
+
const skillRegex = /<name>([^<]+)<\/name>/g;
|
|
437
|
+
let match;
|
|
438
|
+
while ((match = skillRegex.exec(content)) !== null) {
|
|
439
|
+
skillNames.push(match[1].trim());
|
|
440
|
+
}
|
|
441
|
+
return skillNames;
|
|
442
|
+
}
|
|
443
|
+
getInvokeCommand(skillName) {
|
|
444
|
+
return `skillkit read ${skillName}`;
|
|
445
|
+
}
|
|
446
|
+
async isDetected() {
|
|
447
|
+
const projectAgents = join7(process.cwd(), ".agents");
|
|
448
|
+
const globalAgents = join7(homedir6(), ".config", "agents");
|
|
449
|
+
return existsSync7(projectAgents) || existsSync7(globalAgents);
|
|
450
|
+
}
|
|
451
|
+
};
|
|
452
|
+
|
|
453
|
+
// src/clawdbot.ts
|
|
454
|
+
import { existsSync as existsSync8 } from "fs";
|
|
455
|
+
import { join as join8 } from "path";
|
|
456
|
+
import { homedir as homedir7 } from "os";
|
|
457
|
+
var ClawdbotAdapter = class {
|
|
458
|
+
type = "clawdbot";
|
|
459
|
+
name = "Clawdbot";
|
|
460
|
+
skillsDir = "skills";
|
|
461
|
+
configFile = "AGENTS.md";
|
|
462
|
+
generateConfig(skills) {
|
|
463
|
+
const enabledSkills = skills.filter((s) => s.enabled);
|
|
464
|
+
if (enabledSkills.length === 0) {
|
|
465
|
+
return "";
|
|
466
|
+
}
|
|
467
|
+
const skillsXml = enabledSkills.map(createSkillXml).join("\n\n");
|
|
468
|
+
return `<skills_system priority="1">
|
|
469
|
+
|
|
470
|
+
## Available Skills
|
|
471
|
+
|
|
472
|
+
<!-- SKILLS_TABLE_START -->
|
|
473
|
+
<usage>
|
|
474
|
+
When users ask you to perform tasks, check if any of the available skills below can help complete the task more effectively. Skills provide specialized capabilities and domain knowledge.
|
|
475
|
+
|
|
476
|
+
How to use skills:
|
|
477
|
+
- Invoke: \`skillkit read <skill-name>\` or \`npx skillkit read <skill-name>\`
|
|
478
|
+
- The skill content will load with detailed instructions on how to complete the task
|
|
479
|
+
- Base directory provided in output for resolving bundled resources (references/, scripts/, assets/)
|
|
480
|
+
|
|
481
|
+
Usage notes:
|
|
482
|
+
- Only use skills listed in <available_skills> below
|
|
483
|
+
- Do not invoke a skill that is already loaded in your context
|
|
484
|
+
- Each skill invocation is stateless
|
|
485
|
+
</usage>
|
|
486
|
+
|
|
487
|
+
<available_skills>
|
|
488
|
+
|
|
489
|
+
${skillsXml}
|
|
490
|
+
|
|
491
|
+
</available_skills>
|
|
492
|
+
<!-- SKILLS_TABLE_END -->
|
|
493
|
+
|
|
494
|
+
</skills_system>`;
|
|
495
|
+
}
|
|
496
|
+
parseConfig(content) {
|
|
497
|
+
const skillNames = [];
|
|
498
|
+
const skillRegex = /<name>([^<]+)<\/name>/g;
|
|
499
|
+
let match;
|
|
500
|
+
while ((match = skillRegex.exec(content)) !== null) {
|
|
501
|
+
skillNames.push(match[1].trim());
|
|
502
|
+
}
|
|
503
|
+
return skillNames;
|
|
504
|
+
}
|
|
505
|
+
getInvokeCommand(skillName) {
|
|
506
|
+
return `skillkit read ${skillName}`;
|
|
507
|
+
}
|
|
508
|
+
async isDetected() {
|
|
509
|
+
const projectSkills = join8(process.cwd(), "skills");
|
|
510
|
+
const globalClawdbot = join8(homedir7(), ".clawdbot");
|
|
511
|
+
return existsSync8(globalClawdbot) || existsSync8(projectSkills) && existsSync8(join8(process.cwd(), ".clawdbot"));
|
|
512
|
+
}
|
|
513
|
+
};
|
|
514
|
+
|
|
515
|
+
// src/droid.ts
|
|
516
|
+
import { existsSync as existsSync9 } from "fs";
|
|
517
|
+
import { join as join9 } from "path";
|
|
518
|
+
import { homedir as homedir8 } from "os";
|
|
519
|
+
var DroidAdapter = class {
|
|
520
|
+
type = "droid";
|
|
521
|
+
name = "Droid (Factory)";
|
|
522
|
+
skillsDir = ".factory/skills";
|
|
523
|
+
configFile = "AGENTS.md";
|
|
524
|
+
generateConfig(skills) {
|
|
525
|
+
const enabledSkills = skills.filter((s) => s.enabled);
|
|
526
|
+
if (enabledSkills.length === 0) {
|
|
527
|
+
return "";
|
|
528
|
+
}
|
|
529
|
+
const skillsXml = enabledSkills.map(createSkillXml).join("\n\n");
|
|
530
|
+
return `<skills_system priority="1">
|
|
531
|
+
|
|
532
|
+
## Available Skills
|
|
533
|
+
|
|
534
|
+
<!-- SKILLS_TABLE_START -->
|
|
535
|
+
<usage>
|
|
536
|
+
When users ask you to perform tasks, check if any of the available skills below can help complete the task more effectively. Skills provide specialized capabilities and domain knowledge.
|
|
537
|
+
|
|
538
|
+
How to use skills:
|
|
539
|
+
- Invoke: \`skillkit read <skill-name>\` or \`npx skillkit read <skill-name>\`
|
|
540
|
+
- The skill content will load with detailed instructions on how to complete the task
|
|
541
|
+
- Base directory provided in output for resolving bundled resources (references/, scripts/, assets/)
|
|
542
|
+
|
|
543
|
+
Usage notes:
|
|
544
|
+
- Only use skills listed in <available_skills> below
|
|
545
|
+
- Do not invoke a skill that is already loaded in your context
|
|
546
|
+
- Each skill invocation is stateless
|
|
547
|
+
</usage>
|
|
548
|
+
|
|
549
|
+
<available_skills>
|
|
550
|
+
|
|
551
|
+
${skillsXml}
|
|
552
|
+
|
|
553
|
+
</available_skills>
|
|
554
|
+
<!-- SKILLS_TABLE_END -->
|
|
555
|
+
|
|
556
|
+
</skills_system>`;
|
|
557
|
+
}
|
|
558
|
+
parseConfig(content) {
|
|
559
|
+
const skillNames = [];
|
|
560
|
+
const skillRegex = /<name>([^<]+)<\/name>/g;
|
|
561
|
+
let match;
|
|
562
|
+
while ((match = skillRegex.exec(content)) !== null) {
|
|
563
|
+
skillNames.push(match[1].trim());
|
|
564
|
+
}
|
|
565
|
+
return skillNames;
|
|
566
|
+
}
|
|
567
|
+
getInvokeCommand(skillName) {
|
|
568
|
+
return `skillkit read ${skillName}`;
|
|
569
|
+
}
|
|
570
|
+
async isDetected() {
|
|
571
|
+
const projectFactory = join9(process.cwd(), ".factory");
|
|
572
|
+
const globalFactory = join9(homedir8(), ".factory");
|
|
573
|
+
return existsSync9(projectFactory) || existsSync9(globalFactory);
|
|
574
|
+
}
|
|
575
|
+
};
|
|
576
|
+
|
|
577
|
+
// src/github-copilot.ts
|
|
578
|
+
import { existsSync as existsSync10 } from "fs";
|
|
579
|
+
import { join as join10 } from "path";
|
|
580
|
+
import { homedir as homedir9 } from "os";
|
|
581
|
+
var GitHubCopilotAdapter = class {
|
|
582
|
+
type = "github-copilot";
|
|
583
|
+
name = "GitHub Copilot";
|
|
584
|
+
skillsDir = ".github/skills";
|
|
585
|
+
configFile = "AGENTS.md";
|
|
586
|
+
generateConfig(skills) {
|
|
587
|
+
const enabledSkills = skills.filter((s) => s.enabled);
|
|
588
|
+
if (enabledSkills.length === 0) {
|
|
589
|
+
return "";
|
|
590
|
+
}
|
|
591
|
+
const skillsXml = enabledSkills.map(createSkillXml).join("\n\n");
|
|
592
|
+
return `<skills_system priority="1">
|
|
593
|
+
|
|
594
|
+
## Available Skills
|
|
595
|
+
|
|
596
|
+
<!-- SKILLS_TABLE_START -->
|
|
597
|
+
<usage>
|
|
598
|
+
When users ask you to perform tasks, check if any of the available skills below can help complete the task more effectively. Skills provide specialized capabilities and domain knowledge.
|
|
599
|
+
|
|
600
|
+
How to use skills:
|
|
601
|
+
- Invoke: \`skillkit read <skill-name>\` or \`npx skillkit read <skill-name>\`
|
|
602
|
+
- The skill content will load with detailed instructions on how to complete the task
|
|
603
|
+
- Base directory provided in output for resolving bundled resources (references/, scripts/, assets/)
|
|
604
|
+
|
|
605
|
+
Usage notes:
|
|
606
|
+
- Only use skills listed in <available_skills> below
|
|
607
|
+
- Do not invoke a skill that is already loaded in your context
|
|
608
|
+
- Each skill invocation is stateless
|
|
609
|
+
</usage>
|
|
610
|
+
|
|
611
|
+
<available_skills>
|
|
612
|
+
|
|
613
|
+
${skillsXml}
|
|
614
|
+
|
|
615
|
+
</available_skills>
|
|
616
|
+
<!-- SKILLS_TABLE_END -->
|
|
617
|
+
|
|
618
|
+
</skills_system>`;
|
|
619
|
+
}
|
|
620
|
+
parseConfig(content) {
|
|
621
|
+
const skillNames = [];
|
|
622
|
+
const skillRegex = /<name>([^<]+)<\/name>/g;
|
|
623
|
+
let match;
|
|
624
|
+
while ((match = skillRegex.exec(content)) !== null) {
|
|
625
|
+
skillNames.push(match[1].trim());
|
|
626
|
+
}
|
|
627
|
+
return skillNames;
|
|
628
|
+
}
|
|
629
|
+
getInvokeCommand(skillName) {
|
|
630
|
+
return `skillkit read ${skillName}`;
|
|
631
|
+
}
|
|
632
|
+
async isDetected() {
|
|
633
|
+
const projectGithub = join10(process.cwd(), ".github", "skills");
|
|
634
|
+
const globalCopilot = join10(homedir9(), ".copilot");
|
|
635
|
+
return existsSync10(projectGithub) || existsSync10(globalCopilot);
|
|
636
|
+
}
|
|
637
|
+
};
|
|
638
|
+
|
|
639
|
+
// src/goose.ts
|
|
640
|
+
import { existsSync as existsSync11 } from "fs";
|
|
641
|
+
import { join as join11 } from "path";
|
|
642
|
+
import { homedir as homedir10 } from "os";
|
|
643
|
+
var GooseAdapter = class {
|
|
644
|
+
type = "goose";
|
|
645
|
+
name = "Goose";
|
|
646
|
+
skillsDir = ".goose/skills";
|
|
647
|
+
configFile = "AGENTS.md";
|
|
648
|
+
generateConfig(skills) {
|
|
649
|
+
const enabledSkills = skills.filter((s) => s.enabled);
|
|
650
|
+
if (enabledSkills.length === 0) {
|
|
651
|
+
return "";
|
|
652
|
+
}
|
|
653
|
+
const skillsXml = enabledSkills.map(createSkillXml).join("\n\n");
|
|
654
|
+
return `<skills_system priority="1">
|
|
655
|
+
|
|
656
|
+
## Available Skills
|
|
657
|
+
|
|
658
|
+
<!-- SKILLS_TABLE_START -->
|
|
659
|
+
<usage>
|
|
660
|
+
When users ask you to perform tasks, check if any of the available skills below can help complete the task more effectively. Skills provide specialized capabilities and domain knowledge.
|
|
661
|
+
|
|
662
|
+
How to use skills:
|
|
663
|
+
- Invoke: \`skillkit read <skill-name>\` or \`npx skillkit read <skill-name>\`
|
|
664
|
+
- The skill content will load with detailed instructions on how to complete the task
|
|
665
|
+
- Base directory provided in output for resolving bundled resources (references/, scripts/, assets/)
|
|
666
|
+
|
|
667
|
+
Usage notes:
|
|
668
|
+
- Only use skills listed in <available_skills> below
|
|
669
|
+
- Do not invoke a skill that is already loaded in your context
|
|
670
|
+
- Each skill invocation is stateless
|
|
671
|
+
</usage>
|
|
672
|
+
|
|
673
|
+
<available_skills>
|
|
674
|
+
|
|
675
|
+
${skillsXml}
|
|
676
|
+
|
|
677
|
+
</available_skills>
|
|
678
|
+
<!-- SKILLS_TABLE_END -->
|
|
679
|
+
|
|
680
|
+
</skills_system>`;
|
|
681
|
+
}
|
|
682
|
+
parseConfig(content) {
|
|
683
|
+
const skillNames = [];
|
|
684
|
+
const skillRegex = /<name>([^<]+)<\/name>/g;
|
|
685
|
+
let match;
|
|
686
|
+
while ((match = skillRegex.exec(content)) !== null) {
|
|
687
|
+
skillNames.push(match[1].trim());
|
|
688
|
+
}
|
|
689
|
+
return skillNames;
|
|
690
|
+
}
|
|
691
|
+
getInvokeCommand(skillName) {
|
|
692
|
+
return `skillkit read ${skillName}`;
|
|
693
|
+
}
|
|
694
|
+
async isDetected() {
|
|
695
|
+
const projectGoose = join11(process.cwd(), ".goose");
|
|
696
|
+
const globalGoose = join11(homedir10(), ".config", "goose");
|
|
697
|
+
return existsSync11(projectGoose) || existsSync11(globalGoose);
|
|
698
|
+
}
|
|
699
|
+
};
|
|
700
|
+
|
|
701
|
+
// src/kilo.ts
|
|
702
|
+
import { existsSync as existsSync12 } from "fs";
|
|
703
|
+
import { join as join12 } from "path";
|
|
704
|
+
import { homedir as homedir11 } from "os";
|
|
705
|
+
var KiloAdapter = class {
|
|
706
|
+
type = "kilo";
|
|
707
|
+
name = "Kilo Code";
|
|
708
|
+
skillsDir = ".kilocode/skills";
|
|
709
|
+
configFile = "AGENTS.md";
|
|
710
|
+
generateConfig(skills) {
|
|
711
|
+
const enabledSkills = skills.filter((s) => s.enabled);
|
|
712
|
+
if (enabledSkills.length === 0) {
|
|
713
|
+
return "";
|
|
714
|
+
}
|
|
715
|
+
const skillsXml = enabledSkills.map(createSkillXml).join("\n\n");
|
|
716
|
+
return `<skills_system priority="1">
|
|
717
|
+
|
|
718
|
+
## Available Skills
|
|
719
|
+
|
|
720
|
+
<!-- SKILLS_TABLE_START -->
|
|
721
|
+
<usage>
|
|
722
|
+
When users ask you to perform tasks, check if any of the available skills below can help complete the task more effectively. Skills provide specialized capabilities and domain knowledge.
|
|
723
|
+
|
|
724
|
+
How to use skills:
|
|
725
|
+
- Invoke: \`skillkit read <skill-name>\` or \`npx skillkit read <skill-name>\`
|
|
726
|
+
- The skill content will load with detailed instructions on how to complete the task
|
|
727
|
+
- Base directory provided in output for resolving bundled resources (references/, scripts/, assets/)
|
|
728
|
+
|
|
729
|
+
Usage notes:
|
|
730
|
+
- Only use skills listed in <available_skills> below
|
|
731
|
+
- Do not invoke a skill that is already loaded in your context
|
|
732
|
+
- Each skill invocation is stateless
|
|
733
|
+
</usage>
|
|
734
|
+
|
|
735
|
+
<available_skills>
|
|
736
|
+
|
|
737
|
+
${skillsXml}
|
|
738
|
+
|
|
739
|
+
</available_skills>
|
|
740
|
+
<!-- SKILLS_TABLE_END -->
|
|
741
|
+
|
|
742
|
+
</skills_system>`;
|
|
743
|
+
}
|
|
744
|
+
parseConfig(content) {
|
|
745
|
+
const skillNames = [];
|
|
746
|
+
const skillRegex = /<name>([^<]+)<\/name>/g;
|
|
747
|
+
let match;
|
|
748
|
+
while ((match = skillRegex.exec(content)) !== null) {
|
|
749
|
+
skillNames.push(match[1].trim());
|
|
750
|
+
}
|
|
751
|
+
return skillNames;
|
|
752
|
+
}
|
|
753
|
+
getInvokeCommand(skillName) {
|
|
754
|
+
return `skillkit read ${skillName}`;
|
|
755
|
+
}
|
|
756
|
+
async isDetected() {
|
|
757
|
+
const projectKilo = join12(process.cwd(), ".kilocode");
|
|
758
|
+
const globalKilo = join12(homedir11(), ".kilocode");
|
|
759
|
+
return existsSync12(projectKilo) || existsSync12(globalKilo);
|
|
760
|
+
}
|
|
761
|
+
};
|
|
762
|
+
|
|
763
|
+
// src/kiro-cli.ts
|
|
764
|
+
import { existsSync as existsSync13 } from "fs";
|
|
765
|
+
import { join as join13 } from "path";
|
|
766
|
+
import { homedir as homedir12 } from "os";
|
|
767
|
+
var KiroCliAdapter = class {
|
|
768
|
+
type = "kiro-cli";
|
|
769
|
+
name = "Kiro CLI";
|
|
770
|
+
skillsDir = ".kiro/skills";
|
|
771
|
+
configFile = "AGENTS.md";
|
|
772
|
+
generateConfig(skills) {
|
|
773
|
+
const enabledSkills = skills.filter((s) => s.enabled);
|
|
774
|
+
if (enabledSkills.length === 0) {
|
|
775
|
+
return "";
|
|
776
|
+
}
|
|
777
|
+
const skillsXml = enabledSkills.map(createSkillXml).join("\n\n");
|
|
778
|
+
return `<skills_system priority="1">
|
|
779
|
+
|
|
780
|
+
## Available Skills
|
|
781
|
+
|
|
782
|
+
<!-- SKILLS_TABLE_START -->
|
|
783
|
+
<usage>
|
|
784
|
+
When users ask you to perform tasks, check if any of the available skills below can help complete the task more effectively. Skills provide specialized capabilities and domain knowledge.
|
|
785
|
+
|
|
786
|
+
How to use skills:
|
|
787
|
+
- Invoke: \`skillkit read <skill-name>\` or \`npx skillkit read <skill-name>\`
|
|
788
|
+
- The skill content will load with detailed instructions on how to complete the task
|
|
789
|
+
- Base directory provided in output for resolving bundled resources (references/, scripts/, assets/)
|
|
790
|
+
|
|
791
|
+
Usage notes:
|
|
792
|
+
- Only use skills listed in <available_skills> below
|
|
793
|
+
- Do not invoke a skill that is already loaded in your context
|
|
794
|
+
- Each skill invocation is stateless
|
|
795
|
+
</usage>
|
|
796
|
+
|
|
797
|
+
<available_skills>
|
|
798
|
+
|
|
799
|
+
${skillsXml}
|
|
800
|
+
|
|
801
|
+
</available_skills>
|
|
802
|
+
<!-- SKILLS_TABLE_END -->
|
|
803
|
+
|
|
804
|
+
</skills_system>
|
|
805
|
+
|
|
806
|
+
**Note for Kiro CLI users:** After installing skills, you need to manually add them to your custom agent's \`resources\` in \`.kiro/agents/<agent>.json\`:
|
|
807
|
+
|
|
808
|
+
\`\`\`json
|
|
809
|
+
{
|
|
810
|
+
"resources": [
|
|
811
|
+
"skill://.kiro/skills/**/SKILL.md"
|
|
812
|
+
]
|
|
813
|
+
}
|
|
814
|
+
\`\`\``;
|
|
815
|
+
}
|
|
816
|
+
parseConfig(content) {
|
|
817
|
+
const skillNames = [];
|
|
818
|
+
const skillRegex = /<name>([^<]+)<\/name>/g;
|
|
819
|
+
let match;
|
|
820
|
+
while ((match = skillRegex.exec(content)) !== null) {
|
|
821
|
+
skillNames.push(match[1].trim());
|
|
822
|
+
}
|
|
823
|
+
return skillNames;
|
|
824
|
+
}
|
|
825
|
+
getInvokeCommand(skillName) {
|
|
826
|
+
return `skillkit read ${skillName}`;
|
|
827
|
+
}
|
|
828
|
+
async isDetected() {
|
|
829
|
+
const projectKiro = join13(process.cwd(), ".kiro");
|
|
830
|
+
const globalKiro = join13(homedir12(), ".kiro");
|
|
831
|
+
return existsSync13(projectKiro) || existsSync13(globalKiro);
|
|
832
|
+
}
|
|
833
|
+
};
|
|
834
|
+
|
|
835
|
+
// src/roo.ts
|
|
836
|
+
import { existsSync as existsSync14 } from "fs";
|
|
837
|
+
import { join as join14 } from "path";
|
|
838
|
+
import { homedir as homedir13 } from "os";
|
|
839
|
+
var RooAdapter = class {
|
|
840
|
+
type = "roo";
|
|
841
|
+
name = "Roo Code";
|
|
842
|
+
skillsDir = ".roo/skills";
|
|
843
|
+
configFile = "AGENTS.md";
|
|
844
|
+
generateConfig(skills) {
|
|
845
|
+
const enabledSkills = skills.filter((s) => s.enabled);
|
|
846
|
+
if (enabledSkills.length === 0) {
|
|
847
|
+
return "";
|
|
848
|
+
}
|
|
849
|
+
const skillsXml = enabledSkills.map(createSkillXml).join("\n\n");
|
|
850
|
+
return `<skills_system priority="1">
|
|
851
|
+
|
|
852
|
+
## Available Skills
|
|
853
|
+
|
|
854
|
+
<!-- SKILLS_TABLE_START -->
|
|
855
|
+
<usage>
|
|
856
|
+
When users ask you to perform tasks, check if any of the available skills below can help complete the task more effectively. Skills provide specialized capabilities and domain knowledge.
|
|
857
|
+
|
|
858
|
+
How to use skills:
|
|
859
|
+
- Invoke: \`skillkit read <skill-name>\` or \`npx skillkit read <skill-name>\`
|
|
860
|
+
- The skill content will load with detailed instructions on how to complete the task
|
|
861
|
+
- Base directory provided in output for resolving bundled resources (references/, scripts/, assets/)
|
|
862
|
+
|
|
863
|
+
Usage notes:
|
|
864
|
+
- Only use skills listed in <available_skills> below
|
|
865
|
+
- Do not invoke a skill that is already loaded in your context
|
|
866
|
+
- Each skill invocation is stateless
|
|
867
|
+
</usage>
|
|
868
|
+
|
|
869
|
+
<available_skills>
|
|
870
|
+
|
|
871
|
+
${skillsXml}
|
|
872
|
+
|
|
873
|
+
</available_skills>
|
|
874
|
+
<!-- SKILLS_TABLE_END -->
|
|
875
|
+
|
|
876
|
+
</skills_system>`;
|
|
877
|
+
}
|
|
878
|
+
parseConfig(content) {
|
|
879
|
+
const skillNames = [];
|
|
880
|
+
const skillRegex = /<name>([^<]+)<\/name>/g;
|
|
881
|
+
let match;
|
|
882
|
+
while ((match = skillRegex.exec(content)) !== null) {
|
|
883
|
+
skillNames.push(match[1].trim());
|
|
884
|
+
}
|
|
885
|
+
return skillNames;
|
|
886
|
+
}
|
|
887
|
+
getInvokeCommand(skillName) {
|
|
888
|
+
return `skillkit read ${skillName}`;
|
|
889
|
+
}
|
|
890
|
+
async isDetected() {
|
|
891
|
+
const projectRoo = join14(process.cwd(), ".roo");
|
|
892
|
+
const globalRoo = join14(homedir13(), ".roo");
|
|
893
|
+
return existsSync14(projectRoo) || existsSync14(globalRoo);
|
|
894
|
+
}
|
|
895
|
+
};
|
|
896
|
+
|
|
897
|
+
// src/trae.ts
|
|
898
|
+
import { existsSync as existsSync15 } from "fs";
|
|
899
|
+
import { join as join15 } from "path";
|
|
900
|
+
import { homedir as homedir14 } from "os";
|
|
901
|
+
var TraeAdapter = class {
|
|
902
|
+
type = "trae";
|
|
903
|
+
name = "Trae";
|
|
904
|
+
skillsDir = ".trae/skills";
|
|
905
|
+
configFile = "AGENTS.md";
|
|
906
|
+
generateConfig(skills) {
|
|
907
|
+
const enabledSkills = skills.filter((s) => s.enabled);
|
|
908
|
+
if (enabledSkills.length === 0) {
|
|
909
|
+
return "";
|
|
910
|
+
}
|
|
911
|
+
const skillsXml = enabledSkills.map(createSkillXml).join("\n\n");
|
|
912
|
+
return `<skills_system priority="1">
|
|
913
|
+
|
|
914
|
+
## Available Skills
|
|
915
|
+
|
|
916
|
+
<!-- SKILLS_TABLE_START -->
|
|
917
|
+
<usage>
|
|
918
|
+
When users ask you to perform tasks, check if any of the available skills below can help complete the task more effectively. Skills provide specialized capabilities and domain knowledge.
|
|
919
|
+
|
|
920
|
+
How to use skills:
|
|
921
|
+
- Invoke: \`skillkit read <skill-name>\` or \`npx skillkit read <skill-name>\`
|
|
922
|
+
- The skill content will load with detailed instructions on how to complete the task
|
|
923
|
+
- Base directory provided in output for resolving bundled resources (references/, scripts/, assets/)
|
|
924
|
+
|
|
925
|
+
Usage notes:
|
|
926
|
+
- Only use skills listed in <available_skills> below
|
|
927
|
+
- Do not invoke a skill that is already loaded in your context
|
|
928
|
+
- Each skill invocation is stateless
|
|
929
|
+
</usage>
|
|
930
|
+
|
|
931
|
+
<available_skills>
|
|
932
|
+
|
|
933
|
+
${skillsXml}
|
|
934
|
+
|
|
935
|
+
</available_skills>
|
|
936
|
+
<!-- SKILLS_TABLE_END -->
|
|
937
|
+
|
|
938
|
+
</skills_system>`;
|
|
939
|
+
}
|
|
940
|
+
parseConfig(content) {
|
|
941
|
+
const skillNames = [];
|
|
942
|
+
const skillRegex = /<name>([^<]+)<\/name>/g;
|
|
943
|
+
let match;
|
|
944
|
+
while ((match = skillRegex.exec(content)) !== null) {
|
|
945
|
+
skillNames.push(match[1].trim());
|
|
946
|
+
}
|
|
947
|
+
return skillNames;
|
|
948
|
+
}
|
|
949
|
+
getInvokeCommand(skillName) {
|
|
950
|
+
return `skillkit read ${skillName}`;
|
|
951
|
+
}
|
|
952
|
+
async isDetected() {
|
|
953
|
+
const projectTrae = join15(process.cwd(), ".trae");
|
|
954
|
+
const globalTrae = join15(homedir14(), ".trae");
|
|
955
|
+
return existsSync15(projectTrae) || existsSync15(globalTrae);
|
|
956
|
+
}
|
|
957
|
+
};
|
|
958
|
+
|
|
959
|
+
// src/windsurf.ts
|
|
960
|
+
import { existsSync as existsSync16 } from "fs";
|
|
961
|
+
import { join as join16 } from "path";
|
|
962
|
+
import { homedir as homedir15 } from "os";
|
|
963
|
+
var WindsurfAdapter = class {
|
|
964
|
+
type = "windsurf";
|
|
965
|
+
name = "Windsurf";
|
|
966
|
+
skillsDir = ".windsurf/skills";
|
|
967
|
+
configFile = "AGENTS.md";
|
|
968
|
+
generateConfig(skills) {
|
|
969
|
+
const enabledSkills = skills.filter((s) => s.enabled);
|
|
970
|
+
if (enabledSkills.length === 0) {
|
|
971
|
+
return "";
|
|
972
|
+
}
|
|
973
|
+
const skillsXml = enabledSkills.map(createSkillXml).join("\n\n");
|
|
974
|
+
return `<skills_system priority="1">
|
|
975
|
+
|
|
976
|
+
## Available Skills
|
|
977
|
+
|
|
978
|
+
<!-- SKILLS_TABLE_START -->
|
|
979
|
+
<usage>
|
|
980
|
+
When users ask you to perform tasks, check if any of the available skills below can help complete the task more effectively. Skills provide specialized capabilities and domain knowledge.
|
|
981
|
+
|
|
982
|
+
How to use skills:
|
|
983
|
+
- Invoke: \`skillkit read <skill-name>\` or \`npx skillkit read <skill-name>\`
|
|
984
|
+
- The skill content will load with detailed instructions on how to complete the task
|
|
985
|
+
- Base directory provided in output for resolving bundled resources (references/, scripts/, assets/)
|
|
986
|
+
|
|
987
|
+
Usage notes:
|
|
988
|
+
- Only use skills listed in <available_skills> below
|
|
989
|
+
- Do not invoke a skill that is already loaded in your context
|
|
990
|
+
- Each skill invocation is stateless
|
|
991
|
+
</usage>
|
|
992
|
+
|
|
993
|
+
<available_skills>
|
|
994
|
+
|
|
995
|
+
${skillsXml}
|
|
996
|
+
|
|
997
|
+
</available_skills>
|
|
998
|
+
<!-- SKILLS_TABLE_END -->
|
|
999
|
+
|
|
1000
|
+
</skills_system>`;
|
|
1001
|
+
}
|
|
1002
|
+
parseConfig(content) {
|
|
1003
|
+
const skillNames = [];
|
|
1004
|
+
const skillRegex = /<name>([^<]+)<\/name>/g;
|
|
1005
|
+
let match;
|
|
1006
|
+
while ((match = skillRegex.exec(content)) !== null) {
|
|
1007
|
+
skillNames.push(match[1].trim());
|
|
1008
|
+
}
|
|
1009
|
+
return skillNames;
|
|
1010
|
+
}
|
|
1011
|
+
getInvokeCommand(skillName) {
|
|
1012
|
+
return `skillkit read ${skillName}`;
|
|
1013
|
+
}
|
|
1014
|
+
async isDetected() {
|
|
1015
|
+
const projectWindsurf = join16(process.cwd(), ".windsurf");
|
|
1016
|
+
const globalWindsurf = join16(homedir15(), ".codeium", "windsurf");
|
|
1017
|
+
return existsSync16(projectWindsurf) || existsSync16(globalWindsurf);
|
|
1018
|
+
}
|
|
1019
|
+
};
|
|
1020
|
+
|
|
1021
|
+
// src/universal.ts
|
|
1022
|
+
import { existsSync as existsSync17 } from "fs";
|
|
1023
|
+
import { join as join17 } from "path";
|
|
1024
|
+
var UniversalAdapter = class {
|
|
1025
|
+
type = "universal";
|
|
1026
|
+
name = "Universal (Any Agent)";
|
|
1027
|
+
skillsDir = ".agent/skills";
|
|
1028
|
+
configFile = "AGENTS.md";
|
|
1029
|
+
generateConfig(skills) {
|
|
1030
|
+
const enabledSkills = skills.filter((s) => s.enabled);
|
|
1031
|
+
if (enabledSkills.length === 0) {
|
|
1032
|
+
return "";
|
|
1033
|
+
}
|
|
1034
|
+
const skillsXml = enabledSkills.map(createSkillXml).join("\n\n");
|
|
1035
|
+
const skillsList = enabledSkills.map((s) => `- **${s.name}**: ${s.description}`).join("\n");
|
|
1036
|
+
return `# Skills System
|
|
1037
|
+
|
|
1038
|
+
<!-- SKILLKIT_SKILLS_START -->
|
|
1039
|
+
|
|
1040
|
+
## Available Skills
|
|
1041
|
+
|
|
1042
|
+
${skillsList}
|
|
1043
|
+
|
|
1044
|
+
## How to Use Skills
|
|
1045
|
+
|
|
1046
|
+
When a task matches one of the available skills, load it to get detailed instructions:
|
|
1047
|
+
|
|
1048
|
+
\`\`\`bash
|
|
1049
|
+
skillkit read <skill-name>
|
|
1050
|
+
\`\`\`
|
|
1051
|
+
|
|
1052
|
+
Or with npx:
|
|
1053
|
+
|
|
1054
|
+
\`\`\`bash
|
|
1055
|
+
npx skillkit read <skill-name>
|
|
1056
|
+
\`\`\`
|
|
1057
|
+
|
|
1058
|
+
## Skills Data
|
|
1059
|
+
|
|
1060
|
+
<skills_system>
|
|
1061
|
+
<usage>
|
|
1062
|
+
Skills provide specialized capabilities and domain knowledge.
|
|
1063
|
+
- Invoke: \`skillkit read <skill-name>\`
|
|
1064
|
+
- Base directory provided in output for resolving resources
|
|
1065
|
+
- Only use skills listed below
|
|
1066
|
+
- Each invocation is stateless
|
|
1067
|
+
</usage>
|
|
1068
|
+
|
|
1069
|
+
<available_skills>
|
|
1070
|
+
|
|
1071
|
+
${skillsXml}
|
|
1072
|
+
|
|
1073
|
+
</available_skills>
|
|
1074
|
+
</skills_system>
|
|
1075
|
+
|
|
1076
|
+
<!-- SKILLKIT_SKILLS_END -->
|
|
1077
|
+
`;
|
|
1078
|
+
}
|
|
1079
|
+
parseConfig(content) {
|
|
1080
|
+
const skillNames = [];
|
|
1081
|
+
const skillRegex = /<name>([^<]+)<\/name>/g;
|
|
1082
|
+
let match;
|
|
1083
|
+
while ((match = skillRegex.exec(content)) !== null) {
|
|
1084
|
+
skillNames.push(match[1].trim());
|
|
1085
|
+
}
|
|
1086
|
+
if (skillNames.length === 0) {
|
|
1087
|
+
const listRegex = /^- \*\*([a-z0-9-]+)\*\*:/gm;
|
|
1088
|
+
while ((match = listRegex.exec(content)) !== null) {
|
|
1089
|
+
skillNames.push(match[1].trim());
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
return skillNames;
|
|
1093
|
+
}
|
|
1094
|
+
getInvokeCommand(skillName) {
|
|
1095
|
+
return `skillkit read ${skillName}`;
|
|
1096
|
+
}
|
|
1097
|
+
async isDetected() {
|
|
1098
|
+
const agentDir = join17(process.cwd(), ".agent");
|
|
1099
|
+
const agentsMd = join17(process.cwd(), "AGENTS.md");
|
|
1100
|
+
return existsSync17(agentDir) || existsSync17(agentsMd);
|
|
1101
|
+
}
|
|
1102
|
+
};
|
|
1103
|
+
|
|
1104
|
+
// src/index.ts
|
|
1105
|
+
var adapters = {
|
|
1106
|
+
"claude-code": new ClaudeCodeAdapter(),
|
|
1107
|
+
cursor: new CursorAdapter(),
|
|
1108
|
+
codex: new CodexAdapter(),
|
|
1109
|
+
"gemini-cli": new GeminiCliAdapter(),
|
|
1110
|
+
opencode: new OpenCodeAdapter(),
|
|
1111
|
+
antigravity: new AntigravityAdapter(),
|
|
1112
|
+
amp: new AmpAdapter(),
|
|
1113
|
+
clawdbot: new ClawdbotAdapter(),
|
|
1114
|
+
droid: new DroidAdapter(),
|
|
1115
|
+
"github-copilot": new GitHubCopilotAdapter(),
|
|
1116
|
+
goose: new GooseAdapter(),
|
|
1117
|
+
kilo: new KiloAdapter(),
|
|
1118
|
+
"kiro-cli": new KiroCliAdapter(),
|
|
1119
|
+
roo: new RooAdapter(),
|
|
1120
|
+
trae: new TraeAdapter(),
|
|
1121
|
+
windsurf: new WindsurfAdapter(),
|
|
1122
|
+
universal: new UniversalAdapter()
|
|
1123
|
+
};
|
|
1124
|
+
function getAdapter(type) {
|
|
1125
|
+
return adapters[type];
|
|
1126
|
+
}
|
|
1127
|
+
function getAllAdapters() {
|
|
1128
|
+
return Object.values(adapters);
|
|
1129
|
+
}
|
|
1130
|
+
async function detectAgent() {
|
|
1131
|
+
const checkOrder = [
|
|
1132
|
+
"claude-code",
|
|
1133
|
+
"cursor",
|
|
1134
|
+
"codex",
|
|
1135
|
+
"gemini-cli",
|
|
1136
|
+
"opencode",
|
|
1137
|
+
"antigravity",
|
|
1138
|
+
"amp",
|
|
1139
|
+
"clawdbot",
|
|
1140
|
+
"droid",
|
|
1141
|
+
"github-copilot",
|
|
1142
|
+
"goose",
|
|
1143
|
+
"kilo",
|
|
1144
|
+
"kiro-cli",
|
|
1145
|
+
"roo",
|
|
1146
|
+
"trae",
|
|
1147
|
+
"windsurf",
|
|
1148
|
+
"universal"
|
|
1149
|
+
];
|
|
1150
|
+
for (const type of checkOrder) {
|
|
1151
|
+
const adapter = adapters[type];
|
|
1152
|
+
if (await adapter.isDetected()) {
|
|
1153
|
+
return type;
|
|
1154
|
+
}
|
|
1155
|
+
}
|
|
1156
|
+
return "universal";
|
|
1157
|
+
}
|
|
1158
|
+
function getSkillsDir(type) {
|
|
1159
|
+
return adapters[type].skillsDir;
|
|
1160
|
+
}
|
|
1161
|
+
function getConfigFile(type) {
|
|
1162
|
+
return adapters[type].configFile;
|
|
1163
|
+
}
|
|
1164
|
+
export {
|
|
1165
|
+
AmpAdapter,
|
|
1166
|
+
AntigravityAdapter,
|
|
1167
|
+
ClaudeCodeAdapter,
|
|
1168
|
+
ClawdbotAdapter,
|
|
1169
|
+
CodexAdapter,
|
|
1170
|
+
CursorAdapter,
|
|
1171
|
+
DroidAdapter,
|
|
1172
|
+
GeminiCliAdapter,
|
|
1173
|
+
GitHubCopilotAdapter,
|
|
1174
|
+
GooseAdapter,
|
|
1175
|
+
KiloAdapter,
|
|
1176
|
+
KiroCliAdapter,
|
|
1177
|
+
OpenCodeAdapter,
|
|
1178
|
+
RooAdapter,
|
|
1179
|
+
TraeAdapter,
|
|
1180
|
+
UniversalAdapter,
|
|
1181
|
+
WindsurfAdapter,
|
|
1182
|
+
createSkillXml,
|
|
1183
|
+
detectAgent,
|
|
1184
|
+
escapeXml,
|
|
1185
|
+
getAdapter,
|
|
1186
|
+
getAllAdapters,
|
|
1187
|
+
getConfigFile,
|
|
1188
|
+
getSkillsDir
|
|
1189
|
+
};
|
|
1190
|
+
//# sourceMappingURL=index.js.map
|