@onesclawkolor/onesclaw 0.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/README.md +65 -0
- package/dist/agent/conversation.d.ts +34 -0
- package/dist/agent/conversation.js +61 -0
- package/dist/agent/conversation.js.map +1 -0
- package/dist/agent/loop.d.ts +40 -0
- package/dist/agent/loop.js +213 -0
- package/dist/agent/loop.js.map +1 -0
- package/dist/agent/session.d.ts +73 -0
- package/dist/agent/session.js +225 -0
- package/dist/agent/session.js.map +1 -0
- package/dist/audit/file-sink.d.ts +6 -0
- package/dist/audit/file-sink.js +21 -0
- package/dist/audit/file-sink.js.map +1 -0
- package/dist/audit/ids.d.ts +3 -0
- package/dist/audit/ids.js +15 -0
- package/dist/audit/ids.js.map +1 -0
- package/dist/audit/types.d.ts +13 -0
- package/dist/audit/types.js +2 -0
- package/dist/audit/types.js.map +1 -0
- package/dist/cli/commands.d.ts +31 -0
- package/dist/cli/commands.js +433 -0
- package/dist/cli/commands.js.map +1 -0
- package/dist/cli/logger.d.ts +57 -0
- package/dist/cli/logger.js +79 -0
- package/dist/cli/logger.js.map +1 -0
- package/dist/cli/output.d.ts +59 -0
- package/dist/cli/output.js +306 -0
- package/dist/cli/output.js.map +1 -0
- package/dist/cli/prompt.d.ts +29 -0
- package/dist/cli/prompt.js +197 -0
- package/dist/cli/prompt.js.map +1 -0
- package/dist/cli/repl.d.ts +4 -0
- package/dist/cli/repl.js +486 -0
- package/dist/cli/repl.js.map +1 -0
- package/dist/commands/init.d.ts +4 -0
- package/dist/commands/init.js +84 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/model.d.ts +3 -0
- package/dist/commands/model.js +178 -0
- package/dist/commands/model.js.map +1 -0
- package/dist/commands/plugin-init.d.ts +23 -0
- package/dist/commands/plugin-init.js +303 -0
- package/dist/commands/plugin-init.js.map +1 -0
- package/dist/commands/provider-auth.d.ts +14 -0
- package/dist/commands/provider-auth.js +153 -0
- package/dist/commands/provider-auth.js.map +1 -0
- package/dist/config/manager.d.ts +71 -0
- package/dist/config/manager.js +201 -0
- package/dist/config/manager.js.map +1 -0
- package/dist/config/types.d.ts +43 -0
- package/dist/config/types.js +2 -0
- package/dist/config/types.js.map +1 -0
- package/dist/errors.d.ts +37 -0
- package/dist/errors.js +55 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +207 -0
- package/dist/index.js.map +1 -0
- package/dist/llm/anthropic.d.ts +83 -0
- package/dist/llm/anthropic.js +190 -0
- package/dist/llm/anthropic.js.map +1 -0
- package/dist/llm/factory.d.ts +105 -0
- package/dist/llm/factory.js +164 -0
- package/dist/llm/factory.js.map +1 -0
- package/dist/llm/openai-codex.d.ts +102 -0
- package/dist/llm/openai-codex.js +445 -0
- package/dist/llm/openai-codex.js.map +1 -0
- package/dist/llm/openai.d.ts +71 -0
- package/dist/llm/openai.js +289 -0
- package/dist/llm/openai.js.map +1 -0
- package/dist/llm/provider.d.ts +1 -0
- package/dist/llm/provider.js +2 -0
- package/dist/llm/provider.js.map +1 -0
- package/dist/llm/types.d.ts +72 -0
- package/dist/llm/types.js +2 -0
- package/dist/llm/types.js.map +1 -0
- package/dist/mcp/bridge.d.ts +17 -0
- package/dist/mcp/bridge.js +74 -0
- package/dist/mcp/bridge.js.map +1 -0
- package/dist/mcp/config.d.ts +10 -0
- package/dist/mcp/config.js +27 -0
- package/dist/mcp/config.js.map +1 -0
- package/dist/mcp/manager.d.ts +67 -0
- package/dist/mcp/manager.js +207 -0
- package/dist/mcp/manager.js.map +1 -0
- package/dist/memory/scope.d.ts +4 -0
- package/dist/memory/scope.js +14 -0
- package/dist/memory/scope.js.map +1 -0
- package/dist/memory/store.d.ts +28 -0
- package/dist/memory/store.js +126 -0
- package/dist/memory/store.js.map +1 -0
- package/dist/prompts/system.d.ts +4 -0
- package/dist/prompts/system.js +197 -0
- package/dist/prompts/system.js.map +1 -0
- package/dist/skills/loader.d.ts +25 -0
- package/dist/skills/loader.js +98 -0
- package/dist/skills/loader.js.map +1 -0
- package/dist/skills/registry.d.ts +57 -0
- package/dist/skills/registry.js +132 -0
- package/dist/skills/registry.js.map +1 -0
- package/dist/skills/sync.d.ts +33 -0
- package/dist/skills/sync.js +180 -0
- package/dist/skills/sync.js.map +1 -0
- package/dist/skills/types.d.ts +1 -0
- package/dist/skills/types.js +2 -0
- package/dist/skills/types.js.map +1 -0
- package/dist/tools/ask.d.ts +30 -0
- package/dist/tools/ask.js +60 -0
- package/dist/tools/ask.js.map +1 -0
- package/dist/tools/confirmation.d.ts +12 -0
- package/dist/tools/confirmation.js +75 -0
- package/dist/tools/confirmation.js.map +1 -0
- package/dist/tools/plugin-init.d.ts +29 -0
- package/dist/tools/plugin-init.js +47 -0
- package/dist/tools/plugin-init.js.map +1 -0
- package/dist/tools/registry.d.ts +56 -0
- package/dist/tools/registry.js +123 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/safety.d.ts +2 -0
- package/dist/tools/safety.js +30 -0
- package/dist/tools/safety.js.map +1 -0
- package/dist/tools/server.d.ts +91 -0
- package/dist/tools/server.js +149 -0
- package/dist/tools/server.js.map +1 -0
- package/dist/tools/shell.d.ts +11 -0
- package/dist/tools/shell.js +174 -0
- package/dist/tools/shell.js.map +1 -0
- package/dist/tools/skills-sync.d.ts +19 -0
- package/dist/tools/skills-sync.js +29 -0
- package/dist/tools/skills-sync.js.map +1 -0
- package/dist/tools/ssh.d.ts +62 -0
- package/dist/tools/ssh.js +343 -0
- package/dist/tools/ssh.js.map +1 -0
- package/dist/tools/types.d.ts +10 -0
- package/dist/tools/types.js +2 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/utils/retry.d.ts +7 -0
- package/dist/utils/retry.js +34 -0
- package/dist/utils/retry.js.map +1 -0
- package/install.sh +171 -0
- package/package.json +49 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
import matter from 'gray-matter';
|
|
3
|
+
import { readFile } from 'node:fs/promises';
|
|
4
|
+
import { existsSync } from 'node:fs';
|
|
5
|
+
import { join } from 'node:path';
|
|
6
|
+
/**
|
|
7
|
+
* 创建 load_skill 工具
|
|
8
|
+
* 读取并解析 SKILL.md,返回 frontmatter 元数据和 Markdown 正文
|
|
9
|
+
*/
|
|
10
|
+
export function createLoadSkillTool(registry) {
|
|
11
|
+
return {
|
|
12
|
+
name: 'load_skill',
|
|
13
|
+
description: '加载指定技能的完整内容。传入技能名称(从 list_skills 获取),返回技能的元数据和执行步骤(Playbook)。加载后按步骤执行即可完成对应运维/开发任务。',
|
|
14
|
+
inputSchema: {
|
|
15
|
+
type: 'object',
|
|
16
|
+
properties: {
|
|
17
|
+
name: {
|
|
18
|
+
type: 'string',
|
|
19
|
+
description: '技能名称,从 list_skills 工具的返回结果中获取',
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
required: ['name'],
|
|
23
|
+
},
|
|
24
|
+
execute: async (args) => {
|
|
25
|
+
const name = args.name;
|
|
26
|
+
// 1. 查找技能元数据
|
|
27
|
+
const skillMeta = registry.getByName(name);
|
|
28
|
+
if (!skillMeta) {
|
|
29
|
+
return {
|
|
30
|
+
content: `未找到名为 "${name}" 的技能。请先使用 list_skills 工具搜索可用技能。`,
|
|
31
|
+
isError: true,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
// 2. 拼接 SKILL.md 完整路径
|
|
35
|
+
// path 可能缺失(index.json 未包含),此时用 name 作为目录名
|
|
36
|
+
const projectRoot = registry.getProjectRoot();
|
|
37
|
+
const skillDir = typeof skillMeta.path === 'string' && skillMeta.path.trim()
|
|
38
|
+
? skillMeta.path.trim()
|
|
39
|
+
: skillMeta.name;
|
|
40
|
+
const skillPath = join(projectRoot, skillDir, 'SKILL.md');
|
|
41
|
+
// 3. 检查文件是否存在
|
|
42
|
+
if (!existsSync(skillPath)) {
|
|
43
|
+
return {
|
|
44
|
+
content: `技能文件不存在:${skillPath}`,
|
|
45
|
+
isError: true,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
// 4. 读取并解析
|
|
49
|
+
try {
|
|
50
|
+
const raw = await readFile(skillPath, 'utf-8');
|
|
51
|
+
// 5. 使用 gray-matter 解析 frontmatter
|
|
52
|
+
const baseMetadata = {
|
|
53
|
+
name: skillMeta.name,
|
|
54
|
+
description: skillMeta.description || '',
|
|
55
|
+
domain: skillMeta.domain || 'general',
|
|
56
|
+
};
|
|
57
|
+
let metadata = { ...baseMetadata };
|
|
58
|
+
let body;
|
|
59
|
+
try {
|
|
60
|
+
const parsed = matter(raw);
|
|
61
|
+
metadata = {
|
|
62
|
+
...baseMetadata,
|
|
63
|
+
...(parsed.data || {}),
|
|
64
|
+
name: typeof parsed.data?.name === 'string' && parsed.data.name.trim()
|
|
65
|
+
? parsed.data.name
|
|
66
|
+
: baseMetadata.name,
|
|
67
|
+
description: typeof parsed.data?.description === 'string'
|
|
68
|
+
? parsed.data.description
|
|
69
|
+
: baseMetadata.description,
|
|
70
|
+
domain: typeof parsed.data?.domain === 'string' && parsed.data.domain.trim()
|
|
71
|
+
? parsed.data.domain
|
|
72
|
+
: baseMetadata.domain,
|
|
73
|
+
};
|
|
74
|
+
body = parsed.content.trim();
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
// frontmatter 解析失败 → 返回原始内容
|
|
78
|
+
body = raw.trim();
|
|
79
|
+
}
|
|
80
|
+
// 6. 构建返回结果
|
|
81
|
+
const result = {
|
|
82
|
+
metadata,
|
|
83
|
+
content: body,
|
|
84
|
+
};
|
|
85
|
+
return {
|
|
86
|
+
content: JSON.stringify(result, null, 2),
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
return {
|
|
91
|
+
content: `读取技能文件失败 [${skillPath}]: ${error instanceof Error ? error.message : String(error)}`,
|
|
92
|
+
isError: true,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/skills/loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill 注册表
|
|
3
|
+
* 管理 Skill 索引,提供搜索和列表能力
|
|
4
|
+
*/
|
|
5
|
+
export declare class SkillRegistry {
|
|
6
|
+
skills: any[];
|
|
7
|
+
projectRoot: string;
|
|
8
|
+
/**
|
|
9
|
+
* 从 skills/index.json 加载技能索引
|
|
10
|
+
*/
|
|
11
|
+
load(indexPath: any): Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* 按名称精确查找技能
|
|
14
|
+
*/
|
|
15
|
+
getByName(name: any): any;
|
|
16
|
+
/**
|
|
17
|
+
* 获取项目根目录(从 load 时的 indexPath 推导)
|
|
18
|
+
*/
|
|
19
|
+
getProjectRoot(): string;
|
|
20
|
+
/**
|
|
21
|
+
* 搜索技能
|
|
22
|
+
* - keyword: 关键词搜索(匹配 name、description、tags)
|
|
23
|
+
* - domain: 按能力域过滤(大小写不敏感)
|
|
24
|
+
*/
|
|
25
|
+
search(options: any): any[];
|
|
26
|
+
/**
|
|
27
|
+
* 获取所有技能
|
|
28
|
+
*/
|
|
29
|
+
getAll(): any[];
|
|
30
|
+
/**
|
|
31
|
+
* 已加载的技能数量
|
|
32
|
+
*/
|
|
33
|
+
get size(): number;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* 创建 list_skills 工具
|
|
37
|
+
*/
|
|
38
|
+
export declare function createListSkillsTool(registry: any): {
|
|
39
|
+
name: string;
|
|
40
|
+
description: string;
|
|
41
|
+
inputSchema: {
|
|
42
|
+
type: string;
|
|
43
|
+
properties: {
|
|
44
|
+
keyword: {
|
|
45
|
+
type: string;
|
|
46
|
+
description: string;
|
|
47
|
+
};
|
|
48
|
+
domain: {
|
|
49
|
+
type: string;
|
|
50
|
+
description: string;
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
execute: (args: any) => Promise<{
|
|
55
|
+
content: string;
|
|
56
|
+
}>;
|
|
57
|
+
};
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
import { readFile } from 'node:fs/promises';
|
|
3
|
+
import { dirname } from 'node:path';
|
|
4
|
+
/**
|
|
5
|
+
* Skill 注册表
|
|
6
|
+
* 管理 Skill 索引,提供搜索和列表能力
|
|
7
|
+
*/
|
|
8
|
+
export class SkillRegistry {
|
|
9
|
+
skills = [];
|
|
10
|
+
projectRoot = '';
|
|
11
|
+
/**
|
|
12
|
+
* 从 skills/index.json 加载技能索引
|
|
13
|
+
*/
|
|
14
|
+
async load(indexPath) {
|
|
15
|
+
const content = await readFile(indexPath, 'utf-8');
|
|
16
|
+
const index = JSON.parse(content);
|
|
17
|
+
const rawSkills = Array.isArray(index?.skills) ? index.skills : [];
|
|
18
|
+
this.skills = rawSkills
|
|
19
|
+
.map((item) => normalizeSkill(item))
|
|
20
|
+
.filter((item) => item !== null);
|
|
21
|
+
// 技能目录与 index.json 同级
|
|
22
|
+
this.projectRoot = dirname(indexPath);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* 按名称精确查找技能
|
|
26
|
+
*/
|
|
27
|
+
getByName(name) {
|
|
28
|
+
return this.skills.find((s) => s.name === name);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* 获取项目根目录(从 load 时的 indexPath 推导)
|
|
32
|
+
*/
|
|
33
|
+
getProjectRoot() {
|
|
34
|
+
return this.projectRoot;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* 搜索技能
|
|
38
|
+
* - keyword: 关键词搜索(匹配 name、description、tags)
|
|
39
|
+
* - domain: 按能力域过滤(大小写不敏感)
|
|
40
|
+
*/
|
|
41
|
+
search(options) {
|
|
42
|
+
let results = this.skills;
|
|
43
|
+
// 按 domain 过滤
|
|
44
|
+
if (typeof options.domain === 'string' && options.domain.trim().length > 0) {
|
|
45
|
+
const domainNeedle = options.domain.trim().toLowerCase();
|
|
46
|
+
results = results.filter((s) => s.domain.toLowerCase() === domainNeedle);
|
|
47
|
+
}
|
|
48
|
+
// 关键词匹配
|
|
49
|
+
if (typeof options.keyword === 'string' && options.keyword.trim().length > 0) {
|
|
50
|
+
const lower = options.keyword.trim().toLowerCase();
|
|
51
|
+
results = results.filter((s) => s.name.toLowerCase().includes(lower) ||
|
|
52
|
+
s.description.toLowerCase().includes(lower) ||
|
|
53
|
+
s.tags.some((tag) => tag.toLowerCase().includes(lower)));
|
|
54
|
+
}
|
|
55
|
+
return results;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* 获取所有技能
|
|
59
|
+
*/
|
|
60
|
+
getAll() {
|
|
61
|
+
return [...this.skills];
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* 已加载的技能数量
|
|
65
|
+
*/
|
|
66
|
+
get size() {
|
|
67
|
+
return this.skills.length;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function normalizeSkill(input) {
|
|
71
|
+
if (!input || typeof input !== 'object' || Array.isArray(input)) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
const raw = input;
|
|
75
|
+
if (typeof raw.name !== 'string' || raw.name.trim().length === 0) {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
const domain = typeof raw.domain === 'string' && raw.domain.trim().length > 0 ? raw.domain.trim() : 'general';
|
|
79
|
+
const tags = Array.isArray(raw.tags)
|
|
80
|
+
? raw.tags.filter((x) => typeof x === 'string').map((x) => x.trim()).filter(Boolean)
|
|
81
|
+
: [];
|
|
82
|
+
const description = typeof raw.description === 'string' ? raw.description : '';
|
|
83
|
+
const version = typeof raw.version === 'string' ? raw.version : undefined;
|
|
84
|
+
const path = typeof raw.path === 'string' && raw.path.trim().length > 0 ? raw.path.trim() : undefined;
|
|
85
|
+
return {
|
|
86
|
+
...raw,
|
|
87
|
+
name: raw.name.trim(),
|
|
88
|
+
domain,
|
|
89
|
+
tags,
|
|
90
|
+
description,
|
|
91
|
+
version,
|
|
92
|
+
path,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* 创建 list_skills 工具
|
|
97
|
+
*/
|
|
98
|
+
export function createListSkillsTool(registry) {
|
|
99
|
+
return {
|
|
100
|
+
name: 'list_skills',
|
|
101
|
+
description: '搜索可用的技能列表。可按能力域过滤,或通过关键词搜索匹配的技能。返回技能名称、描述和能力域。',
|
|
102
|
+
inputSchema: {
|
|
103
|
+
type: 'object',
|
|
104
|
+
properties: {
|
|
105
|
+
keyword: {
|
|
106
|
+
type: 'string',
|
|
107
|
+
description: '搜索关键词,匹配技能名称、描述和标签',
|
|
108
|
+
},
|
|
109
|
+
domain: {
|
|
110
|
+
type: 'string',
|
|
111
|
+
description: '按能力域过滤(大小写不敏感)',
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
execute: async (args) => {
|
|
116
|
+
const results = registry.search({
|
|
117
|
+
keyword: typeof args?.keyword === 'string' ? args.keyword : undefined,
|
|
118
|
+
domain: typeof args?.domain === 'string' ? args.domain : undefined,
|
|
119
|
+
});
|
|
120
|
+
// 返回精简的技能列表(不暴露 path、tags 等内部信息)
|
|
121
|
+
const simplified = results.map((s) => ({
|
|
122
|
+
name: s.name,
|
|
123
|
+
description: s.description,
|
|
124
|
+
domain: s.domain,
|
|
125
|
+
}));
|
|
126
|
+
return {
|
|
127
|
+
content: JSON.stringify(simplified, null, 2),
|
|
128
|
+
};
|
|
129
|
+
},
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/skills/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 获取 Skills 目录路径 ~/.onesclaw/skills/
|
|
3
|
+
*/
|
|
4
|
+
export declare function getSkillsDir(): string;
|
|
5
|
+
/**
|
|
6
|
+
* 检查是否需要同步 Skills
|
|
7
|
+
*
|
|
8
|
+
* 满足任一条件返回 true:
|
|
9
|
+
* 1. ~/.onesclaw/skills/index.json 不存在
|
|
10
|
+
* 2. ones_skills.last_updated_at 不存在
|
|
11
|
+
* 3. last_updated_at 距今超过 1 天
|
|
12
|
+
*/
|
|
13
|
+
export declare function needsSync(config: any): Promise<boolean>;
|
|
14
|
+
/**
|
|
15
|
+
* 执行 Skills 同步
|
|
16
|
+
*
|
|
17
|
+
* 流程:
|
|
18
|
+
* 1. 检查 git 可用性
|
|
19
|
+
* 2. clone 仓库到临时目录
|
|
20
|
+
* 3. 验证 index.json 存在
|
|
21
|
+
* 4. 全量替换 ~/.onesclaw/skills/
|
|
22
|
+
* 5. 更新 config.ones_skills.last_updated_at
|
|
23
|
+
* 6. 清理临时目录
|
|
24
|
+
*/
|
|
25
|
+
export declare function syncSkills(config: any): Promise<{
|
|
26
|
+
success: boolean;
|
|
27
|
+
error: string;
|
|
28
|
+
skillCount?: undefined;
|
|
29
|
+
} | {
|
|
30
|
+
success: boolean;
|
|
31
|
+
skillCount: number;
|
|
32
|
+
error?: undefined;
|
|
33
|
+
}>;
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
import { spawn } from 'node:child_process';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { mkdir, rm, cp, access, readFile } from 'node:fs/promises';
|
|
5
|
+
import { getConfigDir, loadConfig, saveConfig } from '../config/manager.js';
|
|
6
|
+
import { logger } from '../cli/logger.js';
|
|
7
|
+
const SKILLS_DIR_NAME = 'skills';
|
|
8
|
+
const TEMP_CLONE_DIR_NAME = 'ones-skills';
|
|
9
|
+
const SYNC_INTERVAL_MS = 24 * 60 * 60 * 1000; // 1 天
|
|
10
|
+
/**
|
|
11
|
+
* 获取 Skills 目录路径 ~/.onesclaw/skills/
|
|
12
|
+
*/
|
|
13
|
+
export function getSkillsDir() {
|
|
14
|
+
return join(getConfigDir(), SKILLS_DIR_NAME);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* 获取临时克隆目录路径 ~/.onesclaw/ones-skills/
|
|
18
|
+
*/
|
|
19
|
+
function getTempCloneDir() {
|
|
20
|
+
return join(getConfigDir(), TEMP_CLONE_DIR_NAME);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* 检查文件是否存在
|
|
24
|
+
*/
|
|
25
|
+
async function fileExists(path) {
|
|
26
|
+
try {
|
|
27
|
+
await access(path);
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* 检查 git 是否可用
|
|
36
|
+
*/
|
|
37
|
+
async function checkGitAvailable() {
|
|
38
|
+
return new Promise((resolve) => {
|
|
39
|
+
const child = spawn('git', ['--version'], {
|
|
40
|
+
stdio: ['ignore', 'ignore', 'ignore'],
|
|
41
|
+
});
|
|
42
|
+
child.on('close', (code) => resolve(code === 0));
|
|
43
|
+
child.on('error', () => resolve(false));
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* 执行 git clone --depth 1
|
|
48
|
+
*/
|
|
49
|
+
function gitClone(repoUrl, targetDir) {
|
|
50
|
+
return new Promise((resolve, reject) => {
|
|
51
|
+
const child = spawn('git', ['clone', '--depth', '1', repoUrl, targetDir], { stdio: ['ignore', 'pipe', 'pipe'] });
|
|
52
|
+
let stderr = '';
|
|
53
|
+
child.stderr?.on('data', (data) => {
|
|
54
|
+
stderr += data.toString();
|
|
55
|
+
});
|
|
56
|
+
child.on('close', (code) => {
|
|
57
|
+
if (code === 0)
|
|
58
|
+
resolve();
|
|
59
|
+
else
|
|
60
|
+
reject(new Error(`git clone 失败 (exit ${code}): ${stderr.trim()}`));
|
|
61
|
+
});
|
|
62
|
+
child.on('error', (err) => reject(err));
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* 检查是否需要同步 Skills
|
|
67
|
+
*
|
|
68
|
+
* 满足任一条件返回 true:
|
|
69
|
+
* 1. ~/.onesclaw/skills/index.json 不存在
|
|
70
|
+
* 2. ones_skills.last_updated_at 不存在
|
|
71
|
+
* 3. last_updated_at 距今超过 1 天
|
|
72
|
+
*/
|
|
73
|
+
export async function needsSync(config) {
|
|
74
|
+
// 检查 index.json 是否存在
|
|
75
|
+
const indexPath = join(getSkillsDir(), 'index.json');
|
|
76
|
+
if (!(await fileExists(indexPath))) {
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
// 检查更新时间
|
|
80
|
+
const lastUpdatedAt = config.ones_skills?.last_updated_at;
|
|
81
|
+
if (!lastUpdatedAt) {
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
const lastSync = new Date(lastUpdatedAt).getTime();
|
|
85
|
+
if (isNaN(lastSync)) {
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
return Date.now() - lastSync > SYNC_INTERVAL_MS;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* 执行 Skills 同步
|
|
92
|
+
*
|
|
93
|
+
* 流程:
|
|
94
|
+
* 1. 检查 git 可用性
|
|
95
|
+
* 2. clone 仓库到临时目录
|
|
96
|
+
* 3. 验证 index.json 存在
|
|
97
|
+
* 4. 全量替换 ~/.onesclaw/skills/
|
|
98
|
+
* 5. 更新 config.ones_skills.last_updated_at
|
|
99
|
+
* 6. 清理临时目录
|
|
100
|
+
*/
|
|
101
|
+
export async function syncSkills(config) {
|
|
102
|
+
const tempDir = getTempCloneDir();
|
|
103
|
+
const skillsDir = getSkillsDir();
|
|
104
|
+
try {
|
|
105
|
+
// 1. 检查 git 可用性
|
|
106
|
+
if (!(await checkGitAvailable())) {
|
|
107
|
+
return {
|
|
108
|
+
success: false,
|
|
109
|
+
error: 'git 未安装,请先安装 git 后重试',
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
// 2. 确定仓库地址
|
|
113
|
+
if (!config.ones_skills?.repository) {
|
|
114
|
+
return {
|
|
115
|
+
success: false,
|
|
116
|
+
error: '未配置 ones_skills.repository,请在 ~/.onesclaw/config.json 中设置',
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
const repoUrl = config.ones_skills.repository;
|
|
120
|
+
// 3. 清理可能残留的临时目录
|
|
121
|
+
await rm(tempDir, { recursive: true, force: true });
|
|
122
|
+
// 4. 克隆仓库
|
|
123
|
+
await gitClone(repoUrl, tempDir);
|
|
124
|
+
// 5. 验证克隆内容含 index.json
|
|
125
|
+
const tempIndexPath = join(tempDir, 'index.json');
|
|
126
|
+
if (!(await fileExists(tempIndexPath))) {
|
|
127
|
+
return {
|
|
128
|
+
success: false,
|
|
129
|
+
error: '仓库中未找到 index.json',
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
// 6. 全量替换 skills 目录
|
|
133
|
+
await rm(skillsDir, { recursive: true, force: true });
|
|
134
|
+
await mkdir(skillsDir, { recursive: true });
|
|
135
|
+
await cp(tempDir, skillsDir, {
|
|
136
|
+
recursive: true,
|
|
137
|
+
filter: (src) => !src.includes('/.git'),
|
|
138
|
+
});
|
|
139
|
+
// 7. 读取 skill 数量
|
|
140
|
+
let skillCount = 0;
|
|
141
|
+
try {
|
|
142
|
+
const indexContent = await readFile(join(skillsDir, 'index.json'), 'utf-8');
|
|
143
|
+
const index = JSON.parse(indexContent);
|
|
144
|
+
skillCount = index.skills.length;
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
// 解析失败不阻塞
|
|
148
|
+
}
|
|
149
|
+
// 8. 更新配置
|
|
150
|
+
try {
|
|
151
|
+
const freshConfig = await loadConfig();
|
|
152
|
+
if (freshConfig) {
|
|
153
|
+
if (!freshConfig.ones_skills) {
|
|
154
|
+
freshConfig.ones_skills = { repository: repoUrl };
|
|
155
|
+
}
|
|
156
|
+
freshConfig.ones_skills.last_updated_at = new Date().toISOString();
|
|
157
|
+
await saveConfig(freshConfig);
|
|
158
|
+
// 同步回调用方的 config 对象
|
|
159
|
+
if (!config.ones_skills) {
|
|
160
|
+
config.ones_skills = { repository: repoUrl };
|
|
161
|
+
}
|
|
162
|
+
config.ones_skills.last_updated_at = freshConfig.ones_skills.last_updated_at;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
catch (err) {
|
|
166
|
+
logger.error('skills', `更新 config 失败: ${err instanceof Error ? err.message : String(err)}`);
|
|
167
|
+
}
|
|
168
|
+
return { success: true, skillCount };
|
|
169
|
+
}
|
|
170
|
+
finally {
|
|
171
|
+
// 9. 清理临时目录
|
|
172
|
+
try {
|
|
173
|
+
await rm(tempDir, { recursive: true, force: true });
|
|
174
|
+
}
|
|
175
|
+
catch {
|
|
176
|
+
// 清理失败不阻塞
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=sync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/skills/sync.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/skills/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 设置用户输入回调
|
|
3
|
+
* 由 REPL 层在 readline 创建后调用
|
|
4
|
+
*/
|
|
5
|
+
export declare function setPromptUser(fn: any): void;
|
|
6
|
+
/**
|
|
7
|
+
* 创建 ask_user 工具
|
|
8
|
+
* 让 Agent 在执行危险操作前暂停并请求用户确认或收集参数
|
|
9
|
+
*/
|
|
10
|
+
export declare function createAskUserTool(): {
|
|
11
|
+
name: string;
|
|
12
|
+
description: string;
|
|
13
|
+
inputSchema: {
|
|
14
|
+
type: string;
|
|
15
|
+
properties: {
|
|
16
|
+
question: {
|
|
17
|
+
type: string;
|
|
18
|
+
description: string;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
required: string[];
|
|
22
|
+
};
|
|
23
|
+
execute: (args: any) => Promise<{
|
|
24
|
+
content: string;
|
|
25
|
+
isError: boolean;
|
|
26
|
+
} | {
|
|
27
|
+
content: any;
|
|
28
|
+
isError?: undefined;
|
|
29
|
+
}>;
|
|
30
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
import { UserInterruptError } from '../errors.js';
|
|
3
|
+
import { issueFromAskUser } from './confirmation.js';
|
|
4
|
+
/**
|
|
5
|
+
* 模块级 promptUser 引用
|
|
6
|
+
* 通过 setPromptUser() 延迟绑定,由 REPL 层在创建 readline 后注入
|
|
7
|
+
*/
|
|
8
|
+
let _promptUser = null;
|
|
9
|
+
/**
|
|
10
|
+
* 设置用户输入回调
|
|
11
|
+
* 由 REPL 层在 readline 创建后调用
|
|
12
|
+
*/
|
|
13
|
+
export function setPromptUser(fn) {
|
|
14
|
+
_promptUser = fn;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* 创建 ask_user 工具
|
|
18
|
+
* 让 Agent 在执行危险操作前暂停并请求用户确认或收集参数
|
|
19
|
+
*/
|
|
20
|
+
export function createAskUserTool() {
|
|
21
|
+
return {
|
|
22
|
+
name: 'ask_user',
|
|
23
|
+
description: '向用户请求确认或输入信息。用于危险操作确认(如卸载、删除)或收集必要参数(如服务器地址、版本号)。重要:每次调用只问一个问题,用户每次只能输入一行文本。如需收集多个参数,必须多次调用此工具,每次只问一个问题。',
|
|
24
|
+
inputSchema: {
|
|
25
|
+
type: 'object',
|
|
26
|
+
properties: {
|
|
27
|
+
question: {
|
|
28
|
+
type: 'string',
|
|
29
|
+
description: '要向用户提问的内容。每次只问一个问题,不要在一次调用中包含多个问题。',
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
required: ['question'],
|
|
33
|
+
},
|
|
34
|
+
execute: async (args) => {
|
|
35
|
+
const question = args.question;
|
|
36
|
+
if (!_promptUser) {
|
|
37
|
+
return {
|
|
38
|
+
content: '用户输入不可用(非交互模式)',
|
|
39
|
+
isError: true,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
try {
|
|
43
|
+
const answer = await _promptUser(question);
|
|
44
|
+
issueFromAskUser(question, answer);
|
|
45
|
+
return { content: answer };
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
// 用户中断:放行,让错误传播到 agent loop 以终止当前任务
|
|
49
|
+
if (error instanceof UserInterruptError) {
|
|
50
|
+
throw error;
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
content: `获取用户输入失败: ${error instanceof Error ? error.message : String(error)}`,
|
|
54
|
+
isError: true,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=ask.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ask.js","sourceRoot":"","sources":["../../src/tools/ask.ts"],"names":[],"mappings":"AAAA,cAAc;AACd,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD;;;GAGG;AACH,IAAI,WAAW,GAAG,IAAI,CAAC;AACvB;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,EAAE;IAC5B,WAAW,GAAG,EAAE,CAAC;AACrB,CAAC;AACD;;;GAGG;AACH,MAAM,UAAU,iBAAiB;IAC7B,OAAO;QACH,IAAI,EAAE,UAAU;QAChB,WAAW,EAAE,0GAA0G;QACvH,WAAW,EAAE;YACT,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACR,QAAQ,EAAE;oBACN,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,oCAAoC;iBACpD;aACJ;YACD,QAAQ,EAAE,CAAC,UAAU,CAAC;SACzB;QACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;YACpB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;YAC/B,IAAI,CAAC,WAAW,EAAE,CAAC;gBACf,OAAO;oBACH,OAAO,EAAE,gBAAgB;oBACzB,OAAO,EAAE,IAAI;iBAChB,CAAC;YACN,CAAC;YACD,IAAI,CAAC;gBACD,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,QAAQ,CAAC,CAAC;gBAC3C,gBAAgB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;gBACnC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;YAC/B,CAAC;YACD,OAAO,KAAK,EAAE,CAAC;gBACX,oCAAoC;gBACpC,IAAI,KAAK,YAAY,kBAAkB,EAAE,CAAC;oBACtC,MAAM,KAAK,CAAC;gBAChB,CAAC;gBACD,OAAO;oBACH,OAAO,EAAE,aAAa,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;oBAC9E,OAAO,EAAE,IAAI;iBAChB,CAAC;YACN,CAAC;QACL,CAAC;KACJ,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type ProofIssueStatus = 'issued' | 'rejected' | 'ambiguous' | 'empty';
|
|
2
|
+
export type ProofConsumeStatus = 'valid' | 'missing' | 'expired' | 'already_used';
|
|
3
|
+
export declare function issueFromAskUser(question: string, answer: string, now?: number): {
|
|
4
|
+
issued: boolean;
|
|
5
|
+
status: ProofIssueStatus;
|
|
6
|
+
};
|
|
7
|
+
export declare function consumeForHighRisk(_command: string, now?: number): {
|
|
8
|
+
ok: boolean;
|
|
9
|
+
status: ProofConsumeStatus;
|
|
10
|
+
};
|
|
11
|
+
export declare function requireConfirmationProofError(command: string, status: ProofConsumeStatus): string;
|
|
12
|
+
export declare function resetForTest(): void;
|