opencode-swarm-plugin 0.12.23 → 0.12.24

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.
Files changed (2) hide show
  1. package/bin/swarm.ts +98 -2
  2. package/package.json +1 -1
package/bin/swarm.ts CHANGED
@@ -623,6 +623,66 @@ async function doctor() {
623
623
  const requiredMissing = required.filter((r) => !r.available);
624
624
  const optionalMissing = optional.filter((r) => !r.available);
625
625
 
626
+ // Check skills
627
+ p.log.step("Skills:");
628
+ const configDir = join(homedir(), ".config", "opencode");
629
+ const globalSkillsPath = join(configDir, "skills");
630
+ const bundledSkillsPath = join(__dirname, "..", "global-skills");
631
+
632
+ // Global skills directory
633
+ if (existsSync(globalSkillsPath)) {
634
+ try {
635
+ const { readdirSync } = require("fs");
636
+ const skills = readdirSync(globalSkillsPath, { withFileTypes: true })
637
+ .filter((d: { isDirectory: () => boolean }) => d.isDirectory())
638
+ .map((d: { name: string }) => d.name);
639
+ if (skills.length > 0) {
640
+ p.log.success(`Global skills (${skills.length}): ${skills.join(", ")}`);
641
+ } else {
642
+ p.log.warn("Global skills directory exists but is empty");
643
+ }
644
+ } catch {
645
+ p.log.warn("Global skills directory: " + globalSkillsPath);
646
+ }
647
+ } else {
648
+ p.log.warn("No global skills directory (run 'swarm setup' to create)");
649
+ }
650
+
651
+ // Bundled skills
652
+ if (existsSync(bundledSkillsPath)) {
653
+ try {
654
+ const { readdirSync } = require("fs");
655
+ const bundled = readdirSync(bundledSkillsPath, { withFileTypes: true })
656
+ .filter((d: { isDirectory: () => boolean }) => d.isDirectory())
657
+ .map((d: { name: string }) => d.name);
658
+ p.log.success(
659
+ `Bundled skills (${bundled.length}): ${bundled.join(", ")}`,
660
+ );
661
+ } catch {
662
+ p.log.warn("Could not read bundled skills");
663
+ }
664
+ }
665
+
666
+ // Project skills (check current directory)
667
+ const projectSkillsDirs = [".opencode/skills", ".claude/skills", "skills"];
668
+ for (const dir of projectSkillsDirs) {
669
+ if (existsSync(dir)) {
670
+ try {
671
+ const { readdirSync } = require("fs");
672
+ const skills = readdirSync(dir, { withFileTypes: true })
673
+ .filter((d: { isDirectory: () => boolean }) => d.isDirectory())
674
+ .map((d: { name: string }) => d.name);
675
+ if (skills.length > 0) {
676
+ p.log.success(
677
+ `Project skills in ${dir}/ (${skills.length}): ${skills.join(", ")}`,
678
+ );
679
+ }
680
+ } catch {
681
+ // Ignore
682
+ }
683
+ }
684
+ }
685
+
626
686
  if (requiredMissing.length > 0) {
627
687
  p.outro(
628
688
  "Missing " +
@@ -977,7 +1037,8 @@ async function setup() {
977
1037
  p.log.step("Setting up OpenCode integration...");
978
1038
 
979
1039
  // Create directories if needed
980
- for (const dir of [pluginDir, commandDir, agentDir]) {
1040
+ const skillsDir = join(configDir, "skills");
1041
+ for (const dir of [pluginDir, commandDir, agentDir, skillsDir]) {
981
1042
  if (!existsSync(dir)) {
982
1043
  mkdirSync(dir, { recursive: true });
983
1044
  }
@@ -995,8 +1056,24 @@ async function setup() {
995
1056
  writeFileSync(workerAgentPath, getWorkerAgent(workerModel as string));
996
1057
  p.log.success("Worker agent: " + workerAgentPath);
997
1058
 
1059
+ p.log.success("Skills directory: " + skillsDir);
1060
+
1061
+ // Show bundled skills info
1062
+ const bundledSkillsPath = join(__dirname, "..", "global-skills");
1063
+ if (existsSync(bundledSkillsPath)) {
1064
+ try {
1065
+ const { readdirSync } = require("fs");
1066
+ const bundled = readdirSync(bundledSkillsPath, { withFileTypes: true })
1067
+ .filter((d: { isDirectory: () => boolean }) => d.isDirectory())
1068
+ .map((d: { name: string }) => d.name);
1069
+ p.log.message(dim(" Bundled skills: " + bundled.join(", ")));
1070
+ } catch {
1071
+ // Ignore
1072
+ }
1073
+ }
1074
+
998
1075
  p.note(
999
- 'cd your-project\nbd init\nopencode\n/swarm "your task"',
1076
+ 'cd your-project\nbd init\nopencode\n/swarm "your task"\n\nSkills: Use skills_list to see available skills',
1000
1077
  "Next steps",
1001
1078
  );
1002
1079
 
@@ -1078,6 +1155,25 @@ async function init() {
1078
1155
  }
1079
1156
  }
1080
1157
 
1158
+ // Offer to create project skills directory
1159
+ const createSkillsDir = await p.confirm({
1160
+ message: "Create project skills directory (.opencode/skills/)?",
1161
+ initialValue: false,
1162
+ });
1163
+
1164
+ if (!p.isCancel(createSkillsDir) && createSkillsDir) {
1165
+ const skillsPath = ".opencode/skills";
1166
+ if (!existsSync(skillsPath)) {
1167
+ mkdirSync(skillsPath, { recursive: true });
1168
+ p.log.success("Created " + skillsPath + "/");
1169
+ p.log.message(
1170
+ dim(" Add SKILL.md files here for project-specific skills"),
1171
+ );
1172
+ } else {
1173
+ p.log.warn(skillsPath + "/ already exists");
1174
+ }
1175
+ }
1176
+
1081
1177
  p.outro("Project initialized! Use '/swarm' in OpenCode to get started.");
1082
1178
  } else {
1083
1179
  s.stop("Failed to initialize beads");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm-plugin",
3
- "version": "0.12.23",
3
+ "version": "0.12.24",
4
4
  "description": "Multi-agent swarm coordination for OpenCode with learning capabilities, beads integration, and Agent Mail",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",