opencode-agents 1.0.7
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/bin/agents.js +19 -0
- package/build.mjs +49 -0
- package/dist/agents.js +19 -0
- package/dist/index.cjs +26268 -0
- package/dist/index.cjs.map +7 -0
- package/dist/index.js +26273 -0
- package/dist/index.js.map +7 -0
- package/dist/templates/default-agent.md +35 -0
- package/package.json +38 -0
- package/src/commands/add.ts +44 -0
- package/src/commands/check.ts +11 -0
- package/src/commands/find.ts +25 -0
- package/src/commands/init.ts +84 -0
- package/src/commands/list.ts +42 -0
- package/src/commands/remove.ts +42 -0
- package/src/commands/update.ts +12 -0
- package/src/core/discover.ts +129 -0
- package/src/core/installer.ts +169 -0
- package/src/core/parser.ts +55 -0
- package/src/index.ts +64 -0
- package/src/types/index.ts +78 -0
- package/src/utils/filesystem.ts +177 -0
- package/src/utils/logger.ts +13 -0
- package/templates/default-agent.md +35 -0
- package/tsconfig.json +20 -0
package/src/index.ts
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import { addCommand } from './commands/add.js';
|
|
6
|
+
import { listCommand } from './commands/list.js';
|
|
7
|
+
import { removeCommand } from './commands/remove.js';
|
|
8
|
+
import { initCommand } from './commands/init.js';
|
|
9
|
+
import { findCommand } from './commands/find.js';
|
|
10
|
+
import { checkCommand } from './commands/check.js';
|
|
11
|
+
import { updateCommand } from './commands/update.js';
|
|
12
|
+
|
|
13
|
+
const program = new Command();
|
|
14
|
+
|
|
15
|
+
program
|
|
16
|
+
.name('agents')
|
|
17
|
+
.description('CLI for managing AI coding agents')
|
|
18
|
+
.version('1.0.0');
|
|
19
|
+
|
|
20
|
+
program
|
|
21
|
+
.command('add <source>')
|
|
22
|
+
.description('Install one or more agents from a GitHub repository or local path')
|
|
23
|
+
.option('-g, --global', 'Install to global directory', false)
|
|
24
|
+
.option('-a, --agent <agents...>', 'Target agent platform(s)')
|
|
25
|
+
.option('--agent-name <name>', 'Name for the installed agent')
|
|
26
|
+
.option('-y, --yes', 'Skip confirmation', false)
|
|
27
|
+
.option('--copy', 'Copy instead of symlink', false)
|
|
28
|
+
.action(addCommand);
|
|
29
|
+
|
|
30
|
+
program
|
|
31
|
+
.command('list')
|
|
32
|
+
.description('List installed agents')
|
|
33
|
+
.option('-g, --global', 'List only global agents')
|
|
34
|
+
.option('-a, --agent <agent>', 'Filter by platform')
|
|
35
|
+
.action(listCommand);
|
|
36
|
+
|
|
37
|
+
program
|
|
38
|
+
.command('remove <name>')
|
|
39
|
+
.description('Remove an installed agent')
|
|
40
|
+
.option('-g, --global', 'Remove from global directory')
|
|
41
|
+
.option('-a, --agent <agent>', 'Remove from specific platform')
|
|
42
|
+
.action(removeCommand);
|
|
43
|
+
|
|
44
|
+
program
|
|
45
|
+
.command('init [name]')
|
|
46
|
+
.description('Create a new agent definition template')
|
|
47
|
+
.action(initCommand);
|
|
48
|
+
|
|
49
|
+
program
|
|
50
|
+
.command('find [query]')
|
|
51
|
+
.description('Search for available agents')
|
|
52
|
+
.action(findCommand);
|
|
53
|
+
|
|
54
|
+
program
|
|
55
|
+
.command('check')
|
|
56
|
+
.description('Check for updates to installed agents')
|
|
57
|
+
.action(checkCommand);
|
|
58
|
+
|
|
59
|
+
program
|
|
60
|
+
.command('update')
|
|
61
|
+
.description('Update all installed agents to the latest version')
|
|
62
|
+
.action(updateCommand);
|
|
63
|
+
|
|
64
|
+
program.parse();
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
export interface Agent {
|
|
2
|
+
description: string;
|
|
3
|
+
name?: string;
|
|
4
|
+
mode?: 'primary' | 'subagent' | 'all';
|
|
5
|
+
model?: string;
|
|
6
|
+
temperature?: number;
|
|
7
|
+
maxSteps?: number;
|
|
8
|
+
color?: string;
|
|
9
|
+
trigger?: string;
|
|
10
|
+
hidden?: boolean;
|
|
11
|
+
tools?: {
|
|
12
|
+
read?: boolean;
|
|
13
|
+
write?: boolean;
|
|
14
|
+
edit?: boolean;
|
|
15
|
+
bash?: boolean | string;
|
|
16
|
+
glob?: boolean | string;
|
|
17
|
+
grep?: boolean | string;
|
|
18
|
+
task?: boolean;
|
|
19
|
+
skill?: boolean;
|
|
20
|
+
[key: string]: boolean | string | undefined;
|
|
21
|
+
};
|
|
22
|
+
permission?: {
|
|
23
|
+
bash?: Record<string, 'allow' | 'deny' | 'ask'>;
|
|
24
|
+
edit?: 'allow' | 'deny' | 'ask';
|
|
25
|
+
write?: 'allow' | 'deny' | 'ask';
|
|
26
|
+
skill?: Record<string, 'allow' | 'deny'>;
|
|
27
|
+
task?: Record<string, 'allow' | 'deny'>;
|
|
28
|
+
[key: string]: unknown;
|
|
29
|
+
};
|
|
30
|
+
mcp?: {
|
|
31
|
+
servers?: Array<{
|
|
32
|
+
name: string;
|
|
33
|
+
command: string;
|
|
34
|
+
args?: string[];
|
|
35
|
+
}>;
|
|
36
|
+
};
|
|
37
|
+
version?: string;
|
|
38
|
+
source?: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface AgentManifest {
|
|
42
|
+
agents: Agent[];
|
|
43
|
+
source: string;
|
|
44
|
+
ref?: string;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface AgentFile {
|
|
48
|
+
path: string;
|
|
49
|
+
agent: Agent;
|
|
50
|
+
content: string;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface Config {
|
|
54
|
+
global: boolean;
|
|
55
|
+
agents: Record<string, string[]>;
|
|
56
|
+
updates: {
|
|
57
|
+
check: 'daily' | 'weekly' | 'manual';
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export type AgentPlatform =
|
|
62
|
+
| 'opencode'
|
|
63
|
+
| 'claude-code'
|
|
64
|
+
| 'cursor'
|
|
65
|
+
| 'windsurf'
|
|
66
|
+
| 'cline'
|
|
67
|
+
| 'roo'
|
|
68
|
+
| 'codex'
|
|
69
|
+
| 'continue';
|
|
70
|
+
|
|
71
|
+
export interface InstallOptions {
|
|
72
|
+
source: string;
|
|
73
|
+
global: boolean;
|
|
74
|
+
platforms: AgentPlatform[];
|
|
75
|
+
agentName?: string;
|
|
76
|
+
copy: boolean;
|
|
77
|
+
yes: boolean;
|
|
78
|
+
}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync, symlinkSync, copyFileSync, rmSync, statSync } from 'fs';
|
|
2
|
+
import { join, dirname, basename } from 'path';
|
|
3
|
+
import { homedir } from 'os';
|
|
4
|
+
import type { AgentPlatform } from '../types/index.js';
|
|
5
|
+
|
|
6
|
+
export function ensureDir(dir: string): void {
|
|
7
|
+
if (!existsSync(dir)) {
|
|
8
|
+
mkdirSync(dir, { recursive: true });
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function readDir(dir: string): string[] {
|
|
13
|
+
if (!existsSync(dir)) {
|
|
14
|
+
return [];
|
|
15
|
+
}
|
|
16
|
+
return readdirSync(dir);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function readFile(path: string): string {
|
|
20
|
+
return readFileSync(path, 'utf-8');
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function writeFile(path: string, content: string): void {
|
|
24
|
+
ensureDir(dirname(path));
|
|
25
|
+
writeFileSync(path, content, 'utf-8');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function isDirectory(path: string): boolean {
|
|
29
|
+
return existsSync(path) && statSync(path).isDirectory();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function isFile(path: string): boolean {
|
|
33
|
+
return existsSync(path) && statSync(path).isFile();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function getPlatformPaths(platform: AgentPlatform, global: boolean): string[] {
|
|
37
|
+
const home = homedir();
|
|
38
|
+
|
|
39
|
+
const paths: Record<AgentPlatform, { project: string[]; global: string[] }> = {
|
|
40
|
+
'opencode': {
|
|
41
|
+
project: ['.opencode/agents/'],
|
|
42
|
+
global: [join(home, '.config', 'opencode', 'agents')],
|
|
43
|
+
},
|
|
44
|
+
'claude-code': {
|
|
45
|
+
project: ['.claude/agents/'],
|
|
46
|
+
global: [join(home, '.claude', 'agents')],
|
|
47
|
+
},
|
|
48
|
+
'cursor': {
|
|
49
|
+
project: ['.cursor/agents/'],
|
|
50
|
+
global: [join(home, '.cursor', 'agents')],
|
|
51
|
+
},
|
|
52
|
+
'windsurf': {
|
|
53
|
+
project: ['.windsurf/agents/'],
|
|
54
|
+
global: [join(home, '.codeium', 'windsurf', 'agents')],
|
|
55
|
+
},
|
|
56
|
+
'cline': {
|
|
57
|
+
project: ['.cline/agents/'],
|
|
58
|
+
global: [join(home, '.cline', 'agents')],
|
|
59
|
+
},
|
|
60
|
+
'roo': {
|
|
61
|
+
project: ['.roo/agents/'],
|
|
62
|
+
global: [join(home, '.roo', 'agents')],
|
|
63
|
+
},
|
|
64
|
+
'codex': {
|
|
65
|
+
project: ['.codex/agents/'],
|
|
66
|
+
global: [join(home, '.codex', 'agents')],
|
|
67
|
+
},
|
|
68
|
+
'continue': {
|
|
69
|
+
project: ['.continue/agents/'],
|
|
70
|
+
global: [join(home, '.continue', 'agents')],
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
return global ? paths[platform].global : paths[platform].project;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function getGlobalAgentsDir(): string {
|
|
78
|
+
return process.env.NPX_AGENTS_DIR || join(homedir(), '.config', 'npx-agents');
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function createSymlink(source: string, target: string): void {
|
|
82
|
+
ensureDir(dirname(target));
|
|
83
|
+
symlinkSync(source, target, 'dir');
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export function copyDir(source: string, target: string): void {
|
|
87
|
+
ensureDir(target);
|
|
88
|
+
const files = readdirSync(source);
|
|
89
|
+
for (const file of files) {
|
|
90
|
+
const srcPath = join(source, file);
|
|
91
|
+
const destPath = join(target, file);
|
|
92
|
+
if (isDirectory(srcPath)) {
|
|
93
|
+
copyDir(srcPath, destPath);
|
|
94
|
+
} else {
|
|
95
|
+
copyFileSync(srcPath, destPath);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export function removePath(path: string): void {
|
|
101
|
+
if (existsSync(path)) {
|
|
102
|
+
rmSync(path, { recursive: true, force: true });
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export function findFiles(dir: string, pattern: RegExp): string[] {
|
|
107
|
+
const results: string[] = [];
|
|
108
|
+
|
|
109
|
+
if (!existsSync(dir)) {
|
|
110
|
+
return results;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const files = readdirSync(dir);
|
|
114
|
+
for (const file of files) {
|
|
115
|
+
const fullPath = join(dir, file);
|
|
116
|
+
if (isDirectory(fullPath)) {
|
|
117
|
+
results.push(...findFiles(fullPath, pattern));
|
|
118
|
+
} else if (pattern.test(file)) {
|
|
119
|
+
results.push(fullPath);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return results;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export function detectPlatforms(): AgentPlatform[] {
|
|
127
|
+
const platforms: AgentPlatform[] = [];
|
|
128
|
+
const home = homedir();
|
|
129
|
+
const cwd = process.cwd();
|
|
130
|
+
|
|
131
|
+
const checks: Array<{ platform: AgentPlatform; check: () => boolean }> = [
|
|
132
|
+
{
|
|
133
|
+
platform: 'opencode',
|
|
134
|
+
check: () => existsSync(join(home, '.config', 'opencode')) || existsSync(join(cwd, '.opencode')),
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
platform: 'claude-code',
|
|
138
|
+
check: () => existsSync(join(home, '.claude')) || existsSync(join(cwd, '.claude')),
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
platform: 'cursor',
|
|
142
|
+
check: () => existsSync(join(home, '.cursor')) || existsSync(join(cwd, '.cursor')),
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
platform: 'windsurf',
|
|
146
|
+
check: () => existsSync(join(home, '.codeium', 'windsurf')) || existsSync(join(cwd, '.windsurf')),
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
platform: 'cline',
|
|
150
|
+
check: () => existsSync(join(home, '.cline')) || existsSync(join(cwd, '.cline')),
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
platform: 'roo',
|
|
154
|
+
check: () => existsSync(join(home, '.roo')) || existsSync(join(cwd, '.roo')),
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
platform: 'codex',
|
|
158
|
+
check: () => existsSync(join(home, '.codex')) || existsSync(join(cwd, '.codex')),
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
platform: 'continue',
|
|
162
|
+
check: () => existsSync(join(home, '.continue')) || existsSync(join(cwd, '.continue')),
|
|
163
|
+
},
|
|
164
|
+
];
|
|
165
|
+
|
|
166
|
+
for (const check of checks) {
|
|
167
|
+
if (check.check()) {
|
|
168
|
+
platforms.push(check.platform);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if (platforms.length === 0) {
|
|
173
|
+
platforms.push('opencode');
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return platforms;
|
|
177
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
|
|
3
|
+
export const logger = {
|
|
4
|
+
info: (msg: string) => console.log(chalk.blue('ℹ'), msg),
|
|
5
|
+
success: (msg: string) => console.log(chalk.green('✓'), msg),
|
|
6
|
+
warn: (msg: string) => console.log(chalk.yellow('⚠'), msg),
|
|
7
|
+
error: (msg: string) => console.error(chalk.red('✗'), msg),
|
|
8
|
+
debug: (msg: string) => {
|
|
9
|
+
if (process.env.DEBUG === 'npx-agents') {
|
|
10
|
+
console.log(chalk.gray('[debug]'), msg);
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: my-agent - Add your agent description here
|
|
3
|
+
mode: subagent
|
|
4
|
+
model: anthropic/claude-3-5-sonnet-20241022
|
|
5
|
+
temperature: 0.7
|
|
6
|
+
tools:
|
|
7
|
+
read: true
|
|
8
|
+
write: true
|
|
9
|
+
edit: true
|
|
10
|
+
bash: false
|
|
11
|
+
glob: true
|
|
12
|
+
grep: true
|
|
13
|
+
task: false
|
|
14
|
+
skill: false
|
|
15
|
+
hidden: false
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
# my-agent
|
|
19
|
+
|
|
20
|
+
You are a custom AI agent. Describe your purpose and behavior here.
|
|
21
|
+
|
|
22
|
+
## When to Use
|
|
23
|
+
|
|
24
|
+
Describe when this agent should be invoked.
|
|
25
|
+
|
|
26
|
+
## Workflow
|
|
27
|
+
|
|
28
|
+
1. First step...
|
|
29
|
+
2. Second step...
|
|
30
|
+
3. Third step...
|
|
31
|
+
|
|
32
|
+
## Guidelines
|
|
33
|
+
|
|
34
|
+
- Add your specific guidelines here
|
|
35
|
+
- Be clear and concise
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"lib": ["ES2022"],
|
|
7
|
+
"outDir": "./dist",
|
|
8
|
+
"rootDir": "./src",
|
|
9
|
+
"strict": true,
|
|
10
|
+
"esModuleInterop": true,
|
|
11
|
+
"skipLibCheck": true,
|
|
12
|
+
"forceConsistentCasingInFileNames": true,
|
|
13
|
+
"resolveJsonModule": true,
|
|
14
|
+
"declaration": false,
|
|
15
|
+
"declarationMap": false,
|
|
16
|
+
"sourceMap": true
|
|
17
|
+
},
|
|
18
|
+
"include": ["src/**/*"],
|
|
19
|
+
"exclude": ["node_modules", "dist", "templates"]
|
|
20
|
+
}
|