opencode-agents 1.1.4 → 1.1.5
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 +30 -6
- package/dist/index.js.map +2 -2
- package/package.json +1 -1
- package/src/core/discover.ts +14 -9
- package/src/core/installer.ts +3 -1
- package/src/core/parser.ts +33 -2
package/package.json
CHANGED
package/src/core/discover.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { join, basename } from 'path';
|
|
2
2
|
import { existsSync, readdirSync, readFileSync } from 'fs';
|
|
3
|
-
import { parseAgentFile } from './parser.js';
|
|
3
|
+
import { parseAgentFile, isAgentContent } from './parser.js';
|
|
4
4
|
import { findFiles, isDirectory } from '../utils/filesystem.js';
|
|
5
5
|
import type { AgentFile, Agent } from '../types/index.js';
|
|
6
6
|
|
|
@@ -14,7 +14,6 @@ const SEARCH_DIRECTORIES = [
|
|
|
14
14
|
|
|
15
15
|
const PRIORITY_FILES = [
|
|
16
16
|
'AGENTS.md',
|
|
17
|
-
'SKILL.md',
|
|
18
17
|
'AGENT.md',
|
|
19
18
|
];
|
|
20
19
|
|
|
@@ -34,8 +33,10 @@ export async function discoverFromDirectory(dir: string): Promise<AgentFile[]> {
|
|
|
34
33
|
|
|
35
34
|
try {
|
|
36
35
|
const content = readFileSync(file, 'utf-8');
|
|
37
|
-
const
|
|
38
|
-
|
|
36
|
+
const result = parseAgentFile(content, file);
|
|
37
|
+
// 如果解析结果为 null,说明不是 Agent 文件(是 Skill 文件)
|
|
38
|
+
if (result === null) continue;
|
|
39
|
+
agents.push(result);
|
|
39
40
|
} catch (err) {
|
|
40
41
|
continue;
|
|
41
42
|
}
|
|
@@ -47,10 +48,12 @@ export async function discoverFromDirectory(dir: string): Promise<AgentFile[]> {
|
|
|
47
48
|
if (existsSync(priorityFile)) {
|
|
48
49
|
try {
|
|
49
50
|
const content = readFileSync(priorityFile, 'utf-8');
|
|
50
|
-
const
|
|
51
|
-
|
|
51
|
+
const result = parseAgentFile(content, priorityFile);
|
|
52
|
+
// 如果解析结果为 null,说明不是 Agent 文件(是 Skill 文件)
|
|
53
|
+
if (result === null) continue;
|
|
54
|
+
const exists = agents.some(a => a.path === result.path);
|
|
52
55
|
if (!exists) {
|
|
53
|
-
agents.unshift(
|
|
56
|
+
agents.unshift(result);
|
|
54
57
|
}
|
|
55
58
|
} catch (err) {
|
|
56
59
|
continue;
|
|
@@ -96,8 +99,10 @@ export function discoverLocal(dir: string): AgentFile[] {
|
|
|
96
99
|
|
|
97
100
|
try {
|
|
98
101
|
const content = readFileSync(file, 'utf-8');
|
|
99
|
-
const
|
|
100
|
-
|
|
102
|
+
const result = parseAgentFile(content, file);
|
|
103
|
+
// 如果解析结果为 null,说明不是 Agent 文件(是 Skill 文件)
|
|
104
|
+
if (result === null) continue;
|
|
105
|
+
agents.push(result);
|
|
101
106
|
} catch (err) {
|
|
102
107
|
continue;
|
|
103
108
|
}
|
package/src/core/installer.ts
CHANGED
|
@@ -110,12 +110,14 @@ export function listInstalledAgents(platform: AgentPlatform, global: boolean): A
|
|
|
110
110
|
|
|
111
111
|
for (const path of paths) {
|
|
112
112
|
if (!existsSync(path)) continue;
|
|
113
|
-
|
|
113
|
+
|
|
114
114
|
const mdFiles = findFiles(path, /\.md$/);
|
|
115
115
|
for (const file of mdFiles) {
|
|
116
116
|
try {
|
|
117
117
|
const content = readFileSync(file, 'utf-8');
|
|
118
118
|
const agentFile = parseAgentFile(content, file);
|
|
119
|
+
// 如果解析结果为 null,说明不是 Agent 文件(是 Skill 文件)
|
|
120
|
+
if (agentFile === null) continue;
|
|
119
121
|
agents.push(agentFile);
|
|
120
122
|
} catch (err) {
|
|
121
123
|
continue;
|
package/src/core/parser.ts
CHANGED
|
@@ -1,9 +1,40 @@
|
|
|
1
1
|
import matter from 'gray-matter';
|
|
2
2
|
import type { Agent, AgentFile } from '../types/index.js';
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
// Agent 特有字段,用于区分 Agent 和 Skill
|
|
5
|
+
const AGENT_SPECIFIC_FIELDS = [
|
|
6
|
+
'mode',
|
|
7
|
+
'model',
|
|
8
|
+
'temperature',
|
|
9
|
+
'maxSteps',
|
|
10
|
+
'color',
|
|
11
|
+
'trigger',
|
|
12
|
+
'tools',
|
|
13
|
+
'permission',
|
|
14
|
+
'mcp',
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* 判断一个 markdown 文件内容是 Agent 还是 Skill
|
|
19
|
+
* 如果 frontmatter 中包含任何 Agent 特有字段,则认为是 Agent
|
|
20
|
+
*/
|
|
21
|
+
export function isAgentContent(content: string): boolean {
|
|
22
|
+
try {
|
|
23
|
+
const { data } = matter(content);
|
|
24
|
+
return AGENT_SPECIFIC_FIELDS.some(field => field in data);
|
|
25
|
+
} catch {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function parseAgentFile(content: string, path: string): AgentFile | null {
|
|
5
31
|
const { data, content: body } = matter(content);
|
|
6
32
|
|
|
33
|
+
// 如果不是 Agent 文件(是 Skill 文件),返回 null
|
|
34
|
+
if (!isAgentContent(content)) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
|
|
7
38
|
if (!data.description) {
|
|
8
39
|
throw new Error(`Agent at ${path} is missing required "description" field in frontmatter`);
|
|
9
40
|
}
|
|
@@ -31,7 +62,7 @@ export function parseAgentFile(content: string, path: string): AgentFile {
|
|
|
31
62
|
};
|
|
32
63
|
}
|
|
33
64
|
|
|
34
|
-
export function parseAgentFromString(content: string, filename: string): AgentFile {
|
|
65
|
+
export function parseAgentFromString(content: string, filename: string): AgentFile | null {
|
|
35
66
|
const baseName = filename.replace(/\.md$/, '');
|
|
36
67
|
return parseAgentFile(content, baseName);
|
|
37
68
|
}
|