skillkit 1.2.0 → 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/dist/index.js CHANGED
@@ -1,2048 +1,8 @@
1
- // src/core/types.ts
2
- import { z } from "zod";
3
- var AgentType = z.enum([
4
- "claude-code",
5
- "codex",
6
- "cursor",
7
- "antigravity",
8
- "opencode",
9
- "gemini-cli",
10
- "amp",
11
- "clawdbot",
12
- "droid",
13
- "github-copilot",
14
- "goose",
15
- "kilo",
16
- "kiro-cli",
17
- "roo",
18
- "trae",
19
- "windsurf",
20
- "universal"
21
- ]);
22
- var GitProvider = z.enum(["github", "gitlab", "bitbucket", "local"]);
23
- var SkillFrontmatter = z.object({
24
- name: z.string().min(1).max(64).regex(/^[a-z0-9]+(-[a-z0-9]+)*$/, "Skill name must be lowercase alphanumeric with hyphens, no leading/trailing/consecutive hyphens"),
25
- description: z.string().min(1).max(1024),
26
- license: z.string().optional(),
27
- compatibility: z.string().max(500).optional(),
28
- metadata: z.record(z.string()).optional(),
29
- "allowed-tools": z.string().optional(),
30
- version: z.string().optional(),
31
- author: z.string().optional(),
32
- tags: z.array(z.string()).optional(),
33
- agents: z.array(AgentType).optional()
34
- });
35
- var SkillMetadata = z.object({
36
- name: z.string(),
37
- description: z.string(),
38
- source: z.string(),
39
- sourceType: GitProvider,
40
- subpath: z.string().optional(),
41
- installedAt: z.string().datetime(),
42
- updatedAt: z.string().datetime().optional(),
43
- enabled: z.boolean().default(true),
44
- version: z.string().optional(),
45
- checksum: z.string().optional()
46
- });
47
- var SkillLocation = z.enum(["project", "global"]);
48
- var Skill = z.object({
49
- name: z.string(),
50
- description: z.string(),
51
- path: z.string(),
52
- location: SkillLocation,
53
- metadata: SkillMetadata.optional(),
54
- enabled: z.boolean().default(true)
55
- });
56
- var SkillkitConfig = z.object({
57
- version: z.literal(1),
58
- agent: AgentType.default("universal"),
59
- skillsDir: z.string().optional(),
60
- enabledSkills: z.array(z.string()).optional(),
61
- disabledSkills: z.array(z.string()).optional(),
62
- autoSync: z.boolean().default(true)
63
- });
64
-
65
- // src/core/skills.ts
66
- import { existsSync, readdirSync, readFileSync } from "fs";
67
- import { join, basename } from "path";
68
- import { parse as parseYaml } from "yaml";
69
- var SKILL_DISCOVERY_PATHS = [
70
- "skills",
71
- "skills/.curated",
72
- "skills/.experimental",
73
- "skills/.system",
74
- ".agents/skills",
75
- ".agent/skills",
76
- ".claude/skills",
77
- ".codex/skills",
78
- ".cursor/skills",
79
- ".factory/skills",
80
- ".gemini/skills",
81
- ".github/skills",
82
- ".goose/skills",
83
- ".kilocode/skills",
84
- ".kiro/skills",
85
- ".opencode/skills",
86
- ".roo/skills",
87
- ".trae/skills",
88
- ".windsurf/skills",
89
- ".clawdbot/skills",
90
- ".antigravity/skills",
91
- ".copilot/skills"
92
- ];
93
- function discoverSkillsInDir(dir) {
94
- const skills = [];
95
- if (!existsSync(dir)) {
96
- return skills;
97
- }
98
- const entries = readdirSync(dir, { withFileTypes: true });
99
- for (const entry of entries) {
100
- if (!entry.isDirectory()) continue;
101
- const skillPath = join(dir, entry.name);
102
- const skillMdPath = join(skillPath, "SKILL.md");
103
- if (existsSync(skillMdPath)) {
104
- const skill = parseSkill(skillPath);
105
- if (skill) {
106
- skills.push(skill);
107
- }
108
- }
109
- }
110
- return skills;
111
- }
112
- function discoverSkillsRecursive(dir, seen, maxDepth = 5, currentDepth = 0) {
113
- const skills = [];
114
- if (currentDepth >= maxDepth || !existsSync(dir)) {
115
- return skills;
116
- }
117
- try {
118
- const entries = readdirSync(dir, { withFileTypes: true });
119
- for (const entry of entries) {
120
- if (entry.name === "node_modules" || entry.name === ".git") {
121
- continue;
122
- }
123
- if (!entry.isDirectory()) continue;
124
- const entryPath = join(dir, entry.name);
125
- const skillMdPath = join(entryPath, "SKILL.md");
126
- if (existsSync(skillMdPath)) {
127
- const skill = parseSkill(entryPath);
128
- if (skill && !seen.has(skill.name)) {
129
- seen.add(skill.name);
130
- skills.push(skill);
131
- }
132
- } else {
133
- const subSkills = discoverSkillsRecursive(entryPath, seen, maxDepth, currentDepth + 1);
134
- skills.push(...subSkills);
135
- }
136
- }
137
- } catch {
138
- }
139
- return skills;
140
- }
141
- function discoverSkills(rootDir) {
142
- const skills = [];
143
- const seen = /* @__PURE__ */ new Set();
144
- const rootSkillMd = join(rootDir, "SKILL.md");
145
- if (existsSync(rootSkillMd)) {
146
- const skill = parseSkill(rootDir);
147
- if (skill && !seen.has(skill.name)) {
148
- seen.add(skill.name);
149
- skills.push(skill);
150
- }
151
- }
152
- for (const searchPath of SKILL_DISCOVERY_PATHS) {
153
- const fullPath = join(rootDir, searchPath);
154
- if (existsSync(fullPath)) {
155
- for (const skill of discoverSkillsInDir(fullPath)) {
156
- if (!seen.has(skill.name)) {
157
- seen.add(skill.name);
158
- skills.push(skill);
159
- }
160
- }
161
- }
162
- }
163
- for (const skill of discoverSkillsInDir(rootDir)) {
164
- if (!seen.has(skill.name)) {
165
- seen.add(skill.name);
166
- skills.push(skill);
167
- }
168
- }
169
- if (skills.length === 0) {
170
- skills.push(...discoverSkillsRecursive(rootDir, seen));
171
- }
172
- return skills;
173
- }
174
- function parseSkill(skillPath, location = "project") {
175
- const skillMdPath = join(skillPath, "SKILL.md");
176
- if (!existsSync(skillMdPath)) {
177
- return null;
178
- }
179
- try {
180
- const content = readFileSync(skillMdPath, "utf-8");
181
- const frontmatter = extractFrontmatter(content);
182
- if (!frontmatter) {
183
- const name = basename(skillPath);
184
- return {
185
- name,
186
- description: "No description available",
187
- path: skillPath,
188
- location,
189
- enabled: true
190
- };
191
- }
192
- const parsed = SkillFrontmatter.safeParse(frontmatter);
193
- if (!parsed.success) {
194
- return {
195
- name: frontmatter.name || basename(skillPath),
196
- description: frontmatter.description || "No description available",
197
- path: skillPath,
198
- location,
199
- enabled: true
200
- };
201
- }
202
- const metadata = loadMetadata(skillPath);
203
- return {
204
- name: parsed.data.name,
205
- description: parsed.data.description,
206
- path: skillPath,
207
- location,
208
- metadata: metadata ?? void 0,
209
- enabled: metadata?.enabled ?? true
210
- };
211
- } catch {
212
- return null;
213
- }
214
- }
215
- function extractFrontmatter(content) {
216
- const match = content.match(/^---\s*\n([\s\S]*?)\n---/);
217
- if (!match) {
218
- return null;
219
- }
220
- try {
221
- return parseYaml(match[1]);
222
- } catch {
223
- return null;
224
- }
225
- }
226
- function extractField(content, field) {
227
- const frontmatter = extractFrontmatter(content);
228
- if (!frontmatter || !(field in frontmatter)) {
229
- return null;
230
- }
231
- const value = frontmatter[field];
232
- return typeof value === "string" ? value : null;
233
- }
234
- function loadMetadata(skillPath) {
235
- const metadataPath = join(skillPath, ".skillkit.json");
236
- if (!existsSync(metadataPath)) {
237
- return null;
238
- }
239
- try {
240
- const content = readFileSync(metadataPath, "utf-8");
241
- const data = JSON.parse(content);
242
- const parsed = SkillMetadata.safeParse(data);
243
- return parsed.success ? parsed.data : null;
244
- } catch {
245
- return null;
246
- }
247
- }
248
- function readSkillContent(skillPath) {
249
- const skillMdPath = join(skillPath, "SKILL.md");
250
- if (!existsSync(skillMdPath)) {
251
- return null;
252
- }
253
- try {
254
- return readFileSync(skillMdPath, "utf-8");
255
- } catch {
256
- return null;
257
- }
258
- }
259
- function findSkill(name, searchDirs) {
260
- for (const dir of searchDirs) {
261
- if (!existsSync(dir)) continue;
262
- const skillPath = join(dir, name);
263
- if (existsSync(skillPath)) {
264
- const location = dir.includes(process.cwd()) ? "project" : "global";
265
- return parseSkill(skillPath, location);
266
- }
267
- }
268
- return null;
269
- }
270
- function findAllSkills(searchDirs) {
271
- const skills = [];
272
- const seen = /* @__PURE__ */ new Set();
273
- for (const dir of searchDirs) {
274
- if (!existsSync(dir)) continue;
275
- const location = dir.includes(process.cwd()) ? "project" : "global";
276
- const discovered = discoverSkills(dir);
277
- for (const skill of discovered) {
278
- if (!seen.has(skill.name)) {
279
- seen.add(skill.name);
280
- skills.push({ ...skill, location });
281
- }
282
- }
283
- }
284
- return skills;
285
- }
286
- function validateSkill(skillPath) {
287
- const errors = [];
288
- const warnings = [];
289
- const dirName = basename(skillPath);
290
- const skillMdPath = join(skillPath, "SKILL.md");
291
- if (!existsSync(skillMdPath)) {
292
- errors.push("Missing SKILL.md file");
293
- return { valid: false, errors };
294
- }
295
- const content = readFileSync(skillMdPath, "utf-8");
296
- const frontmatter = extractFrontmatter(content);
297
- if (!frontmatter) {
298
- errors.push("Missing YAML frontmatter in SKILL.md");
299
- return { valid: false, errors };
300
- }
301
- const parsed = SkillFrontmatter.safeParse(frontmatter);
302
- if (!parsed.success) {
303
- for (const issue of parsed.error.issues) {
304
- errors.push(`${issue.path.join(".") || "frontmatter"}: ${issue.message}`);
305
- }
306
- }
307
- if (parsed.success) {
308
- const data = parsed.data;
309
- if (data.name !== dirName) {
310
- warnings.push(`name "${data.name}" does not match directory name "${dirName}"`);
311
- }
312
- if (data.description && data.description.length < 50) {
313
- warnings.push("description is short; consider describing what the skill does AND when to use it");
314
- }
315
- }
316
- const bodyContent = content.replace(/^---[\s\S]*?---\s*/, "");
317
- const lineCount = bodyContent.split("\n").length;
318
- if (lineCount > 500) {
319
- warnings.push(`SKILL.md has ${lineCount} lines; consider moving detailed content to references/`);
320
- }
321
- return { valid: errors.length === 0, errors, warnings };
322
- }
323
- function isPathInside(child, parent) {
324
- const relative = child.replace(parent, "");
325
- return !relative.startsWith("..") && !relative.includes("/..");
326
- }
327
-
328
- // src/core/config.ts
329
- import { existsSync as existsSync19, readFileSync as readFileSync2, writeFileSync, mkdirSync } from "fs";
330
- import { join as join19, dirname } from "path";
331
- import { homedir as homedir16 } from "os";
332
- import { parse as parseYaml2, stringify as stringifyYaml } from "yaml";
333
-
334
- // src/agents/claude-code.ts
335
- import { existsSync as existsSync2 } from "fs";
336
- import { join as join2 } from "path";
337
- import { homedir } from "os";
338
-
339
- // src/agents/base.ts
340
- function createSkillXml(skill) {
341
- return `<skill>
342
- <name>${skill.name}</name>
343
- <description>${escapeXml(skill.description)}</description>
344
- <location>${skill.location}</location>
345
- </skill>`;
346
- }
347
- function escapeXml(text) {
348
- return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
349
- }
350
-
351
- // src/agents/claude-code.ts
352
- var ClaudeCodeAdapter = class {
353
- type = "claude-code";
354
- name = "Claude Code";
355
- skillsDir = ".claude/skills";
356
- configFile = "AGENTS.md";
357
- generateConfig(skills) {
358
- const enabledSkills = skills.filter((s) => s.enabled);
359
- if (enabledSkills.length === 0) {
360
- return "";
361
- }
362
- const skillsXml = enabledSkills.map(createSkillXml).join("\n\n");
363
- return `<skills_system priority="1">
364
-
365
- ## Available Skills
366
-
367
- <!-- SKILLS_TABLE_START -->
368
- <usage>
369
- 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.
370
-
371
- How to use skills:
372
- - Invoke: \`skillkit read <skill-name>\` or \`npx skillkit read <skill-name>\`
373
- - The skill content will load with detailed instructions on how to complete the task
374
- - Base directory provided in output for resolving bundled resources (references/, scripts/, assets/)
375
-
376
- Usage notes:
377
- - Only use skills listed in <available_skills> below
378
- - Do not invoke a skill that is already loaded in your context
379
- - Each skill invocation is stateless
380
- </usage>
381
-
382
- <available_skills>
383
-
384
- ${skillsXml}
385
-
386
- </available_skills>
387
- <!-- SKILLS_TABLE_END -->
388
-
389
- </skills_system>`;
390
- }
391
- parseConfig(content) {
392
- const skillNames = [];
393
- const skillRegex = /<name>([^<]+)<\/name>/g;
394
- let match;
395
- while ((match = skillRegex.exec(content)) !== null) {
396
- skillNames.push(match[1].trim());
397
- }
398
- return skillNames;
399
- }
400
- getInvokeCommand(skillName) {
401
- return `skillkit read ${skillName}`;
402
- }
403
- async isDetected() {
404
- const projectClaude = join2(process.cwd(), ".claude");
405
- const globalClaude = join2(homedir(), ".claude");
406
- const claudeMd = join2(process.cwd(), "CLAUDE.md");
407
- return existsSync2(projectClaude) || existsSync2(globalClaude) || existsSync2(claudeMd);
408
- }
409
- };
410
-
411
- // src/agents/cursor.ts
412
- import { existsSync as existsSync3 } from "fs";
413
- import { join as join3 } from "path";
414
- var CursorAdapter = class {
415
- type = "cursor";
416
- name = "Cursor";
417
- skillsDir = ".cursor/skills";
418
- configFile = ".cursorrules";
419
- generateConfig(skills) {
420
- const enabledSkills = skills.filter((s) => s.enabled);
421
- if (enabledSkills.length === 0) {
422
- return "";
423
- }
424
- const skillsList = enabledSkills.map((s) => `- **${s.name}**: ${s.description}`).join("\n");
425
- const skillsXml = enabledSkills.map(createSkillXml).join("\n\n");
426
- return `# Skills System
427
-
428
- You have access to specialized skills that can help complete tasks. Use the skillkit CLI to load skill instructions when needed.
429
-
430
- ## Available Skills
431
-
432
- ${skillsList}
433
-
434
- ## How to Use Skills
435
-
436
- When a task matches a skill's description, load it with:
437
- \`\`\`bash
438
- skillkit read <skill-name>
439
- \`\`\`
440
-
441
- The skill will provide detailed instructions for completing the task.
442
-
443
- <!-- SKILLS_DATA_START -->
444
- ${skillsXml}
445
- <!-- SKILLS_DATA_END -->
446
- `;
447
- }
448
- parseConfig(content) {
449
- const skillNames = [];
450
- const skillRegex = /<name>([^<]+)<\/name>/g;
451
- let match;
452
- while ((match = skillRegex.exec(content)) !== null) {
453
- skillNames.push(match[1].trim());
454
- }
455
- return skillNames;
456
- }
457
- getInvokeCommand(skillName) {
458
- return `skillkit read ${skillName}`;
459
- }
460
- async isDetected() {
461
- const cursorRules = join3(process.cwd(), ".cursorrules");
462
- const cursorDir = join3(process.cwd(), ".cursor");
463
- return existsSync3(cursorRules) || existsSync3(cursorDir);
464
- }
465
- };
466
-
467
- // src/agents/codex.ts
468
- import { existsSync as existsSync4 } from "fs";
469
- import { join as join4 } from "path";
470
- import { homedir as homedir2 } from "os";
471
- var CodexAdapter = class {
472
- type = "codex";
473
- name = "OpenAI Codex CLI";
474
- skillsDir = ".codex/skills";
475
- configFile = "AGENTS.md";
476
- generateConfig(skills) {
477
- const enabledSkills = skills.filter((s) => s.enabled);
478
- if (enabledSkills.length === 0) {
479
- return "";
480
- }
481
- const skillsList = enabledSkills.map((s) => `| ${s.name} | ${s.description} | \`skillkit read ${s.name}\` |`).join("\n");
482
- return `# Skills
483
-
484
- You have access to specialized skills for completing complex tasks.
485
-
486
- | Skill | Description | Command |
487
- |-------|-------------|---------|
488
- ${skillsList}
489
-
490
- ## Usage
491
-
492
- When a task matches a skill's capability, run the command to load detailed instructions:
493
-
494
- \`\`\`bash
495
- skillkit read <skill-name>
496
- \`\`\`
497
-
498
- Skills are loaded on-demand to keep context clean. Only load skills when relevant to the current task.
499
- `;
500
- }
501
- parseConfig(content) {
502
- const skillNames = [];
503
- const tableRegex = /^\|\s*([a-z0-9-]+)\s*\|/gm;
504
- let match;
505
- while ((match = tableRegex.exec(content)) !== null) {
506
- const name = match[1].trim();
507
- if (name && name !== "Skill" && name !== "-------") {
508
- skillNames.push(name);
509
- }
510
- }
511
- return skillNames;
512
- }
513
- getInvokeCommand(skillName) {
514
- return `skillkit read ${skillName}`;
515
- }
516
- async isDetected() {
517
- const codexDir = join4(process.cwd(), ".codex");
518
- const globalCodex = join4(homedir2(), ".codex");
519
- return existsSync4(codexDir) || existsSync4(globalCodex);
520
- }
521
- };
522
-
523
- // src/agents/gemini-cli.ts
524
- import { existsSync as existsSync5 } from "fs";
525
- import { join as join5 } from "path";
526
- import { homedir as homedir3 } from "os";
527
- var GeminiCliAdapter = class {
528
- type = "gemini-cli";
529
- name = "Gemini CLI";
530
- skillsDir = ".gemini/skills";
531
- configFile = "GEMINI.md";
532
- generateConfig(skills) {
533
- const enabledSkills = skills.filter((s) => s.enabled);
534
- if (enabledSkills.length === 0) {
535
- return "";
536
- }
537
- const skillsJson = enabledSkills.map((s) => ({
538
- name: s.name,
539
- description: s.description,
540
- invoke: `skillkit read ${s.name}`,
541
- location: s.location
542
- }));
543
- return `# Skills Configuration
544
-
545
- You have access to specialized skills that extend your capabilities.
546
-
547
- ## Available Skills
548
-
549
- ${enabledSkills.map((s) => `### ${s.name}
550
- ${s.description}
551
-
552
- Invoke: \`skillkit read ${s.name}\``).join("\n\n")}
553
-
554
- ## Skills Data
555
-
556
- \`\`\`json
557
- ${JSON.stringify(skillsJson, null, 2)}
558
- \`\`\`
559
-
560
- ## Usage Instructions
561
-
562
- 1. When a task matches a skill's description, load it using the invoke command
563
- 2. Skills provide step-by-step instructions for complex tasks
564
- 3. Each skill is self-contained with its own resources
565
- `;
566
- }
567
- parseConfig(content) {
568
- const skillNames = [];
569
- const jsonMatch = content.match(/```json\s*([\s\S]*?)```/);
570
- if (jsonMatch) {
571
- try {
572
- const skills = JSON.parse(jsonMatch[1]);
573
- if (Array.isArray(skills)) {
574
- skills.forEach((s) => {
575
- if (s.name) skillNames.push(s.name);
576
- });
577
- }
578
- } catch {
579
- }
580
- }
581
- if (skillNames.length === 0) {
582
- const headerRegex = /^### ([a-z0-9-]+)$/gm;
583
- let match;
584
- while ((match = headerRegex.exec(content)) !== null) {
585
- skillNames.push(match[1].trim());
586
- }
587
- }
588
- return skillNames;
589
- }
590
- getInvokeCommand(skillName) {
591
- return `skillkit read ${skillName}`;
592
- }
593
- async isDetected() {
594
- const geminiMd = join5(process.cwd(), "GEMINI.md");
595
- const geminiDir = join5(process.cwd(), ".gemini");
596
- const globalGemini = join5(homedir3(), ".gemini");
597
- return existsSync5(geminiMd) || existsSync5(geminiDir) || existsSync5(globalGemini);
598
- }
599
- };
600
-
601
- // src/agents/opencode.ts
602
- import { existsSync as existsSync6 } from "fs";
603
- import { join as join6 } from "path";
604
- import { homedir as homedir4 } from "os";
605
- var OpenCodeAdapter = class {
606
- type = "opencode";
607
- name = "OpenCode";
608
- skillsDir = ".opencode/skills";
609
- configFile = "AGENTS.md";
610
- generateConfig(skills) {
611
- const enabledSkills = skills.filter((s) => s.enabled);
612
- if (enabledSkills.length === 0) {
613
- return "";
614
- }
615
- const skillsXml = enabledSkills.map(createSkillXml).join("\n\n");
616
- return `<!-- SKILLKIT_START -->
617
- # Skills
618
-
619
- The following skills are available to help complete tasks:
620
-
621
- <skills>
622
- ${skillsXml}
623
- </skills>
624
-
625
- ## How to Use
626
-
627
- When a task matches a skill's description:
628
-
629
- \`\`\`bash
630
- skillkit read <skill-name>
631
- \`\`\`
632
-
633
- This loads the skill's instructions into context.
634
-
635
- <!-- SKILLKIT_END -->`;
636
- }
637
- parseConfig(content) {
638
- const skillNames = [];
639
- const skillRegex = /<name>([^<]+)<\/name>/g;
640
- let match;
641
- while ((match = skillRegex.exec(content)) !== null) {
642
- skillNames.push(match[1].trim());
643
- }
644
- return skillNames;
645
- }
646
- getInvokeCommand(skillName) {
647
- return `skillkit read ${skillName}`;
648
- }
649
- async isDetected() {
650
- const opencodeDir = join6(process.cwd(), ".opencode");
651
- const globalOpencode = join6(homedir4(), ".opencode");
652
- return existsSync6(opencodeDir) || existsSync6(globalOpencode);
653
- }
654
- };
655
-
656
- // src/agents/antigravity.ts
657
- import { existsSync as existsSync7 } from "fs";
658
- import { join as join7 } from "path";
659
- import { homedir as homedir5 } from "os";
660
- var AntigravityAdapter = class {
661
- type = "antigravity";
662
- name = "Antigravity";
663
- skillsDir = ".antigravity/skills";
664
- configFile = "AGENTS.md";
665
- generateConfig(skills) {
666
- const enabledSkills = skills.filter((s) => s.enabled);
667
- if (enabledSkills.length === 0) {
668
- return "";
669
- }
670
- const skillsYaml = enabledSkills.map((s) => ` - name: ${s.name}
671
- description: "${s.description}"
672
- invoke: skillkit read ${s.name}`).join("\n");
673
- return `# Antigravity Skills Configuration
674
-
675
- <!-- skills:
676
- ${skillsYaml}
677
- -->
678
-
679
- ## Available Skills
680
-
681
- ${enabledSkills.map((s) => `### ${s.name}
682
-
683
- ${s.description}
684
-
685
- **Usage:** \`skillkit read ${s.name}\`
686
- `).join("\n")}
687
-
688
- ## How Skills Work
689
-
690
- 1. Skills provide specialized knowledge for specific tasks
691
- 2. Load a skill when the current task matches its description
692
- 3. Skills are loaded on-demand to preserve context window
693
- `;
694
- }
695
- parseConfig(content) {
696
- const skillNames = [];
697
- const yamlMatch = content.match(/<!-- skills:\s*([\s\S]*?)-->/);
698
- if (yamlMatch) {
699
- const nameRegex = /name:\s*([a-z0-9-]+)/g;
700
- let match;
701
- while ((match = nameRegex.exec(yamlMatch[1])) !== null) {
702
- skillNames.push(match[1].trim());
703
- }
704
- }
705
- if (skillNames.length === 0) {
706
- const headerRegex = /^### ([a-z0-9-]+)$/gm;
707
- let match;
708
- while ((match = headerRegex.exec(content)) !== null) {
709
- skillNames.push(match[1].trim());
710
- }
711
- }
712
- return skillNames;
713
- }
714
- getInvokeCommand(skillName) {
715
- return `skillkit read ${skillName}`;
716
- }
717
- async isDetected() {
718
- const agDir = join7(process.cwd(), ".antigravity");
719
- const globalAg = join7(homedir5(), ".antigravity");
720
- return existsSync7(agDir) || existsSync7(globalAg);
721
- }
722
- };
723
-
724
- // src/agents/amp.ts
725
- import { existsSync as existsSync8 } from "fs";
726
- import { join as join8 } from "path";
727
- import { homedir as homedir6 } from "os";
728
- var AmpAdapter = class {
729
- type = "amp";
730
- name = "Amp";
731
- skillsDir = ".agents/skills";
732
- configFile = "AGENTS.md";
733
- globalSkillsDir = join8(homedir6(), ".config", "agents", "skills");
734
- generateConfig(skills) {
735
- const enabledSkills = skills.filter((s) => s.enabled);
736
- if (enabledSkills.length === 0) {
737
- return "";
738
- }
739
- const skillsXml = enabledSkills.map(createSkillXml).join("\n\n");
740
- return `<skills_system priority="1">
741
-
742
- ## Available Skills
743
-
744
- <!-- SKILLS_TABLE_START -->
745
- <usage>
746
- 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.
747
-
748
- How to use skills:
749
- - Invoke: \`skillkit read <skill-name>\` or \`npx skillkit read <skill-name>\`
750
- - The skill content will load with detailed instructions on how to complete the task
751
- - Base directory provided in output for resolving bundled resources (references/, scripts/, assets/)
752
-
753
- Usage notes:
754
- - Only use skills listed in <available_skills> below
755
- - Do not invoke a skill that is already loaded in your context
756
- - Each skill invocation is stateless
757
- </usage>
758
-
759
- <available_skills>
760
-
761
- ${skillsXml}
762
-
763
- </available_skills>
764
- <!-- SKILLS_TABLE_END -->
765
-
766
- </skills_system>`;
767
- }
768
- parseConfig(content) {
769
- const skillNames = [];
770
- const skillRegex = /<name>([^<]+)<\/name>/g;
771
- let match;
772
- while ((match = skillRegex.exec(content)) !== null) {
773
- skillNames.push(match[1].trim());
774
- }
775
- return skillNames;
776
- }
777
- getInvokeCommand(skillName) {
778
- return `skillkit read ${skillName}`;
779
- }
780
- async isDetected() {
781
- const projectAgents = join8(process.cwd(), ".agents");
782
- const globalAgents = join8(homedir6(), ".config", "agents");
783
- return existsSync8(projectAgents) || existsSync8(globalAgents);
784
- }
785
- };
786
-
787
- // src/agents/clawdbot.ts
788
- import { existsSync as existsSync9 } from "fs";
789
- import { join as join9 } from "path";
790
- import { homedir as homedir7 } from "os";
791
- var ClawdbotAdapter = class {
792
- type = "clawdbot";
793
- name = "Clawdbot";
794
- skillsDir = "skills";
795
- configFile = "AGENTS.md";
796
- globalSkillsDir = join9(homedir7(), ".clawdbot", "skills");
797
- generateConfig(skills) {
798
- const enabledSkills = skills.filter((s) => s.enabled);
799
- if (enabledSkills.length === 0) {
800
- return "";
801
- }
802
- const skillsXml = enabledSkills.map(createSkillXml).join("\n\n");
803
- return `<skills_system priority="1">
804
-
805
- ## Available Skills
806
-
807
- <!-- SKILLS_TABLE_START -->
808
- <usage>
809
- 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.
810
-
811
- How to use skills:
812
- - Invoke: \`skillkit read <skill-name>\` or \`npx skillkit read <skill-name>\`
813
- - The skill content will load with detailed instructions on how to complete the task
814
- - Base directory provided in output for resolving bundled resources (references/, scripts/, assets/)
815
-
816
- Usage notes:
817
- - Only use skills listed in <available_skills> below
818
- - Do not invoke a skill that is already loaded in your context
819
- - Each skill invocation is stateless
820
- </usage>
821
-
822
- <available_skills>
823
-
824
- ${skillsXml}
825
-
826
- </available_skills>
827
- <!-- SKILLS_TABLE_END -->
828
-
829
- </skills_system>`;
830
- }
831
- parseConfig(content) {
832
- const skillNames = [];
833
- const skillRegex = /<name>([^<]+)<\/name>/g;
834
- let match;
835
- while ((match = skillRegex.exec(content)) !== null) {
836
- skillNames.push(match[1].trim());
837
- }
838
- return skillNames;
839
- }
840
- getInvokeCommand(skillName) {
841
- return `skillkit read ${skillName}`;
842
- }
843
- async isDetected() {
844
- const projectSkills = join9(process.cwd(), "skills");
845
- const globalClawdbot = join9(homedir7(), ".clawdbot");
846
- return existsSync9(globalClawdbot) || existsSync9(projectSkills) && existsSync9(join9(process.cwd(), ".clawdbot"));
847
- }
848
- };
849
-
850
- // src/agents/droid.ts
851
- import { existsSync as existsSync10 } from "fs";
852
- import { join as join10 } from "path";
853
- import { homedir as homedir8 } from "os";
854
- var DroidAdapter = class {
855
- type = "droid";
856
- name = "Droid (Factory)";
857
- skillsDir = ".factory/skills";
858
- configFile = "AGENTS.md";
859
- globalSkillsDir = join10(homedir8(), ".factory", "skills");
860
- generateConfig(skills) {
861
- const enabledSkills = skills.filter((s) => s.enabled);
862
- if (enabledSkills.length === 0) {
863
- return "";
864
- }
865
- const skillsXml = enabledSkills.map(createSkillXml).join("\n\n");
866
- return `<skills_system priority="1">
867
-
868
- ## Available Skills
869
-
870
- <!-- SKILLS_TABLE_START -->
871
- <usage>
872
- 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.
873
-
874
- How to use skills:
875
- - Invoke: \`skillkit read <skill-name>\` or \`npx skillkit read <skill-name>\`
876
- - The skill content will load with detailed instructions on how to complete the task
877
- - Base directory provided in output for resolving bundled resources (references/, scripts/, assets/)
878
-
879
- Usage notes:
880
- - Only use skills listed in <available_skills> below
881
- - Do not invoke a skill that is already loaded in your context
882
- - Each skill invocation is stateless
883
- </usage>
884
-
885
- <available_skills>
886
-
887
- ${skillsXml}
888
-
889
- </available_skills>
890
- <!-- SKILLS_TABLE_END -->
891
-
892
- </skills_system>`;
893
- }
894
- parseConfig(content) {
895
- const skillNames = [];
896
- const skillRegex = /<name>([^<]+)<\/name>/g;
897
- let match;
898
- while ((match = skillRegex.exec(content)) !== null) {
899
- skillNames.push(match[1].trim());
900
- }
901
- return skillNames;
902
- }
903
- getInvokeCommand(skillName) {
904
- return `skillkit read ${skillName}`;
905
- }
906
- async isDetected() {
907
- const projectFactory = join10(process.cwd(), ".factory");
908
- const globalFactory = join10(homedir8(), ".factory");
909
- return existsSync10(projectFactory) || existsSync10(globalFactory);
910
- }
911
- };
912
-
913
- // src/agents/github-copilot.ts
914
- import { existsSync as existsSync11 } from "fs";
915
- import { join as join11 } from "path";
916
- import { homedir as homedir9 } from "os";
917
- var GitHubCopilotAdapter = class {
918
- type = "github-copilot";
919
- name = "GitHub Copilot";
920
- skillsDir = ".github/skills";
921
- configFile = "AGENTS.md";
922
- globalSkillsDir = join11(homedir9(), ".copilot", "skills");
923
- generateConfig(skills) {
924
- const enabledSkills = skills.filter((s) => s.enabled);
925
- if (enabledSkills.length === 0) {
926
- return "";
927
- }
928
- const skillsXml = enabledSkills.map(createSkillXml).join("\n\n");
929
- return `<skills_system priority="1">
930
-
931
- ## Available Skills
932
-
933
- <!-- SKILLS_TABLE_START -->
934
- <usage>
935
- 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.
936
-
937
- How to use skills:
938
- - Invoke: \`skillkit read <skill-name>\` or \`npx skillkit read <skill-name>\`
939
- - The skill content will load with detailed instructions on how to complete the task
940
- - Base directory provided in output for resolving bundled resources (references/, scripts/, assets/)
941
-
942
- Usage notes:
943
- - Only use skills listed in <available_skills> below
944
- - Do not invoke a skill that is already loaded in your context
945
- - Each skill invocation is stateless
946
- </usage>
947
-
948
- <available_skills>
949
-
950
- ${skillsXml}
951
-
952
- </available_skills>
953
- <!-- SKILLS_TABLE_END -->
954
-
955
- </skills_system>`;
956
- }
957
- parseConfig(content) {
958
- const skillNames = [];
959
- const skillRegex = /<name>([^<]+)<\/name>/g;
960
- let match;
961
- while ((match = skillRegex.exec(content)) !== null) {
962
- skillNames.push(match[1].trim());
963
- }
964
- return skillNames;
965
- }
966
- getInvokeCommand(skillName) {
967
- return `skillkit read ${skillName}`;
968
- }
969
- async isDetected() {
970
- const projectGithub = join11(process.cwd(), ".github", "skills");
971
- const globalCopilot = join11(homedir9(), ".copilot");
972
- return existsSync11(projectGithub) || existsSync11(globalCopilot);
973
- }
974
- };
975
-
976
- // src/agents/goose.ts
977
- import { existsSync as existsSync12 } from "fs";
978
- import { join as join12 } from "path";
979
- import { homedir as homedir10 } from "os";
980
- var GooseAdapter = class {
981
- type = "goose";
982
- name = "Goose";
983
- skillsDir = ".goose/skills";
984
- configFile = "AGENTS.md";
985
- globalSkillsDir = join12(homedir10(), ".config", "goose", "skills");
986
- generateConfig(skills) {
987
- const enabledSkills = skills.filter((s) => s.enabled);
988
- if (enabledSkills.length === 0) {
989
- return "";
990
- }
991
- const skillsXml = enabledSkills.map(createSkillXml).join("\n\n");
992
- return `<skills_system priority="1">
993
-
994
- ## Available Skills
995
-
996
- <!-- SKILLS_TABLE_START -->
997
- <usage>
998
- 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.
999
-
1000
- How to use skills:
1001
- - Invoke: \`skillkit read <skill-name>\` or \`npx skillkit read <skill-name>\`
1002
- - The skill content will load with detailed instructions on how to complete the task
1003
- - Base directory provided in output for resolving bundled resources (references/, scripts/, assets/)
1004
-
1005
- Usage notes:
1006
- - Only use skills listed in <available_skills> below
1007
- - Do not invoke a skill that is already loaded in your context
1008
- - Each skill invocation is stateless
1009
- </usage>
1010
-
1011
- <available_skills>
1012
-
1013
- ${skillsXml}
1014
-
1015
- </available_skills>
1016
- <!-- SKILLS_TABLE_END -->
1017
-
1018
- </skills_system>`;
1019
- }
1020
- parseConfig(content) {
1021
- const skillNames = [];
1022
- const skillRegex = /<name>([^<]+)<\/name>/g;
1023
- let match;
1024
- while ((match = skillRegex.exec(content)) !== null) {
1025
- skillNames.push(match[1].trim());
1026
- }
1027
- return skillNames;
1028
- }
1029
- getInvokeCommand(skillName) {
1030
- return `skillkit read ${skillName}`;
1031
- }
1032
- async isDetected() {
1033
- const projectGoose = join12(process.cwd(), ".goose");
1034
- const globalGoose = join12(homedir10(), ".config", "goose");
1035
- return existsSync12(projectGoose) || existsSync12(globalGoose);
1036
- }
1037
- };
1038
-
1039
- // src/agents/kilo.ts
1040
- import { existsSync as existsSync13 } from "fs";
1041
- import { join as join13 } from "path";
1042
- import { homedir as homedir11 } from "os";
1043
- var KiloAdapter = class {
1044
- type = "kilo";
1045
- name = "Kilo Code";
1046
- skillsDir = ".kilocode/skills";
1047
- configFile = "AGENTS.md";
1048
- globalSkillsDir = join13(homedir11(), ".kilocode", "skills");
1049
- generateConfig(skills) {
1050
- const enabledSkills = skills.filter((s) => s.enabled);
1051
- if (enabledSkills.length === 0) {
1052
- return "";
1053
- }
1054
- const skillsXml = enabledSkills.map(createSkillXml).join("\n\n");
1055
- return `<skills_system priority="1">
1056
-
1057
- ## Available Skills
1058
-
1059
- <!-- SKILLS_TABLE_START -->
1060
- <usage>
1061
- 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.
1062
-
1063
- How to use skills:
1064
- - Invoke: \`skillkit read <skill-name>\` or \`npx skillkit read <skill-name>\`
1065
- - The skill content will load with detailed instructions on how to complete the task
1066
- - Base directory provided in output for resolving bundled resources (references/, scripts/, assets/)
1067
-
1068
- Usage notes:
1069
- - Only use skills listed in <available_skills> below
1070
- - Do not invoke a skill that is already loaded in your context
1071
- - Each skill invocation is stateless
1072
- </usage>
1073
-
1074
- <available_skills>
1075
-
1076
- ${skillsXml}
1077
-
1078
- </available_skills>
1079
- <!-- SKILLS_TABLE_END -->
1080
-
1081
- </skills_system>`;
1082
- }
1083
- parseConfig(content) {
1084
- const skillNames = [];
1085
- const skillRegex = /<name>([^<]+)<\/name>/g;
1086
- let match;
1087
- while ((match = skillRegex.exec(content)) !== null) {
1088
- skillNames.push(match[1].trim());
1089
- }
1090
- return skillNames;
1091
- }
1092
- getInvokeCommand(skillName) {
1093
- return `skillkit read ${skillName}`;
1094
- }
1095
- async isDetected() {
1096
- const projectKilo = join13(process.cwd(), ".kilocode");
1097
- const globalKilo = join13(homedir11(), ".kilocode");
1098
- return existsSync13(projectKilo) || existsSync13(globalKilo);
1099
- }
1100
- };
1101
-
1102
- // src/agents/kiro-cli.ts
1103
- import { existsSync as existsSync14 } from "fs";
1104
- import { join as join14 } from "path";
1105
- import { homedir as homedir12 } from "os";
1106
- var KiroCliAdapter = class {
1107
- type = "kiro-cli";
1108
- name = "Kiro CLI";
1109
- skillsDir = ".kiro/skills";
1110
- configFile = "AGENTS.md";
1111
- globalSkillsDir = join14(homedir12(), ".kiro", "skills");
1112
- generateConfig(skills) {
1113
- const enabledSkills = skills.filter((s) => s.enabled);
1114
- if (enabledSkills.length === 0) {
1115
- return "";
1116
- }
1117
- const skillsXml = enabledSkills.map(createSkillXml).join("\n\n");
1118
- return `<skills_system priority="1">
1119
-
1120
- ## Available Skills
1121
-
1122
- <!-- SKILLS_TABLE_START -->
1123
- <usage>
1124
- 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.
1125
-
1126
- How to use skills:
1127
- - Invoke: \`skillkit read <skill-name>\` or \`npx skillkit read <skill-name>\`
1128
- - The skill content will load with detailed instructions on how to complete the task
1129
- - Base directory provided in output for resolving bundled resources (references/, scripts/, assets/)
1130
-
1131
- Usage notes:
1132
- - Only use skills listed in <available_skills> below
1133
- - Do not invoke a skill that is already loaded in your context
1134
- - Each skill invocation is stateless
1135
- </usage>
1136
-
1137
- <available_skills>
1138
-
1139
- ${skillsXml}
1140
-
1141
- </available_skills>
1142
- <!-- SKILLS_TABLE_END -->
1143
-
1144
- </skills_system>
1145
-
1146
- **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\`:
1147
-
1148
- \`\`\`json
1149
- {
1150
- "resources": [
1151
- "skill://.kiro/skills/**/SKILL.md"
1152
- ]
1153
- }
1154
- \`\`\``;
1155
- }
1156
- parseConfig(content) {
1157
- const skillNames = [];
1158
- const skillRegex = /<name>([^<]+)<\/name>/g;
1159
- let match;
1160
- while ((match = skillRegex.exec(content)) !== null) {
1161
- skillNames.push(match[1].trim());
1162
- }
1163
- return skillNames;
1164
- }
1165
- getInvokeCommand(skillName) {
1166
- return `skillkit read ${skillName}`;
1167
- }
1168
- async isDetected() {
1169
- const projectKiro = join14(process.cwd(), ".kiro");
1170
- const globalKiro = join14(homedir12(), ".kiro");
1171
- return existsSync14(projectKiro) || existsSync14(globalKiro);
1172
- }
1173
- };
1174
-
1175
- // src/agents/roo.ts
1176
- import { existsSync as existsSync15 } from "fs";
1177
- import { join as join15 } from "path";
1178
- import { homedir as homedir13 } from "os";
1179
- var RooAdapter = class {
1180
- type = "roo";
1181
- name = "Roo Code";
1182
- skillsDir = ".roo/skills";
1183
- configFile = "AGENTS.md";
1184
- globalSkillsDir = join15(homedir13(), ".roo", "skills");
1185
- generateConfig(skills) {
1186
- const enabledSkills = skills.filter((s) => s.enabled);
1187
- if (enabledSkills.length === 0) {
1188
- return "";
1189
- }
1190
- const skillsXml = enabledSkills.map(createSkillXml).join("\n\n");
1191
- return `<skills_system priority="1">
1192
-
1193
- ## Available Skills
1194
-
1195
- <!-- SKILLS_TABLE_START -->
1196
- <usage>
1197
- 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.
1198
-
1199
- How to use skills:
1200
- - Invoke: \`skillkit read <skill-name>\` or \`npx skillkit read <skill-name>\`
1201
- - The skill content will load with detailed instructions on how to complete the task
1202
- - Base directory provided in output for resolving bundled resources (references/, scripts/, assets/)
1203
-
1204
- Usage notes:
1205
- - Only use skills listed in <available_skills> below
1206
- - Do not invoke a skill that is already loaded in your context
1207
- - Each skill invocation is stateless
1208
- </usage>
1209
-
1210
- <available_skills>
1211
-
1212
- ${skillsXml}
1213
-
1214
- </available_skills>
1215
- <!-- SKILLS_TABLE_END -->
1216
-
1217
- </skills_system>`;
1218
- }
1219
- parseConfig(content) {
1220
- const skillNames = [];
1221
- const skillRegex = /<name>([^<]+)<\/name>/g;
1222
- let match;
1223
- while ((match = skillRegex.exec(content)) !== null) {
1224
- skillNames.push(match[1].trim());
1225
- }
1226
- return skillNames;
1227
- }
1228
- getInvokeCommand(skillName) {
1229
- return `skillkit read ${skillName}`;
1230
- }
1231
- async isDetected() {
1232
- const projectRoo = join15(process.cwd(), ".roo");
1233
- const globalRoo = join15(homedir13(), ".roo");
1234
- return existsSync15(projectRoo) || existsSync15(globalRoo);
1235
- }
1236
- };
1237
-
1238
- // src/agents/trae.ts
1239
- import { existsSync as existsSync16 } from "fs";
1240
- import { join as join16 } from "path";
1241
- import { homedir as homedir14 } from "os";
1242
- var TraeAdapter = class {
1243
- type = "trae";
1244
- name = "Trae";
1245
- skillsDir = ".trae/skills";
1246
- configFile = "AGENTS.md";
1247
- globalSkillsDir = join16(homedir14(), ".trae", "skills");
1248
- generateConfig(skills) {
1249
- const enabledSkills = skills.filter((s) => s.enabled);
1250
- if (enabledSkills.length === 0) {
1251
- return "";
1252
- }
1253
- const skillsXml = enabledSkills.map(createSkillXml).join("\n\n");
1254
- return `<skills_system priority="1">
1255
-
1256
- ## Available Skills
1257
-
1258
- <!-- SKILLS_TABLE_START -->
1259
- <usage>
1260
- 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.
1261
-
1262
- How to use skills:
1263
- - Invoke: \`skillkit read <skill-name>\` or \`npx skillkit read <skill-name>\`
1264
- - The skill content will load with detailed instructions on how to complete the task
1265
- - Base directory provided in output for resolving bundled resources (references/, scripts/, assets/)
1266
-
1267
- Usage notes:
1268
- - Only use skills listed in <available_skills> below
1269
- - Do not invoke a skill that is already loaded in your context
1270
- - Each skill invocation is stateless
1271
- </usage>
1272
-
1273
- <available_skills>
1274
-
1275
- ${skillsXml}
1276
-
1277
- </available_skills>
1278
- <!-- SKILLS_TABLE_END -->
1279
-
1280
- </skills_system>`;
1281
- }
1282
- parseConfig(content) {
1283
- const skillNames = [];
1284
- const skillRegex = /<name>([^<]+)<\/name>/g;
1285
- let match;
1286
- while ((match = skillRegex.exec(content)) !== null) {
1287
- skillNames.push(match[1].trim());
1288
- }
1289
- return skillNames;
1290
- }
1291
- getInvokeCommand(skillName) {
1292
- return `skillkit read ${skillName}`;
1293
- }
1294
- async isDetected() {
1295
- const projectTrae = join16(process.cwd(), ".trae");
1296
- const globalTrae = join16(homedir14(), ".trae");
1297
- return existsSync16(projectTrae) || existsSync16(globalTrae);
1298
- }
1299
- };
1300
-
1301
- // src/agents/windsurf.ts
1302
- import { existsSync as existsSync17 } from "fs";
1303
- import { join as join17 } from "path";
1304
- import { homedir as homedir15 } from "os";
1305
- var WindsurfAdapter = class {
1306
- type = "windsurf";
1307
- name = "Windsurf";
1308
- skillsDir = ".windsurf/skills";
1309
- configFile = "AGENTS.md";
1310
- globalSkillsDir = join17(homedir15(), ".codeium", "windsurf", "skills");
1311
- generateConfig(skills) {
1312
- const enabledSkills = skills.filter((s) => s.enabled);
1313
- if (enabledSkills.length === 0) {
1314
- return "";
1315
- }
1316
- const skillsXml = enabledSkills.map(createSkillXml).join("\n\n");
1317
- return `<skills_system priority="1">
1318
-
1319
- ## Available Skills
1320
-
1321
- <!-- SKILLS_TABLE_START -->
1322
- <usage>
1323
- 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.
1324
-
1325
- How to use skills:
1326
- - Invoke: \`skillkit read <skill-name>\` or \`npx skillkit read <skill-name>\`
1327
- - The skill content will load with detailed instructions on how to complete the task
1328
- - Base directory provided in output for resolving bundled resources (references/, scripts/, assets/)
1329
-
1330
- Usage notes:
1331
- - Only use skills listed in <available_skills> below
1332
- - Do not invoke a skill that is already loaded in your context
1333
- - Each skill invocation is stateless
1334
- </usage>
1335
-
1336
- <available_skills>
1337
-
1338
- ${skillsXml}
1339
-
1340
- </available_skills>
1341
- <!-- SKILLS_TABLE_END -->
1342
-
1343
- </skills_system>`;
1344
- }
1345
- parseConfig(content) {
1346
- const skillNames = [];
1347
- const skillRegex = /<name>([^<]+)<\/name>/g;
1348
- let match;
1349
- while ((match = skillRegex.exec(content)) !== null) {
1350
- skillNames.push(match[1].trim());
1351
- }
1352
- return skillNames;
1353
- }
1354
- getInvokeCommand(skillName) {
1355
- return `skillkit read ${skillName}`;
1356
- }
1357
- async isDetected() {
1358
- const projectWindsurf = join17(process.cwd(), ".windsurf");
1359
- const globalWindsurf = join17(homedir15(), ".codeium", "windsurf");
1360
- return existsSync17(projectWindsurf) || existsSync17(globalWindsurf);
1361
- }
1362
- };
1363
-
1364
- // src/agents/universal.ts
1365
- import { existsSync as existsSync18 } from "fs";
1366
- import { join as join18 } from "path";
1367
- var UniversalAdapter = class {
1368
- type = "universal";
1369
- name = "Universal (Any Agent)";
1370
- skillsDir = ".agent/skills";
1371
- configFile = "AGENTS.md";
1372
- generateConfig(skills) {
1373
- const enabledSkills = skills.filter((s) => s.enabled);
1374
- if (enabledSkills.length === 0) {
1375
- return "";
1376
- }
1377
- const skillsXml = enabledSkills.map(createSkillXml).join("\n\n");
1378
- const skillsList = enabledSkills.map((s) => `- **${s.name}**: ${s.description}`).join("\n");
1379
- return `# Skills System
1380
-
1381
- <!-- SKILLKIT_SKILLS_START -->
1382
-
1383
- ## Available Skills
1384
-
1385
- ${skillsList}
1386
-
1387
- ## How to Use Skills
1388
-
1389
- When a task matches one of the available skills, load it to get detailed instructions:
1390
-
1391
- \`\`\`bash
1392
- skillkit read <skill-name>
1393
- \`\`\`
1394
-
1395
- Or with npx:
1396
-
1397
- \`\`\`bash
1398
- npx skillkit read <skill-name>
1399
- \`\`\`
1400
-
1401
- ## Skills Data
1402
-
1403
- <skills_system>
1404
- <usage>
1405
- Skills provide specialized capabilities and domain knowledge.
1406
- - Invoke: \`skillkit read <skill-name>\`
1407
- - Base directory provided in output for resolving resources
1408
- - Only use skills listed below
1409
- - Each invocation is stateless
1410
- </usage>
1411
-
1412
- <available_skills>
1413
-
1414
- ${skillsXml}
1415
-
1416
- </available_skills>
1417
- </skills_system>
1418
-
1419
- <!-- SKILLKIT_SKILLS_END -->
1420
- `;
1421
- }
1422
- parseConfig(content) {
1423
- const skillNames = [];
1424
- const skillRegex = /<name>([^<]+)<\/name>/g;
1425
- let match;
1426
- while ((match = skillRegex.exec(content)) !== null) {
1427
- skillNames.push(match[1].trim());
1428
- }
1429
- if (skillNames.length === 0) {
1430
- const listRegex = /^- \*\*([a-z0-9-]+)\*\*:/gm;
1431
- while ((match = listRegex.exec(content)) !== null) {
1432
- skillNames.push(match[1].trim());
1433
- }
1434
- }
1435
- return skillNames;
1436
- }
1437
- getInvokeCommand(skillName) {
1438
- return `skillkit read ${skillName}`;
1439
- }
1440
- async isDetected() {
1441
- const agentDir = join18(process.cwd(), ".agent");
1442
- const agentsMd = join18(process.cwd(), "AGENTS.md");
1443
- return existsSync18(agentDir) || existsSync18(agentsMd);
1444
- }
1445
- };
1446
-
1447
- // src/agents/index.ts
1448
- var adapters = {
1449
- "claude-code": new ClaudeCodeAdapter(),
1450
- cursor: new CursorAdapter(),
1451
- codex: new CodexAdapter(),
1452
- "gemini-cli": new GeminiCliAdapter(),
1453
- opencode: new OpenCodeAdapter(),
1454
- antigravity: new AntigravityAdapter(),
1455
- amp: new AmpAdapter(),
1456
- clawdbot: new ClawdbotAdapter(),
1457
- droid: new DroidAdapter(),
1458
- "github-copilot": new GitHubCopilotAdapter(),
1459
- goose: new GooseAdapter(),
1460
- kilo: new KiloAdapter(),
1461
- "kiro-cli": new KiroCliAdapter(),
1462
- roo: new RooAdapter(),
1463
- trae: new TraeAdapter(),
1464
- windsurf: new WindsurfAdapter(),
1465
- universal: new UniversalAdapter()
1466
- };
1467
- function getAdapter(type) {
1468
- return adapters[type];
1469
- }
1470
- function getAllAdapters() {
1471
- return Object.values(adapters);
1472
- }
1473
- async function detectAgent() {
1474
- const checkOrder = [
1475
- "claude-code",
1476
- "cursor",
1477
- "codex",
1478
- "gemini-cli",
1479
- "opencode",
1480
- "antigravity",
1481
- "amp",
1482
- "clawdbot",
1483
- "droid",
1484
- "github-copilot",
1485
- "goose",
1486
- "kilo",
1487
- "kiro-cli",
1488
- "roo",
1489
- "trae",
1490
- "windsurf",
1491
- "universal"
1492
- ];
1493
- for (const type of checkOrder) {
1494
- const adapter = adapters[type];
1495
- if (await adapter.isDetected()) {
1496
- return type;
1497
- }
1498
- }
1499
- return "universal";
1500
- }
1501
- function getSkillsDir(type) {
1502
- return adapters[type].skillsDir;
1503
- }
1504
- function getConfigFile(type) {
1505
- return adapters[type].configFile;
1506
- }
1507
-
1508
- // src/core/config.ts
1509
- var CONFIG_FILE = "skillkit.yaml";
1510
- var METADATA_FILE = ".skillkit.json";
1511
- function getProjectConfigPath() {
1512
- return join19(process.cwd(), CONFIG_FILE);
1513
- }
1514
- function getGlobalConfigPath() {
1515
- return join19(homedir16(), ".config", "skillkit", CONFIG_FILE);
1516
- }
1517
- function loadConfig() {
1518
- const projectPath = getProjectConfigPath();
1519
- const globalPath = getGlobalConfigPath();
1520
- if (existsSync19(projectPath)) {
1521
- try {
1522
- const content = readFileSync2(projectPath, "utf-8");
1523
- const data = parseYaml2(content);
1524
- const parsed = SkillkitConfig.safeParse(data);
1525
- if (parsed.success) {
1526
- return parsed.data;
1527
- }
1528
- } catch {
1529
- }
1530
- }
1531
- if (existsSync19(globalPath)) {
1532
- try {
1533
- const content = readFileSync2(globalPath, "utf-8");
1534
- const data = parseYaml2(content);
1535
- const parsed = SkillkitConfig.safeParse(data);
1536
- if (parsed.success) {
1537
- return parsed.data;
1538
- }
1539
- } catch {
1540
- }
1541
- }
1542
- return {
1543
- version: 1,
1544
- agent: "universal",
1545
- autoSync: true
1546
- };
1547
- }
1548
- function saveConfig(config, global = false) {
1549
- const configPath = global ? getGlobalConfigPath() : getProjectConfigPath();
1550
- const dir = dirname(configPath);
1551
- if (!existsSync19(dir)) {
1552
- mkdirSync(dir, { recursive: true });
1553
- }
1554
- const content = stringifyYaml(config);
1555
- writeFileSync(configPath, content, "utf-8");
1556
- }
1557
- function getSearchDirs(agentType) {
1558
- const type = agentType || loadConfig().agent;
1559
- const adapter = getAdapter(type);
1560
- const dirs = [];
1561
- dirs.push(join19(process.cwd(), adapter.skillsDir));
1562
- dirs.push(join19(process.cwd(), ".agent", "skills"));
1563
- dirs.push(join19(homedir16(), adapter.skillsDir));
1564
- dirs.push(join19(homedir16(), ".agent", "skills"));
1565
- return dirs;
1566
- }
1567
- function getInstallDir(global = false, agentType) {
1568
- const type = agentType || loadConfig().agent;
1569
- const adapter = getAdapter(type);
1570
- if (global) {
1571
- return join19(homedir16(), adapter.skillsDir);
1572
- }
1573
- return join19(process.cwd(), adapter.skillsDir);
1574
- }
1575
- function getAgentConfigPath(agentType) {
1576
- const type = agentType || loadConfig().agent;
1577
- const adapter = getAdapter(type);
1578
- return join19(process.cwd(), adapter.configFile);
1579
- }
1580
- function saveSkillMetadata(skillPath, metadata) {
1581
- const metadataPath = join19(skillPath, METADATA_FILE);
1582
- writeFileSync(metadataPath, JSON.stringify(metadata, null, 2), "utf-8");
1583
- }
1584
- function loadSkillMetadata(skillPath) {
1585
- const metadataPath = join19(skillPath, METADATA_FILE);
1586
- if (!existsSync19(metadataPath)) {
1587
- return null;
1588
- }
1589
- try {
1590
- const content = readFileSync2(metadataPath, "utf-8");
1591
- return JSON.parse(content);
1592
- } catch {
1593
- return null;
1594
- }
1595
- }
1596
- function setSkillEnabled(skillPath, enabled) {
1597
- const metadata = loadSkillMetadata(skillPath);
1598
- if (!metadata) {
1599
- return false;
1600
- }
1601
- metadata.enabled = enabled;
1602
- metadata.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
1603
- saveSkillMetadata(skillPath, metadata);
1604
- return true;
1605
- }
1606
- async function initProject(agentType) {
1607
- const type = agentType || await detectAgent();
1608
- const adapter = getAdapter(type);
1609
- const skillsDir = join19(process.cwd(), adapter.skillsDir);
1610
- if (!existsSync19(skillsDir)) {
1611
- mkdirSync(skillsDir, { recursive: true });
1612
- }
1613
- const config = {
1614
- version: 1,
1615
- agent: type,
1616
- autoSync: true
1617
- };
1618
- saveConfig(config);
1619
- const agentConfigPath = join19(process.cwd(), adapter.configFile);
1620
- if (!existsSync19(agentConfigPath)) {
1621
- writeFileSync(agentConfigPath, `# ${adapter.name} Configuration
1622
-
1623
- `, "utf-8");
1624
- }
1625
- }
1626
-
1627
- // src/providers/github.ts
1628
- import { execSync } from "child_process";
1629
- import { existsSync as existsSync20, rmSync } from "fs";
1630
- import { join as join20, basename as basename2 } from "path";
1631
- import { tmpdir } from "os";
1632
- import { randomUUID } from "crypto";
1633
-
1634
- // src/providers/base.ts
1635
- function parseShorthand(source) {
1636
- const cleaned = source.replace(/^\/+|\/+$/g, "");
1637
- const parts = cleaned.split("/");
1638
- if (parts.length < 2) {
1639
- return null;
1640
- }
1641
- const owner = parts[0];
1642
- const repo = parts[1];
1643
- const subpath = parts.length > 2 ? parts.slice(2).join("/") : void 0;
1644
- return { owner, repo, subpath };
1645
- }
1646
- function isLocalPath(source) {
1647
- return source.startsWith("/") || source.startsWith("./") || source.startsWith("../") || source.startsWith("~/") || source.startsWith(".");
1648
- }
1649
- function isGitUrl(source) {
1650
- return source.startsWith("git@") || source.startsWith("https://") || source.startsWith("http://") || source.startsWith("ssh://");
1651
- }
1652
-
1653
- // src/providers/github.ts
1654
- var GitHubProvider = class {
1655
- type = "github";
1656
- name = "GitHub";
1657
- baseUrl = "https://github.com";
1658
- parseSource(source) {
1659
- if (source.startsWith("https://github.com/")) {
1660
- const path = source.replace("https://github.com/", "").replace(/\.git$/, "");
1661
- return parseShorthand(path);
1662
- }
1663
- if (source.startsWith("git@github.com:")) {
1664
- const path = source.replace("git@github.com:", "").replace(/\.git$/, "");
1665
- return parseShorthand(path);
1666
- }
1667
- if (!isGitUrl(source) && !source.includes(":")) {
1668
- return parseShorthand(source);
1669
- }
1670
- return null;
1671
- }
1672
- matches(source) {
1673
- return source.startsWith("https://github.com/") || source.startsWith("git@github.com:") || !isGitUrl(source) && !source.includes(":") && source.includes("/");
1674
- }
1675
- getCloneUrl(owner, repo) {
1676
- return `https://github.com/${owner}/${repo}.git`;
1677
- }
1678
- getSshUrl(owner, repo) {
1679
- return `git@github.com:${owner}/${repo}.git`;
1680
- }
1681
- async clone(source, _targetDir, options = {}) {
1682
- const parsed = this.parseSource(source);
1683
- if (!parsed) {
1684
- return { success: false, error: `Invalid GitHub source: ${source}` };
1685
- }
1686
- const { owner, repo, subpath } = parsed;
1687
- const cloneUrl = options.ssh ? this.getSshUrl(owner, repo) : this.getCloneUrl(owner, repo);
1688
- const tempDir = join20(tmpdir(), `skillkit-${randomUUID()}`);
1689
- try {
1690
- const args = ["clone"];
1691
- if (options.depth) {
1692
- args.push("--depth", String(options.depth));
1693
- }
1694
- if (options.branch) {
1695
- args.push("--branch", options.branch);
1696
- }
1697
- args.push(cloneUrl, tempDir);
1698
- execSync(`git ${args.join(" ")}`, {
1699
- stdio: ["pipe", "pipe", "pipe"],
1700
- encoding: "utf-8"
1701
- });
1702
- const searchDir = subpath ? join20(tempDir, subpath) : tempDir;
1703
- const skills = discoverSkills(searchDir);
1704
- return {
1705
- success: true,
1706
- path: searchDir,
1707
- tempRoot: tempDir,
1708
- skills: skills.map((s) => s.name),
1709
- discoveredSkills: skills.map((s) => ({
1710
- name: s.name,
1711
- dirName: basename2(s.path),
1712
- path: s.path
1713
- }))
1714
- };
1715
- } catch (error) {
1716
- if (existsSync20(tempDir)) {
1717
- rmSync(tempDir, { recursive: true, force: true });
1718
- }
1719
- const message = error instanceof Error ? error.message : String(error);
1720
- return { success: false, error: `Failed to clone: ${message}` };
1721
- }
1722
- }
1723
- };
1724
-
1725
- // src/providers/gitlab.ts
1726
- import { execSync as execSync2 } from "child_process";
1727
- import { existsSync as existsSync21, rmSync as rmSync2 } from "fs";
1728
- import { join as join21, basename as basename3 } from "path";
1729
- import { tmpdir as tmpdir2 } from "os";
1730
- import { randomUUID as randomUUID2 } from "crypto";
1731
- var GitLabProvider = class {
1732
- type = "gitlab";
1733
- name = "GitLab";
1734
- baseUrl = "https://gitlab.com";
1735
- parseSource(source) {
1736
- if (source.startsWith("https://gitlab.com/")) {
1737
- const path = source.replace("https://gitlab.com/", "").replace(/\.git$/, "");
1738
- return parseShorthand(path);
1739
- }
1740
- if (source.startsWith("git@gitlab.com:")) {
1741
- const path = source.replace("git@gitlab.com:", "").replace(/\.git$/, "");
1742
- return parseShorthand(path);
1743
- }
1744
- if (source.startsWith("gitlab:")) {
1745
- return parseShorthand(source.replace("gitlab:", ""));
1746
- }
1747
- if (source.startsWith("gitlab.com/")) {
1748
- return parseShorthand(source.replace("gitlab.com/", ""));
1749
- }
1750
- return null;
1751
- }
1752
- matches(source) {
1753
- return source.startsWith("https://gitlab.com/") || source.startsWith("git@gitlab.com:") || source.startsWith("gitlab:") || source.startsWith("gitlab.com/");
1754
- }
1755
- getCloneUrl(owner, repo) {
1756
- return `https://gitlab.com/${owner}/${repo}.git`;
1757
- }
1758
- getSshUrl(owner, repo) {
1759
- return `git@gitlab.com:${owner}/${repo}.git`;
1760
- }
1761
- async clone(source, _targetDir, options = {}) {
1762
- const parsed = this.parseSource(source);
1763
- if (!parsed) {
1764
- return { success: false, error: `Invalid GitLab source: ${source}` };
1765
- }
1766
- const { owner, repo, subpath } = parsed;
1767
- const cloneUrl = options.ssh ? this.getSshUrl(owner, repo) : this.getCloneUrl(owner, repo);
1768
- const tempDir = join21(tmpdir2(), `skillkit-${randomUUID2()}`);
1769
- try {
1770
- const args = ["clone"];
1771
- if (options.depth) {
1772
- args.push("--depth", String(options.depth));
1773
- }
1774
- if (options.branch) {
1775
- args.push("--branch", options.branch);
1776
- }
1777
- args.push(cloneUrl, tempDir);
1778
- execSync2(`git ${args.join(" ")}`, {
1779
- stdio: ["pipe", "pipe", "pipe"],
1780
- encoding: "utf-8"
1781
- });
1782
- const searchDir = subpath ? join21(tempDir, subpath) : tempDir;
1783
- const skills = discoverSkills(searchDir);
1784
- return {
1785
- success: true,
1786
- path: searchDir,
1787
- tempRoot: tempDir,
1788
- skills: skills.map((s) => s.name),
1789
- discoveredSkills: skills.map((s) => ({
1790
- name: s.name,
1791
- dirName: basename3(s.path),
1792
- path: s.path
1793
- }))
1794
- };
1795
- } catch (error) {
1796
- if (existsSync21(tempDir)) {
1797
- rmSync2(tempDir, { recursive: true, force: true });
1798
- }
1799
- const message = error instanceof Error ? error.message : String(error);
1800
- return { success: false, error: `Failed to clone: ${message}` };
1801
- }
1802
- }
1803
- };
1804
-
1805
- // src/providers/bitbucket.ts
1806
- import { execSync as execSync3 } from "child_process";
1807
- import { existsSync as existsSync22, rmSync as rmSync3 } from "fs";
1808
- import { join as join22, basename as basename4 } from "path";
1809
- import { tmpdir as tmpdir3 } from "os";
1810
- import { randomUUID as randomUUID3 } from "crypto";
1811
- var BitbucketProvider = class {
1812
- type = "bitbucket";
1813
- name = "Bitbucket";
1814
- baseUrl = "https://bitbucket.org";
1815
- parseSource(source) {
1816
- if (source.startsWith("https://bitbucket.org/")) {
1817
- const path = source.replace("https://bitbucket.org/", "").replace(/\.git$/, "");
1818
- return parseShorthand(path);
1819
- }
1820
- if (source.startsWith("git@bitbucket.org:")) {
1821
- const path = source.replace("git@bitbucket.org:", "").replace(/\.git$/, "");
1822
- return parseShorthand(path);
1823
- }
1824
- if (source.startsWith("bitbucket:")) {
1825
- return parseShorthand(source.replace("bitbucket:", ""));
1826
- }
1827
- if (source.startsWith("bitbucket.org/")) {
1828
- return parseShorthand(source.replace("bitbucket.org/", ""));
1829
- }
1830
- return null;
1831
- }
1832
- matches(source) {
1833
- return source.startsWith("https://bitbucket.org/") || source.startsWith("git@bitbucket.org:") || source.startsWith("bitbucket:") || source.startsWith("bitbucket.org/");
1834
- }
1835
- getCloneUrl(owner, repo) {
1836
- return `https://bitbucket.org/${owner}/${repo}.git`;
1837
- }
1838
- getSshUrl(owner, repo) {
1839
- return `git@bitbucket.org:${owner}/${repo}.git`;
1840
- }
1841
- async clone(source, _targetDir, options = {}) {
1842
- const parsed = this.parseSource(source);
1843
- if (!parsed) {
1844
- return { success: false, error: `Invalid Bitbucket source: ${source}` };
1845
- }
1846
- const { owner, repo, subpath } = parsed;
1847
- const cloneUrl = options.ssh ? this.getSshUrl(owner, repo) : this.getCloneUrl(owner, repo);
1848
- const tempDir = join22(tmpdir3(), `skillkit-${randomUUID3()}`);
1849
- try {
1850
- const args = ["clone"];
1851
- if (options.depth) {
1852
- args.push("--depth", String(options.depth));
1853
- }
1854
- if (options.branch) {
1855
- args.push("--branch", options.branch);
1856
- }
1857
- args.push(cloneUrl, tempDir);
1858
- execSync3(`git ${args.join(" ")}`, {
1859
- stdio: ["pipe", "pipe", "pipe"],
1860
- encoding: "utf-8"
1861
- });
1862
- const searchDir = subpath ? join22(tempDir, subpath) : tempDir;
1863
- const skills = discoverSkills(searchDir);
1864
- return {
1865
- success: true,
1866
- path: searchDir,
1867
- tempRoot: tempDir,
1868
- skills: skills.map((s) => s.name),
1869
- discoveredSkills: skills.map((s) => ({
1870
- name: s.name,
1871
- dirName: basename4(s.path),
1872
- path: s.path
1873
- }))
1874
- };
1875
- } catch (error) {
1876
- if (existsSync22(tempDir)) {
1877
- rmSync3(tempDir, { recursive: true, force: true });
1878
- }
1879
- const message = error instanceof Error ? error.message : String(error);
1880
- return { success: false, error: `Failed to clone: ${message}` };
1881
- }
1882
- }
1883
- };
1884
-
1885
- // src/providers/local.ts
1886
- import { existsSync as existsSync23, statSync, realpathSync } from "fs";
1887
- import { join as join23, resolve, basename as basename5 } from "path";
1888
- import { homedir as homedir17 } from "os";
1889
- var LocalProvider = class {
1890
- type = "local";
1891
- name = "Local Filesystem";
1892
- baseUrl = "";
1893
- parseSource(source) {
1894
- if (!isLocalPath(source)) {
1895
- return null;
1896
- }
1897
- let expandedPath = source;
1898
- if (source.startsWith("~/")) {
1899
- expandedPath = join23(homedir17(), source.slice(2));
1900
- }
1901
- const absolutePath = resolve(expandedPath);
1902
- const dirName = basename5(absolutePath);
1903
- return {
1904
- owner: "local",
1905
- repo: dirName,
1906
- subpath: absolutePath
1907
- };
1908
- }
1909
- matches(source) {
1910
- return isLocalPath(source);
1911
- }
1912
- getCloneUrl(_owner, _repo) {
1913
- return "";
1914
- }
1915
- getSshUrl(_owner, _repo) {
1916
- return "";
1917
- }
1918
- async clone(source, _targetDir, _options = {}) {
1919
- const parsed = this.parseSource(source);
1920
- if (!parsed || !parsed.subpath) {
1921
- return { success: false, error: `Invalid local path: ${source}` };
1922
- }
1923
- const sourcePath = parsed.subpath;
1924
- if (!existsSync23(sourcePath)) {
1925
- return { success: false, error: `Path does not exist: ${sourcePath}` };
1926
- }
1927
- const stats = statSync(sourcePath);
1928
- if (!stats.isDirectory()) {
1929
- return { success: false, error: `Path is not a directory: ${sourcePath}` };
1930
- }
1931
- try {
1932
- let actualPath = sourcePath;
1933
- try {
1934
- actualPath = realpathSync(sourcePath);
1935
- } catch {
1936
- }
1937
- const skills = discoverSkills(actualPath);
1938
- return {
1939
- success: true,
1940
- path: actualPath,
1941
- skills: skills.map((s) => s.name),
1942
- discoveredSkills: skills.map((s) => ({
1943
- name: s.name,
1944
- dirName: basename5(s.path),
1945
- path: s.path
1946
- }))
1947
- };
1948
- } catch (error) {
1949
- const message = error instanceof Error ? error.message : String(error);
1950
- return { success: false, error: `Failed to process local path: ${message}` };
1951
- }
1952
- }
1953
- };
1954
-
1955
- // src/providers/index.ts
1956
- var providers = [
1957
- new LocalProvider(),
1958
- new GitLabProvider(),
1959
- new BitbucketProvider(),
1960
- new GitHubProvider()
1961
- ];
1962
- function getProvider(type) {
1963
- return providers.find((p) => p.type === type);
1964
- }
1965
- function getAllProviders() {
1966
- return providers;
1967
- }
1968
- function detectProvider(source) {
1969
- return providers.find((p) => p.matches(source));
1970
- }
1971
- function parseSource(source) {
1972
- for (const provider of providers) {
1973
- if (provider.matches(source)) {
1974
- const parsed = provider.parseSource(source);
1975
- if (parsed) {
1976
- return { provider, ...parsed };
1977
- }
1978
- }
1979
- }
1980
- return null;
1981
- }
1
+ // src/index.ts
2
+ export * from "@skillkit/core";
3
+ export * from "@skillkit/agents";
4
+ import { startTUI } from "@skillkit/tui";
1982
5
  export {
1983
- AgentType,
1984
- AmpAdapter,
1985
- AntigravityAdapter,
1986
- BitbucketProvider,
1987
- ClaudeCodeAdapter,
1988
- ClawdbotAdapter,
1989
- CodexAdapter,
1990
- CursorAdapter,
1991
- DroidAdapter,
1992
- GeminiCliAdapter,
1993
- GitHubCopilotAdapter,
1994
- GitHubProvider,
1995
- GitLabProvider,
1996
- GitProvider,
1997
- GooseAdapter,
1998
- KiloAdapter,
1999
- KiroCliAdapter,
2000
- LocalProvider,
2001
- OpenCodeAdapter,
2002
- RooAdapter,
2003
- SKILL_DISCOVERY_PATHS,
2004
- Skill,
2005
- SkillFrontmatter,
2006
- SkillLocation,
2007
- SkillMetadata,
2008
- SkillkitConfig,
2009
- TraeAdapter,
2010
- UniversalAdapter,
2011
- WindsurfAdapter,
2012
- createSkillXml,
2013
- detectAgent,
2014
- detectProvider,
2015
- discoverSkills,
2016
- escapeXml,
2017
- extractField,
2018
- extractFrontmatter,
2019
- findAllSkills,
2020
- findSkill,
2021
- getAdapter,
2022
- getAgentConfigPath,
2023
- getAllAdapters,
2024
- getAllProviders,
2025
- getConfigFile,
2026
- getGlobalConfigPath,
2027
- getInstallDir,
2028
- getProjectConfigPath,
2029
- getProvider,
2030
- getSearchDirs,
2031
- getSkillsDir,
2032
- initProject,
2033
- isGitUrl,
2034
- isLocalPath,
2035
- isPathInside,
2036
- loadConfig,
2037
- loadMetadata,
2038
- loadSkillMetadata,
2039
- parseShorthand,
2040
- parseSkill,
2041
- parseSource,
2042
- readSkillContent,
2043
- saveConfig,
2044
- saveSkillMetadata,
2045
- setSkillEnabled,
2046
- validateSkill
6
+ startTUI
2047
7
  };
2048
8
  //# sourceMappingURL=index.js.map