@orchestra-research/ai-research-skills 1.0.3 → 1.1.3

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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @orchestra-research/ai-research-skills
2
2
 
3
- Install AI research engineering skills to your coding agents (Claude Code, Cursor, Gemini CLI, and more).
3
+ Install AI research engineering skills to your coding agents (Claude Code, OpenCode, Cursor, Gemini CLI, and more).
4
4
 
5
5
  ```bash
6
6
  npx @orchestra-research/ai-research-skills
@@ -12,7 +12,7 @@ npx @orchestra-research/ai-research-skills
12
12
  - **Auto-detects** installed coding agents
13
13
  - **Interactive installer** with guided experience
14
14
  - **One canonical copy** with symlinks to all agents
15
- - **Works with 7 agents**: Claude Code, Cursor, Codex, Windsurf, Gemini CLI, Kilo Code, Qwen Code
15
+ - **Works with 6 agents**: Claude Code, OpenCode, Cursor, Codex, Gemini CLI, Qwen Code
16
16
 
17
17
  ## Quick Start
18
18
 
@@ -85,11 +85,10 @@ npx @orchestra-research/ai-research-skills update
85
85
  | Agent | Config Directory |
86
86
  |-------|-----------------|
87
87
  | Claude Code | `~/.claude` |
88
+ | OpenCode | `~/.config/opencode` |
88
89
  | Cursor | `~/.cursor` |
89
90
  | Codex (OpenAI) | `~/.codex` |
90
- | Windsurf | `~/.windsurf` |
91
91
  | Gemini CLI | `~/.gemini` |
92
- | Kilo Code | `~/.kilocode` |
93
92
  | Qwen Code | `~/.qwen` |
94
93
 
95
94
  ## License
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@orchestra-research/ai-research-skills",
3
- "version": "1.0.3",
4
- "description": "Install AI research engineering skills to your coding agents (Claude Code, Cursor, Gemini CLI, and more)",
3
+ "version": "1.1.3",
4
+ "description": "Install AI research engineering skills to your coding agents (Claude Code, OpenCode, Cursor, Gemini CLI, and more)",
5
5
  "main": "src/index.js",
6
6
  "bin": {
7
7
  "ai-research-skills": "./bin/cli.js"
@@ -16,6 +16,7 @@
16
16
  "research",
17
17
  "skills",
18
18
  "claude",
19
+ "opencode",
19
20
  "cursor",
20
21
  "gemini",
21
22
  "codex",
@@ -29,11 +30,11 @@
29
30
  "license": "MIT",
30
31
  "repository": {
31
32
  "type": "git",
32
- "url": "https://github.com/orchestra-research/ai-research-skills.git"
33
+ "url": "https://github.com/Orchestra-Research/AI-research-SKILLs.git"
33
34
  },
34
- "homepage": "https://github.com/orchestra-research/ai-research-skills",
35
+ "homepage": "https://github.com/Orchestra-Research/AI-research-SKILLs",
35
36
  "bugs": {
36
- "url": "https://github.com/orchestra-research/ai-research-skills/issues"
37
+ "url": "https://github.com/Orchestra-Research/AI-research-SKILLs/issues"
37
38
  },
38
39
  "engines": {
39
40
  "node": ">=18.0.0"
package/src/agents.js CHANGED
@@ -37,6 +37,12 @@ export const SUPPORTED_AGENTS = [
37
37
  configDir: '.qwen',
38
38
  skillsDir: 'skills',
39
39
  },
40
+ {
41
+ id: 'opencode',
42
+ name: 'OpenCode',
43
+ configDir: '.config/opencode',
44
+ skillsDir: 'skills',
45
+ },
40
46
  ];
41
47
 
42
48
  /**
package/src/ascii.js CHANGED
@@ -15,7 +15,7 @@ const logo = `
15
15
  /**
16
16
  * Welcome screen
17
17
  */
18
- export function showWelcome(skillCount = 82, categoryCount = 20, agentCount = 5) {
18
+ export function showWelcome(skillCount = 82, categoryCount = 20, agentCount = 6) {
19
19
  console.clear();
20
20
  console.log(chalk.white(logo));
21
21
  console.log();
@@ -115,11 +115,10 @@ export function showNoAgents() {
115
115
  console.log(chalk.dim(' Install one of these supported agents:'));
116
116
  console.log();
117
117
  console.log(' ○ Claude Code');
118
+ console.log(' ○ OpenCode');
118
119
  console.log(' ○ Cursor');
119
120
  console.log(' ○ Codex (OpenAI)');
120
- console.log(' ○ Windsurf');
121
121
  console.log(' ○ Gemini CLI');
122
- console.log(' ○ Kilo Code');
123
122
  console.log(' ○ Qwen Code');
124
123
  console.log();
125
124
  console.log();
package/src/installer.js CHANGED
@@ -1,4 +1,4 @@
1
- import { existsSync, mkdirSync, symlinkSync, readdirSync, readFileSync, writeFileSync, rmSync, lstatSync } from 'fs';
1
+ import { existsSync, mkdirSync, symlinkSync, readdirSync, readFileSync, writeFileSync, rmSync, lstatSync, cpSync } from 'fs';
2
2
  import { homedir } from 'os';
3
3
  import { join, basename, dirname } from 'path';
4
4
  import { execSync } from 'child_process';
@@ -9,6 +9,18 @@ const REPO_URL = 'https://github.com/Orchestra-Research/AI-research-SKILLs';
9
9
  const CANONICAL_DIR = join(homedir(), '.orchestra', 'skills');
10
10
  const LOCK_FILE = join(homedir(), '.orchestra', '.lock.json');
11
11
 
12
+ /**
13
+ * Copy directory contents (cross-platform replacement for `cp -r source/* dest/`)
14
+ */
15
+ function copyDirectoryContents(source, dest) {
16
+ const entries = readdirSync(source, { withFileTypes: true });
17
+ for (const entry of entries) {
18
+ const srcPath = join(source, entry.name);
19
+ const destPath = join(dest, entry.name);
20
+ cpSync(srcPath, destPath, { recursive: true });
21
+ }
22
+ }
23
+
12
24
  /**
13
25
  * Ensure the canonical skills directory exists
14
26
  */
@@ -79,7 +91,7 @@ async function downloadSkills(categories, spinner) {
79
91
  if (existsSync(standaloneSkillPath)) {
80
92
  // Copy the entire category as a standalone skill
81
93
  spinner.text = `Downloading ${categoryId}...`;
82
- execSync(`cp -r "${categoryPath}"/* "${targetCategoryPath}/"`, { stdio: 'pipe' });
94
+ copyDirectoryContents(categoryPath, targetCategoryPath);
83
95
  skills.push({ category: categoryId, skill: categoryId, standalone: true });
84
96
  } else {
85
97
  // It's a nested category with multiple skills
@@ -93,7 +105,7 @@ async function downloadSkills(categories, spinner) {
93
105
  if (!existsSync(targetSkillPath)) {
94
106
  mkdirSync(targetSkillPath, { recursive: true });
95
107
  }
96
- execSync(`cp -r "${join(categoryPath, entry.name)}"/* "${targetSkillPath}/"`, { stdio: 'pipe' });
108
+ copyDirectoryContents(join(categoryPath, entry.name), targetSkillPath);
97
109
  skills.push({ category: categoryId, skill: entry.name, standalone: false });
98
110
  }
99
111
  }
@@ -192,7 +204,7 @@ async function downloadSpecificSkills(skillPaths, spinner) {
192
204
  if (!existsSync(targetSkillPath)) {
193
205
  mkdirSync(targetSkillPath, { recursive: true });
194
206
  }
195
- execSync(`cp -r "${sourcePath}"/* "${targetSkillPath}/"`, { stdio: 'pipe' });
207
+ copyDirectoryContents(sourcePath, targetSkillPath);
196
208
  skills.push({ category: categoryId, skill: skillName, standalone: false });
197
209
  }
198
210
  } else {
@@ -200,7 +212,7 @@ async function downloadSpecificSkills(skillPaths, spinner) {
200
212
  const sourcePath = join(tempDir, categoryId);
201
213
  if (existsSync(sourcePath)) {
202
214
  spinner.text = `Downloading ${categoryId}...`;
203
- execSync(`cp -r "${sourcePath}"/* "${targetCategoryPath}/"`, { stdio: 'pipe' });
215
+ copyDirectoryContents(sourcePath, targetCategoryPath);
204
216
  skills.push({ category: categoryId, skill: categoryId, standalone: true });
205
217
  }
206
218
  }