skillkit 1.0.3 → 1.1.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
@@ -7,6 +7,16 @@ var AgentType = z.enum([
7
7
  "antigravity",
8
8
  "opencode",
9
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",
10
20
  "universal"
11
21
  ]);
12
22
  var GitProvider = z.enum(["github", "gitlab", "bitbucket", "local"]);
@@ -56,7 +66,31 @@ var SkillkitConfig = z.object({
56
66
  import { existsSync, readdirSync, readFileSync } from "fs";
57
67
  import { join, basename } from "path";
58
68
  import { parse as parseYaml } from "yaml";
59
- function discoverSkills(dir) {
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) {
60
94
  const skills = [];
61
95
  if (!existsSync(dir)) {
62
96
  return skills;
@@ -75,6 +109,68 @@ function discoverSkills(dir) {
75
109
  }
76
110
  return skills;
77
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
+ }
78
174
  function parseSkill(skillPath, location = "project") {
79
175
  const skillMdPath = join(skillPath, "SKILL.md");
80
176
  if (!existsSync(skillMdPath)) {
@@ -230,9 +326,9 @@ function isPathInside(child, parent) {
230
326
  }
231
327
 
232
328
  // src/core/config.ts
233
- import { existsSync as existsSync9, readFileSync as readFileSync2, writeFileSync, mkdirSync } from "fs";
234
- import { join as join9, dirname } from "path";
235
- import { homedir as homedir6 } from "os";
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";
236
332
  import { parse as parseYaml2, stringify as stringifyYaml } from "yaml";
237
333
 
238
334
  // src/agents/claude-code.ts
@@ -368,49 +464,701 @@ ${skillsXml}
368
464
  }
369
465
  };
370
466
 
371
- // src/agents/codex.ts
372
- import { existsSync as existsSync4 } from "fs";
373
- import { join as join4 } from "path";
374
- import { homedir as homedir2 } from "os";
375
- var CodexAdapter = class {
376
- type = "codex";
377
- name = "OpenAI Codex CLI";
378
- skillsDir = ".codex/skills";
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";
379
1110
  configFile = "AGENTS.md";
1111
+ globalSkillsDir = join14(homedir12(), ".kiro", "skills");
380
1112
  generateConfig(skills) {
381
1113
  const enabledSkills = skills.filter((s) => s.enabled);
382
1114
  if (enabledSkills.length === 0) {
383
1115
  return "";
384
1116
  }
385
- const skillsList = enabledSkills.map((s) => `| ${s.name} | ${s.description} | \`skillkit read ${s.name}\` |`).join("\n");
386
- return `# Skills
1117
+ const skillsXml = enabledSkills.map(createSkillXml).join("\n\n");
1118
+ return `<skills_system priority="1">
387
1119
 
388
- You have access to specialized skills for completing complex tasks.
1120
+ ## Available Skills
389
1121
 
390
- | Skill | Description | Command |
391
- |-------|-------------|---------|
392
- ${skillsList}
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.
393
1125
 
394
- ## Usage
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/)
395
1130
 
396
- When a task matches a skill's capability, run the command to load detailed instructions:
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>
397
1136
 
398
- \`\`\`bash
399
- skillkit read <skill-name>
400
- \`\`\`
1137
+ <available_skills>
401
1138
 
402
- Skills are loaded on-demand to keep context clean. Only load skills when relevant to the current task.
403
- `;
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
+ \`\`\``;
404
1155
  }
405
1156
  parseConfig(content) {
406
1157
  const skillNames = [];
407
- const tableRegex = /^\|\s*([a-z0-9-]+)\s*\|/gm;
1158
+ const skillRegex = /<name>([^<]+)<\/name>/g;
408
1159
  let match;
409
- while ((match = tableRegex.exec(content)) !== null) {
410
- const name = match[1].trim();
411
- if (name && name !== "Skill" && name !== "-------") {
412
- skillNames.push(name);
413
- }
1160
+ while ((match = skillRegex.exec(content)) !== null) {
1161
+ skillNames.push(match[1].trim());
414
1162
  }
415
1163
  return skillNames;
416
1164
  }
@@ -418,76 +1166,62 @@ Skills are loaded on-demand to keep context clean. Only load skills when relevan
418
1166
  return `skillkit read ${skillName}`;
419
1167
  }
420
1168
  async isDetected() {
421
- const codexDir = join4(process.cwd(), ".codex");
422
- const globalCodex = join4(homedir2(), ".codex");
423
- return existsSync4(codexDir) || existsSync4(globalCodex);
1169
+ const projectKiro = join14(process.cwd(), ".kiro");
1170
+ const globalKiro = join14(homedir12(), ".kiro");
1171
+ return existsSync14(projectKiro) || existsSync14(globalKiro);
424
1172
  }
425
1173
  };
426
1174
 
427
- // src/agents/gemini-cli.ts
428
- import { existsSync as existsSync5 } from "fs";
429
- import { join as join5 } from "path";
430
- import { homedir as homedir3 } from "os";
431
- var GeminiCliAdapter = class {
432
- type = "gemini-cli";
433
- name = "Gemini CLI";
434
- skillsDir = ".gemini/skills";
435
- configFile = "GEMINI.md";
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");
436
1185
  generateConfig(skills) {
437
1186
  const enabledSkills = skills.filter((s) => s.enabled);
438
1187
  if (enabledSkills.length === 0) {
439
1188
  return "";
440
1189
  }
441
- const skillsJson = enabledSkills.map((s) => ({
442
- name: s.name,
443
- description: s.description,
444
- invoke: `skillkit read ${s.name}`,
445
- location: s.location
446
- }));
447
- return `# Skills Configuration
448
-
449
- You have access to specialized skills that extend your capabilities.
1190
+ const skillsXml = enabledSkills.map(createSkillXml).join("\n\n");
1191
+ return `<skills_system priority="1">
450
1192
 
451
1193
  ## Available Skills
452
1194
 
453
- ${enabledSkills.map((s) => `### ${s.name}
454
- ${s.description}
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.
455
1198
 
456
- Invoke: \`skillkit read ${s.name}\``).join("\n\n")}
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/)
457
1203
 
458
- ## Skills Data
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>
459
1209
 
460
- \`\`\`json
461
- ${JSON.stringify(skillsJson, null, 2)}
462
- \`\`\`
1210
+ <available_skills>
463
1211
 
464
- ## Usage Instructions
1212
+ ${skillsXml}
465
1213
 
466
- 1. When a task matches a skill's description, load it using the invoke command
467
- 2. Skills provide step-by-step instructions for complex tasks
468
- 3. Each skill is self-contained with its own resources
469
- `;
1214
+ </available_skills>
1215
+ <!-- SKILLS_TABLE_END -->
1216
+
1217
+ </skills_system>`;
470
1218
  }
471
1219
  parseConfig(content) {
472
1220
  const skillNames = [];
473
- const jsonMatch = content.match(/```json\s*([\s\S]*?)```/);
474
- if (jsonMatch) {
475
- try {
476
- const skills = JSON.parse(jsonMatch[1]);
477
- if (Array.isArray(skills)) {
478
- skills.forEach((s) => {
479
- if (s.name) skillNames.push(s.name);
480
- });
481
- }
482
- } catch {
483
- }
484
- }
485
- if (skillNames.length === 0) {
486
- const headerRegex = /^### ([a-z0-9-]+)$/gm;
487
- let match;
488
- while ((match = headerRegex.exec(content)) !== null) {
489
- skillNames.push(match[1].trim());
490
- }
1221
+ const skillRegex = /<name>([^<]+)<\/name>/g;
1222
+ let match;
1223
+ while ((match = skillRegex.exec(content)) !== null) {
1224
+ skillNames.push(match[1].trim());
491
1225
  }
492
1226
  return skillNames;
493
1227
  }
@@ -495,48 +1229,55 @@ ${JSON.stringify(skillsJson, null, 2)}
495
1229
  return `skillkit read ${skillName}`;
496
1230
  }
497
1231
  async isDetected() {
498
- const geminiMd = join5(process.cwd(), "GEMINI.md");
499
- const geminiDir = join5(process.cwd(), ".gemini");
500
- const globalGemini = join5(homedir3(), ".gemini");
501
- return existsSync5(geminiMd) || existsSync5(geminiDir) || existsSync5(globalGemini);
1232
+ const projectRoo = join15(process.cwd(), ".roo");
1233
+ const globalRoo = join15(homedir13(), ".roo");
1234
+ return existsSync15(projectRoo) || existsSync15(globalRoo);
502
1235
  }
503
1236
  };
504
1237
 
505
- // src/agents/opencode.ts
506
- import { existsSync as existsSync6 } from "fs";
507
- import { join as join6 } from "path";
508
- import { homedir as homedir4 } from "os";
509
- var OpenCodeAdapter = class {
510
- type = "opencode";
511
- name = "OpenCode";
512
- skillsDir = ".opencode/skills";
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";
513
1246
  configFile = "AGENTS.md";
1247
+ globalSkillsDir = join16(homedir14(), ".trae", "skills");
514
1248
  generateConfig(skills) {
515
1249
  const enabledSkills = skills.filter((s) => s.enabled);
516
1250
  if (enabledSkills.length === 0) {
517
1251
  return "";
518
1252
  }
519
1253
  const skillsXml = enabledSkills.map(createSkillXml).join("\n\n");
520
- return `<!-- SKILLKIT_START -->
521
- # Skills
1254
+ return `<skills_system priority="1">
522
1255
 
523
- The following skills are available to help complete tasks:
1256
+ ## Available Skills
524
1257
 
525
- <skills>
526
- ${skillsXml}
527
- </skills>
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.
528
1261
 
529
- ## How to Use
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/)
530
1266
 
531
- When a task matches a skill's description:
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>
532
1272
 
533
- \`\`\`bash
534
- skillkit read <skill-name>
535
- \`\`\`
1273
+ <available_skills>
536
1274
 
537
- This loads the skill's instructions into context.
1275
+ ${skillsXml}
538
1276
 
539
- <!-- SKILLKIT_END -->`;
1277
+ </available_skills>
1278
+ <!-- SKILLS_TABLE_END -->
1279
+
1280
+ </skills_system>`;
540
1281
  }
541
1282
  parseConfig(content) {
542
1283
  const skillNames = [];
@@ -551,67 +1292,62 @@ This loads the skill's instructions into context.
551
1292
  return `skillkit read ${skillName}`;
552
1293
  }
553
1294
  async isDetected() {
554
- const opencodeDir = join6(process.cwd(), ".opencode");
555
- const globalOpencode = join6(homedir4(), ".opencode");
556
- return existsSync6(opencodeDir) || existsSync6(globalOpencode);
1295
+ const projectTrae = join16(process.cwd(), ".trae");
1296
+ const globalTrae = join16(homedir14(), ".trae");
1297
+ return existsSync16(projectTrae) || existsSync16(globalTrae);
557
1298
  }
558
1299
  };
559
1300
 
560
- // src/agents/antigravity.ts
561
- import { existsSync as existsSync7 } from "fs";
562
- import { join as join7 } from "path";
563
- import { homedir as homedir5 } from "os";
564
- var AntigravityAdapter = class {
565
- type = "antigravity";
566
- name = "Antigravity";
567
- skillsDir = ".antigravity/skills";
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";
568
1309
  configFile = "AGENTS.md";
1310
+ globalSkillsDir = join17(homedir15(), ".codeium", "windsurf", "skills");
569
1311
  generateConfig(skills) {
570
1312
  const enabledSkills = skills.filter((s) => s.enabled);
571
1313
  if (enabledSkills.length === 0) {
572
1314
  return "";
573
1315
  }
574
- const skillsYaml = enabledSkills.map((s) => ` - name: ${s.name}
575
- description: "${s.description}"
576
- invoke: skillkit read ${s.name}`).join("\n");
577
- return `# Antigravity Skills Configuration
578
-
579
- <!-- skills:
580
- ${skillsYaml}
581
- -->
1316
+ const skillsXml = enabledSkills.map(createSkillXml).join("\n\n");
1317
+ return `<skills_system priority="1">
582
1318
 
583
1319
  ## Available Skills
584
1320
 
585
- ${enabledSkills.map((s) => `### ${s.name}
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.
586
1324
 
587
- ${s.description}
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/)
588
1329
 
589
- **Usage:** \`skillkit read ${s.name}\`
590
- `).join("\n")}
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>
591
1335
 
592
- ## How Skills Work
1336
+ <available_skills>
593
1337
 
594
- 1. Skills provide specialized knowledge for specific tasks
595
- 2. Load a skill when the current task matches its description
596
- 3. Skills are loaded on-demand to preserve context window
597
- `;
1338
+ ${skillsXml}
1339
+
1340
+ </available_skills>
1341
+ <!-- SKILLS_TABLE_END -->
1342
+
1343
+ </skills_system>`;
598
1344
  }
599
1345
  parseConfig(content) {
600
1346
  const skillNames = [];
601
- const yamlMatch = content.match(/<!-- skills:\s*([\s\S]*?)-->/);
602
- if (yamlMatch) {
603
- const nameRegex = /name:\s*([a-z0-9-]+)/g;
604
- let match;
605
- while ((match = nameRegex.exec(yamlMatch[1])) !== null) {
606
- skillNames.push(match[1].trim());
607
- }
608
- }
609
- if (skillNames.length === 0) {
610
- const headerRegex = /^### ([a-z0-9-]+)$/gm;
611
- let match;
612
- while ((match = headerRegex.exec(content)) !== null) {
613
- skillNames.push(match[1].trim());
614
- }
1347
+ const skillRegex = /<name>([^<]+)<\/name>/g;
1348
+ let match;
1349
+ while ((match = skillRegex.exec(content)) !== null) {
1350
+ skillNames.push(match[1].trim());
615
1351
  }
616
1352
  return skillNames;
617
1353
  }
@@ -619,15 +1355,15 @@ ${s.description}
619
1355
  return `skillkit read ${skillName}`;
620
1356
  }
621
1357
  async isDetected() {
622
- const agDir = join7(process.cwd(), ".antigravity");
623
- const globalAg = join7(homedir5(), ".antigravity");
624
- return existsSync7(agDir) || existsSync7(globalAg);
1358
+ const projectWindsurf = join17(process.cwd(), ".windsurf");
1359
+ const globalWindsurf = join17(homedir15(), ".codeium", "windsurf");
1360
+ return existsSync17(projectWindsurf) || existsSync17(globalWindsurf);
625
1361
  }
626
1362
  };
627
1363
 
628
1364
  // src/agents/universal.ts
629
- import { existsSync as existsSync8 } from "fs";
630
- import { join as join8 } from "path";
1365
+ import { existsSync as existsSync18 } from "fs";
1366
+ import { join as join18 } from "path";
631
1367
  var UniversalAdapter = class {
632
1368
  type = "universal";
633
1369
  name = "Universal (Any Agent)";
@@ -702,9 +1438,9 @@ ${skillsXml}
702
1438
  return `skillkit read ${skillName}`;
703
1439
  }
704
1440
  async isDetected() {
705
- const agentDir = join8(process.cwd(), ".agent");
706
- const agentsMd = join8(process.cwd(), "AGENTS.md");
707
- return existsSync8(agentDir) || existsSync8(agentsMd);
1441
+ const agentDir = join18(process.cwd(), ".agent");
1442
+ const agentsMd = join18(process.cwd(), "AGENTS.md");
1443
+ return existsSync18(agentDir) || existsSync18(agentsMd);
708
1444
  }
709
1445
  };
710
1446
 
@@ -716,6 +1452,16 @@ var adapters = {
716
1452
  "gemini-cli": new GeminiCliAdapter(),
717
1453
  opencode: new OpenCodeAdapter(),
718
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(),
719
1465
  universal: new UniversalAdapter()
720
1466
  };
721
1467
  function getAdapter(type) {
@@ -732,6 +1478,16 @@ async function detectAgent() {
732
1478
  "gemini-cli",
733
1479
  "opencode",
734
1480
  "antigravity",
1481
+ "amp",
1482
+ "clawdbot",
1483
+ "droid",
1484
+ "github-copilot",
1485
+ "goose",
1486
+ "kilo",
1487
+ "kiro-cli",
1488
+ "roo",
1489
+ "trae",
1490
+ "windsurf",
735
1491
  "universal"
736
1492
  ];
737
1493
  for (const type of checkOrder) {
@@ -753,15 +1509,15 @@ function getConfigFile(type) {
753
1509
  var CONFIG_FILE = "skillkit.yaml";
754
1510
  var METADATA_FILE = ".skillkit.json";
755
1511
  function getProjectConfigPath() {
756
- return join9(process.cwd(), CONFIG_FILE);
1512
+ return join19(process.cwd(), CONFIG_FILE);
757
1513
  }
758
1514
  function getGlobalConfigPath() {
759
- return join9(homedir6(), ".config", "skillkit", CONFIG_FILE);
1515
+ return join19(homedir16(), ".config", "skillkit", CONFIG_FILE);
760
1516
  }
761
1517
  function loadConfig() {
762
1518
  const projectPath = getProjectConfigPath();
763
1519
  const globalPath = getGlobalConfigPath();
764
- if (existsSync9(projectPath)) {
1520
+ if (existsSync19(projectPath)) {
765
1521
  try {
766
1522
  const content = readFileSync2(projectPath, "utf-8");
767
1523
  const data = parseYaml2(content);
@@ -772,7 +1528,7 @@ function loadConfig() {
772
1528
  } catch {
773
1529
  }
774
1530
  }
775
- if (existsSync9(globalPath)) {
1531
+ if (existsSync19(globalPath)) {
776
1532
  try {
777
1533
  const content = readFileSync2(globalPath, "utf-8");
778
1534
  const data = parseYaml2(content);
@@ -792,7 +1548,7 @@ function loadConfig() {
792
1548
  function saveConfig(config, global = false) {
793
1549
  const configPath = global ? getGlobalConfigPath() : getProjectConfigPath();
794
1550
  const dir = dirname(configPath);
795
- if (!existsSync9(dir)) {
1551
+ if (!existsSync19(dir)) {
796
1552
  mkdirSync(dir, { recursive: true });
797
1553
  }
798
1554
  const content = stringifyYaml(config);
@@ -802,32 +1558,32 @@ function getSearchDirs(agentType) {
802
1558
  const type = agentType || loadConfig().agent;
803
1559
  const adapter = getAdapter(type);
804
1560
  const dirs = [];
805
- dirs.push(join9(process.cwd(), adapter.skillsDir));
806
- dirs.push(join9(process.cwd(), ".agent", "skills"));
807
- dirs.push(join9(homedir6(), adapter.skillsDir));
808
- dirs.push(join9(homedir6(), ".agent", "skills"));
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"));
809
1565
  return dirs;
810
1566
  }
811
1567
  function getInstallDir(global = false, agentType) {
812
1568
  const type = agentType || loadConfig().agent;
813
1569
  const adapter = getAdapter(type);
814
1570
  if (global) {
815
- return join9(homedir6(), adapter.skillsDir);
1571
+ return join19(homedir16(), adapter.skillsDir);
816
1572
  }
817
- return join9(process.cwd(), adapter.skillsDir);
1573
+ return join19(process.cwd(), adapter.skillsDir);
818
1574
  }
819
1575
  function getAgentConfigPath(agentType) {
820
1576
  const type = agentType || loadConfig().agent;
821
1577
  const adapter = getAdapter(type);
822
- return join9(process.cwd(), adapter.configFile);
1578
+ return join19(process.cwd(), adapter.configFile);
823
1579
  }
824
1580
  function saveSkillMetadata(skillPath, metadata) {
825
- const metadataPath = join9(skillPath, METADATA_FILE);
1581
+ const metadataPath = join19(skillPath, METADATA_FILE);
826
1582
  writeFileSync(metadataPath, JSON.stringify(metadata, null, 2), "utf-8");
827
1583
  }
828
1584
  function loadSkillMetadata(skillPath) {
829
- const metadataPath = join9(skillPath, METADATA_FILE);
830
- if (!existsSync9(metadataPath)) {
1585
+ const metadataPath = join19(skillPath, METADATA_FILE);
1586
+ if (!existsSync19(metadataPath)) {
831
1587
  return null;
832
1588
  }
833
1589
  try {
@@ -850,8 +1606,8 @@ function setSkillEnabled(skillPath, enabled) {
850
1606
  async function initProject(agentType) {
851
1607
  const type = agentType || await detectAgent();
852
1608
  const adapter = getAdapter(type);
853
- const skillsDir = join9(process.cwd(), adapter.skillsDir);
854
- if (!existsSync9(skillsDir)) {
1609
+ const skillsDir = join19(process.cwd(), adapter.skillsDir);
1610
+ if (!existsSync19(skillsDir)) {
855
1611
  mkdirSync(skillsDir, { recursive: true });
856
1612
  }
857
1613
  const config = {
@@ -860,8 +1616,8 @@ async function initProject(agentType) {
860
1616
  autoSync: true
861
1617
  };
862
1618
  saveConfig(config);
863
- const agentConfigPath = join9(process.cwd(), adapter.configFile);
864
- if (!existsSync9(agentConfigPath)) {
1619
+ const agentConfigPath = join19(process.cwd(), adapter.configFile);
1620
+ if (!existsSync19(agentConfigPath)) {
865
1621
  writeFileSync(agentConfigPath, `# ${adapter.name} Configuration
866
1622
 
867
1623
  `, "utf-8");
@@ -870,8 +1626,8 @@ async function initProject(agentType) {
870
1626
 
871
1627
  // src/providers/github.ts
872
1628
  import { execSync } from "child_process";
873
- import { existsSync as existsSync10, rmSync } from "fs";
874
- import { join as join10, basename as basename2 } from "path";
1629
+ import { existsSync as existsSync20, rmSync } from "fs";
1630
+ import { join as join20, basename as basename2 } from "path";
875
1631
  import { tmpdir } from "os";
876
1632
  import { randomUUID } from "crypto";
877
1633
 
@@ -929,7 +1685,7 @@ var GitHubProvider = class {
929
1685
  }
930
1686
  const { owner, repo, subpath } = parsed;
931
1687
  const cloneUrl = options.ssh ? this.getSshUrl(owner, repo) : this.getCloneUrl(owner, repo);
932
- const tempDir = join10(tmpdir(), `skillkit-${randomUUID()}`);
1688
+ const tempDir = join20(tmpdir(), `skillkit-${randomUUID()}`);
933
1689
  try {
934
1690
  const args = ["clone"];
935
1691
  if (options.depth) {
@@ -943,7 +1699,7 @@ var GitHubProvider = class {
943
1699
  stdio: ["pipe", "pipe", "pipe"],
944
1700
  encoding: "utf-8"
945
1701
  });
946
- const searchDir = subpath ? join10(tempDir, subpath) : tempDir;
1702
+ const searchDir = subpath ? join20(tempDir, subpath) : tempDir;
947
1703
  const skills = discoverSkills(searchDir);
948
1704
  return {
949
1705
  success: true,
@@ -957,7 +1713,7 @@ var GitHubProvider = class {
957
1713
  }))
958
1714
  };
959
1715
  } catch (error) {
960
- if (existsSync10(tempDir)) {
1716
+ if (existsSync20(tempDir)) {
961
1717
  rmSync(tempDir, { recursive: true, force: true });
962
1718
  }
963
1719
  const message = error instanceof Error ? error.message : String(error);
@@ -968,8 +1724,8 @@ var GitHubProvider = class {
968
1724
 
969
1725
  // src/providers/gitlab.ts
970
1726
  import { execSync as execSync2 } from "child_process";
971
- import { existsSync as existsSync11, rmSync as rmSync2 } from "fs";
972
- import { join as join11, basename as basename3 } from "path";
1727
+ import { existsSync as existsSync21, rmSync as rmSync2 } from "fs";
1728
+ import { join as join21, basename as basename3 } from "path";
973
1729
  import { tmpdir as tmpdir2 } from "os";
974
1730
  import { randomUUID as randomUUID2 } from "crypto";
975
1731
  var GitLabProvider = class {
@@ -1009,7 +1765,7 @@ var GitLabProvider = class {
1009
1765
  }
1010
1766
  const { owner, repo, subpath } = parsed;
1011
1767
  const cloneUrl = options.ssh ? this.getSshUrl(owner, repo) : this.getCloneUrl(owner, repo);
1012
- const tempDir = join11(tmpdir2(), `skillkit-${randomUUID2()}`);
1768
+ const tempDir = join21(tmpdir2(), `skillkit-${randomUUID2()}`);
1013
1769
  try {
1014
1770
  const args = ["clone"];
1015
1771
  if (options.depth) {
@@ -1023,7 +1779,7 @@ var GitLabProvider = class {
1023
1779
  stdio: ["pipe", "pipe", "pipe"],
1024
1780
  encoding: "utf-8"
1025
1781
  });
1026
- const searchDir = subpath ? join11(tempDir, subpath) : tempDir;
1782
+ const searchDir = subpath ? join21(tempDir, subpath) : tempDir;
1027
1783
  const skills = discoverSkills(searchDir);
1028
1784
  return {
1029
1785
  success: true,
@@ -1037,7 +1793,7 @@ var GitLabProvider = class {
1037
1793
  }))
1038
1794
  };
1039
1795
  } catch (error) {
1040
- if (existsSync11(tempDir)) {
1796
+ if (existsSync21(tempDir)) {
1041
1797
  rmSync2(tempDir, { recursive: true, force: true });
1042
1798
  }
1043
1799
  const message = error instanceof Error ? error.message : String(error);
@@ -1048,8 +1804,8 @@ var GitLabProvider = class {
1048
1804
 
1049
1805
  // src/providers/bitbucket.ts
1050
1806
  import { execSync as execSync3 } from "child_process";
1051
- import { existsSync as existsSync12, rmSync as rmSync3 } from "fs";
1052
- import { join as join12, basename as basename4 } from "path";
1807
+ import { existsSync as existsSync22, rmSync as rmSync3 } from "fs";
1808
+ import { join as join22, basename as basename4 } from "path";
1053
1809
  import { tmpdir as tmpdir3 } from "os";
1054
1810
  import { randomUUID as randomUUID3 } from "crypto";
1055
1811
  var BitbucketProvider = class {
@@ -1089,7 +1845,7 @@ var BitbucketProvider = class {
1089
1845
  }
1090
1846
  const { owner, repo, subpath } = parsed;
1091
1847
  const cloneUrl = options.ssh ? this.getSshUrl(owner, repo) : this.getCloneUrl(owner, repo);
1092
- const tempDir = join12(tmpdir3(), `skillkit-${randomUUID3()}`);
1848
+ const tempDir = join22(tmpdir3(), `skillkit-${randomUUID3()}`);
1093
1849
  try {
1094
1850
  const args = ["clone"];
1095
1851
  if (options.depth) {
@@ -1103,7 +1859,7 @@ var BitbucketProvider = class {
1103
1859
  stdio: ["pipe", "pipe", "pipe"],
1104
1860
  encoding: "utf-8"
1105
1861
  });
1106
- const searchDir = subpath ? join12(tempDir, subpath) : tempDir;
1862
+ const searchDir = subpath ? join22(tempDir, subpath) : tempDir;
1107
1863
  const skills = discoverSkills(searchDir);
1108
1864
  return {
1109
1865
  success: true,
@@ -1117,7 +1873,7 @@ var BitbucketProvider = class {
1117
1873
  }))
1118
1874
  };
1119
1875
  } catch (error) {
1120
- if (existsSync12(tempDir)) {
1876
+ if (existsSync22(tempDir)) {
1121
1877
  rmSync3(tempDir, { recursive: true, force: true });
1122
1878
  }
1123
1879
  const message = error instanceof Error ? error.message : String(error);
@@ -1127,9 +1883,9 @@ var BitbucketProvider = class {
1127
1883
  };
1128
1884
 
1129
1885
  // src/providers/local.ts
1130
- import { existsSync as existsSync13, statSync, realpathSync } from "fs";
1131
- import { join as join13, resolve, basename as basename5 } from "path";
1132
- import { homedir as homedir7 } from "os";
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";
1133
1889
  var LocalProvider = class {
1134
1890
  type = "local";
1135
1891
  name = "Local Filesystem";
@@ -1140,7 +1896,7 @@ var LocalProvider = class {
1140
1896
  }
1141
1897
  let expandedPath = source;
1142
1898
  if (source.startsWith("~/")) {
1143
- expandedPath = join13(homedir7(), source.slice(2));
1899
+ expandedPath = join23(homedir17(), source.slice(2));
1144
1900
  }
1145
1901
  const absolutePath = resolve(expandedPath);
1146
1902
  const dirName = basename5(absolutePath);
@@ -1165,7 +1921,7 @@ var LocalProvider = class {
1165
1921
  return { success: false, error: `Invalid local path: ${source}` };
1166
1922
  }
1167
1923
  const sourcePath = parsed.subpath;
1168
- if (!existsSync13(sourcePath)) {
1924
+ if (!existsSync23(sourcePath)) {
1169
1925
  return { success: false, error: `Path does not exist: ${sourcePath}` };
1170
1926
  }
1171
1927
  const stats = statSync(sourcePath);
@@ -1182,7 +1938,12 @@ var LocalProvider = class {
1182
1938
  return {
1183
1939
  success: true,
1184
1940
  path: actualPath,
1185
- skills: skills.map((s) => s.name)
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
+ }))
1186
1947
  };
1187
1948
  } catch (error) {
1188
1949
  const message = error instanceof Error ? error.message : String(error);
@@ -1220,23 +1981,34 @@ function parseSource(source) {
1220
1981
  }
1221
1982
  export {
1222
1983
  AgentType,
1984
+ AmpAdapter,
1223
1985
  AntigravityAdapter,
1224
1986
  BitbucketProvider,
1225
1987
  ClaudeCodeAdapter,
1988
+ ClawdbotAdapter,
1226
1989
  CodexAdapter,
1227
1990
  CursorAdapter,
1991
+ DroidAdapter,
1228
1992
  GeminiCliAdapter,
1993
+ GitHubCopilotAdapter,
1229
1994
  GitHubProvider,
1230
1995
  GitLabProvider,
1231
1996
  GitProvider,
1997
+ GooseAdapter,
1998
+ KiloAdapter,
1999
+ KiroCliAdapter,
1232
2000
  LocalProvider,
1233
2001
  OpenCodeAdapter,
2002
+ RooAdapter,
2003
+ SKILL_DISCOVERY_PATHS,
1234
2004
  Skill,
1235
2005
  SkillFrontmatter,
1236
2006
  SkillLocation,
1237
2007
  SkillMetadata,
1238
2008
  SkillkitConfig,
2009
+ TraeAdapter,
1239
2010
  UniversalAdapter,
2011
+ WindsurfAdapter,
1240
2012
  createSkillXml,
1241
2013
  detectAgent,
1242
2014
  detectProvider,