@shareai-lab/kode-sdk 1.0.0-beta.9 → 2.7.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/LICENSE +21 -0
- package/README.md +115 -273
- package/README.zh-CN.md +114 -0
- package/dist/core/agent/breakpoint-manager.d.ts +16 -0
- package/dist/core/agent/breakpoint-manager.js +36 -0
- package/dist/core/agent/message-queue.d.ts +26 -0
- package/dist/core/agent/message-queue.js +57 -0
- package/dist/core/agent/permission-manager.d.ts +9 -0
- package/dist/core/agent/permission-manager.js +32 -0
- package/dist/core/agent/todo-manager.d.ts +26 -0
- package/dist/core/agent/todo-manager.js +91 -0
- package/dist/core/agent/tool-runner.d.ts +9 -0
- package/dist/core/agent/tool-runner.js +45 -0
- package/dist/core/agent.d.ts +228 -62
- package/dist/core/agent.js +1890 -615
- package/dist/core/config.d.ts +10 -0
- package/dist/core/config.js +2 -0
- package/dist/core/context-manager.d.ts +82 -0
- package/dist/core/context-manager.js +241 -0
- package/dist/core/errors.d.ts +22 -0
- package/dist/core/errors.js +49 -0
- package/dist/core/events.d.ts +41 -10
- package/dist/core/events.js +270 -68
- package/dist/core/file-pool.d.ts +41 -0
- package/dist/core/file-pool.js +102 -0
- package/dist/core/hooks.d.ts +3 -3
- package/dist/core/hooks.js +1 -1
- package/dist/core/permission-modes.d.ts +31 -0
- package/dist/core/permission-modes.js +61 -0
- package/dist/core/pool.d.ts +56 -13
- package/dist/core/pool.js +244 -34
- package/dist/core/room.d.ts +2 -2
- package/dist/core/room.js +10 -10
- package/dist/core/scheduler.d.ts +30 -23
- package/dist/core/scheduler.js +42 -168
- package/dist/core/skills/index.d.ts +10 -0
- package/dist/core/skills/index.js +20 -0
- package/dist/core/skills/management-manager.d.ts +130 -0
- package/dist/core/skills/management-manager.js +557 -0
- package/dist/core/skills/manager.d.ts +47 -0
- package/dist/core/skills/manager.js +243 -0
- package/dist/core/skills/operation-queue.d.ts +87 -0
- package/dist/core/skills/operation-queue.js +113 -0
- package/dist/core/skills/sandbox-file-manager.d.ts +82 -0
- package/dist/core/skills/sandbox-file-manager.js +183 -0
- package/dist/core/skills/types.d.ts +120 -0
- package/dist/core/skills/types.js +9 -0
- package/dist/core/skills/xml-generator.d.ts +13 -0
- package/dist/core/skills/xml-generator.js +70 -0
- package/dist/core/template.d.ts +57 -0
- package/dist/core/template.js +35 -0
- package/dist/core/time-bridge.d.ts +18 -0
- package/dist/core/time-bridge.js +100 -0
- package/dist/core/todo.d.ts +34 -0
- package/dist/core/todo.js +89 -0
- package/dist/core/types.d.ts +311 -114
- package/dist/core/types.js +1 -12
- package/dist/index.d.ts +47 -9
- package/dist/index.js +108 -15
- package/dist/infra/db/postgres/postgres-store.d.ts +97 -0
- package/dist/infra/db/postgres/postgres-store.js +1073 -0
- package/dist/infra/db/sqlite/sqlite-store.d.ts +84 -0
- package/dist/infra/db/sqlite/sqlite-store.js +800 -0
- package/dist/infra/e2b/e2b-fs.d.ts +29 -0
- package/dist/infra/e2b/e2b-fs.js +128 -0
- package/dist/infra/e2b/e2b-sandbox.d.ts +37 -0
- package/dist/infra/e2b/e2b-sandbox.js +156 -0
- package/dist/infra/e2b/e2b-template.d.ts +24 -0
- package/dist/infra/e2b/e2b-template.js +105 -0
- package/dist/infra/e2b/index.d.ts +4 -0
- package/dist/infra/e2b/index.js +9 -0
- package/dist/infra/e2b/types.d.ts +46 -0
- package/dist/infra/e2b/types.js +2 -0
- package/dist/infra/provider.d.ts +17 -58
- package/dist/infra/provider.js +65 -116
- package/dist/infra/providers/anthropic.d.ts +42 -0
- package/dist/infra/providers/anthropic.js +308 -0
- package/dist/infra/providers/core/errors.d.ts +230 -0
- package/dist/infra/providers/core/errors.js +353 -0
- package/dist/infra/providers/core/fork.d.ts +106 -0
- package/dist/infra/providers/core/fork.js +418 -0
- package/dist/infra/providers/core/index.d.ts +10 -0
- package/dist/infra/providers/core/index.js +76 -0
- package/dist/infra/providers/core/logger.d.ts +186 -0
- package/dist/infra/providers/core/logger.js +191 -0
- package/dist/infra/providers/core/retry.d.ts +62 -0
- package/dist/infra/providers/core/retry.js +189 -0
- package/dist/infra/providers/core/usage.d.ts +151 -0
- package/dist/infra/providers/core/usage.js +376 -0
- package/dist/infra/providers/gemini.d.ts +49 -0
- package/dist/infra/providers/gemini.js +493 -0
- package/dist/infra/providers/index.d.ts +25 -0
- package/dist/infra/providers/index.js +83 -0
- package/dist/infra/providers/openai.d.ts +123 -0
- package/dist/infra/providers/openai.js +662 -0
- package/dist/infra/providers/types.d.ts +334 -0
- package/dist/infra/providers/types.js +20 -0
- package/dist/infra/providers/utils.d.ts +53 -0
- package/dist/infra/providers/utils.js +400 -0
- package/dist/infra/sandbox-factory.d.ts +13 -0
- package/dist/infra/sandbox-factory.js +30 -0
- package/dist/infra/sandbox.d.ts +35 -6
- package/dist/infra/sandbox.js +174 -8
- package/dist/infra/store/factory.d.ts +45 -0
- package/dist/infra/store/factory.js +80 -0
- package/dist/infra/store/index.d.ts +3 -0
- package/dist/infra/store/index.js +26 -0
- package/dist/infra/store/json-store.d.ts +67 -0
- package/dist/infra/store/json-store.js +606 -0
- package/dist/infra/store/types.d.ts +342 -0
- package/dist/infra/store/types.js +2 -0
- package/dist/infra/store.d.ts +12 -32
- package/dist/infra/store.js +27 -130
- package/dist/tools/bash_kill/index.d.ts +1 -0
- package/dist/tools/bash_kill/index.js +35 -0
- package/dist/tools/bash_kill/prompt.d.ts +2 -0
- package/dist/tools/bash_kill/prompt.js +14 -0
- package/dist/tools/bash_logs/index.d.ts +1 -0
- package/dist/tools/bash_logs/index.js +40 -0
- package/dist/tools/bash_logs/prompt.d.ts +2 -0
- package/dist/tools/bash_logs/prompt.js +14 -0
- package/dist/tools/bash_run/index.d.ts +16 -0
- package/dist/tools/bash_run/index.js +61 -0
- package/dist/tools/bash_run/prompt.d.ts +2 -0
- package/dist/tools/bash_run/prompt.js +18 -0
- package/dist/tools/builtin.d.ts +7 -13
- package/dist/tools/builtin.js +19 -90
- package/dist/tools/define.d.ts +101 -0
- package/dist/tools/define.js +214 -0
- package/dist/tools/fs_edit/index.d.ts +1 -0
- package/dist/tools/fs_edit/index.js +62 -0
- package/dist/tools/fs_edit/prompt.d.ts +2 -0
- package/dist/tools/fs_edit/prompt.js +15 -0
- package/dist/tools/fs_glob/index.d.ts +1 -0
- package/dist/tools/fs_glob/index.js +40 -0
- package/dist/tools/fs_glob/prompt.d.ts +2 -0
- package/dist/tools/fs_glob/prompt.js +15 -0
- package/dist/tools/fs_grep/index.d.ts +1 -0
- package/dist/tools/fs_grep/index.js +66 -0
- package/dist/tools/fs_grep/prompt.d.ts +2 -0
- package/dist/tools/fs_grep/prompt.js +16 -0
- package/dist/tools/fs_multi_edit/index.d.ts +1 -0
- package/dist/tools/fs_multi_edit/index.js +106 -0
- package/dist/tools/fs_multi_edit/prompt.d.ts +2 -0
- package/dist/tools/fs_multi_edit/prompt.js +16 -0
- package/dist/tools/fs_read/index.d.ts +1 -0
- package/dist/tools/fs_read/index.js +40 -0
- package/dist/tools/fs_read/prompt.d.ts +2 -0
- package/dist/tools/fs_read/prompt.js +16 -0
- package/dist/tools/fs_write/index.d.ts +1 -0
- package/dist/tools/fs_write/index.js +40 -0
- package/dist/tools/fs_write/prompt.d.ts +2 -0
- package/dist/tools/fs_write/prompt.js +15 -0
- package/dist/tools/index.d.ts +11 -0
- package/dist/tools/index.js +61 -0
- package/dist/tools/mcp.d.ts +69 -0
- package/dist/tools/mcp.js +185 -0
- package/dist/tools/registry.d.ts +29 -0
- package/dist/tools/registry.js +26 -0
- package/dist/tools/scripts.d.ts +22 -0
- package/dist/tools/scripts.js +205 -0
- package/dist/tools/skills.d.ts +20 -0
- package/dist/tools/skills.js +115 -0
- package/dist/tools/task_run/index.d.ts +7 -0
- package/dist/tools/task_run/index.js +58 -0
- package/dist/tools/task_run/prompt.d.ts +5 -0
- package/dist/tools/task_run/prompt.js +25 -0
- package/dist/tools/todo_read/index.d.ts +1 -0
- package/dist/tools/todo_read/index.js +29 -0
- package/dist/tools/todo_read/prompt.d.ts +2 -0
- package/dist/tools/todo_read/prompt.js +18 -0
- package/dist/tools/todo_write/index.d.ts +1 -0
- package/dist/tools/todo_write/index.js +42 -0
- package/dist/tools/todo_write/prompt.d.ts +2 -0
- package/dist/tools/todo_write/prompt.js +23 -0
- package/dist/tools/tool.d.ts +43 -0
- package/dist/tools/tool.js +211 -0
- package/dist/tools/toolkit.d.ts +69 -0
- package/dist/tools/toolkit.js +98 -0
- package/dist/tools/type-inference.d.ts +127 -0
- package/dist/tools/type-inference.js +207 -0
- package/dist/utils/agent-id.d.ts +1 -0
- package/dist/utils/agent-id.js +28 -0
- package/dist/utils/logger.d.ts +15 -0
- package/dist/utils/logger.js +44 -0
- package/dist/utils/session-id.js +16 -16
- package/package.json +35 -11
- package/dist/tools/bash.d.ts +0 -63
- package/dist/tools/bash.js +0 -92
- package/dist/tools/fs.d.ts +0 -96
- package/dist/tools/fs.js +0 -100
- package/dist/tools/task.d.ts +0 -38
- package/dist/tools/task.js +0 -45
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Skills 管理器
|
|
4
|
+
*
|
|
5
|
+
* 设计原则 (UNIX哲学):
|
|
6
|
+
* - 简洁: 只负责扫描和加载skills,不处理业务逻辑
|
|
7
|
+
* - 模块化: 单一职责,易于测试和维护
|
|
8
|
+
* - 热更新: 每次调用都重新扫描文件系统,确保数据最新
|
|
9
|
+
*/
|
|
10
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
13
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
14
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
15
|
+
}
|
|
16
|
+
Object.defineProperty(o, k2, desc);
|
|
17
|
+
}) : (function(o, m, k, k2) {
|
|
18
|
+
if (k2 === undefined) k2 = k;
|
|
19
|
+
o[k2] = m[k];
|
|
20
|
+
}));
|
|
21
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
22
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
23
|
+
}) : function(o, v) {
|
|
24
|
+
o["default"] = v;
|
|
25
|
+
});
|
|
26
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
27
|
+
var ownKeys = function(o) {
|
|
28
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
29
|
+
var ar = [];
|
|
30
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
31
|
+
return ar;
|
|
32
|
+
};
|
|
33
|
+
return ownKeys(o);
|
|
34
|
+
};
|
|
35
|
+
return function (mod) {
|
|
36
|
+
if (mod && mod.__esModule) return mod;
|
|
37
|
+
var result = {};
|
|
38
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
39
|
+
__setModuleDefault(result, mod);
|
|
40
|
+
return result;
|
|
41
|
+
};
|
|
42
|
+
})();
|
|
43
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
44
|
+
exports.SkillsManager = void 0;
|
|
45
|
+
const fs = __importStar(require("fs/promises"));
|
|
46
|
+
const path = __importStar(require("path"));
|
|
47
|
+
const logger_1 = require("../../utils/logger");
|
|
48
|
+
/**
|
|
49
|
+
* Skills 管理器
|
|
50
|
+
*/
|
|
51
|
+
class SkillsManager {
|
|
52
|
+
constructor(skillsDir, allowedSkills) {
|
|
53
|
+
this.cache = new Map();
|
|
54
|
+
// 优先使用传入的路径,其次使用环境变量,最后使用默认路径
|
|
55
|
+
// 默认路径:程序当前工作目录下的 skills/
|
|
56
|
+
const envSkillsDir = process.env.SKILLS_DIR;
|
|
57
|
+
const defaultSkillsDir = path.join(process.cwd(), 'skills');
|
|
58
|
+
this.skillsDir = path.resolve(skillsDir ||
|
|
59
|
+
envSkillsDir ||
|
|
60
|
+
defaultSkillsDir);
|
|
61
|
+
// 设置允许加载的 skills 白名单
|
|
62
|
+
this.allowedSkills = allowedSkills;
|
|
63
|
+
logger_1.logger.log(`[SkillsManager] Initialized with skills directory: ${this.skillsDir}`);
|
|
64
|
+
if (this.allowedSkills) {
|
|
65
|
+
logger_1.logger.log(`[SkillsManager] Allowed skills whitelist: ${this.allowedSkills.join(', ')}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* 扫描skills目录(支持热更新)
|
|
70
|
+
* 每次调用时重新扫描,确保读取最新数据
|
|
71
|
+
*/
|
|
72
|
+
async scan() {
|
|
73
|
+
// 清空缓存
|
|
74
|
+
this.cache.clear();
|
|
75
|
+
try {
|
|
76
|
+
// 检查目录是否存在
|
|
77
|
+
const exists = await this.fileExists(this.skillsDir);
|
|
78
|
+
if (!exists) {
|
|
79
|
+
logger_1.logger.log(`[SkillsManager] Skills directory does not exist: ${this.skillsDir}`);
|
|
80
|
+
return [];
|
|
81
|
+
}
|
|
82
|
+
// 递归扫描skills目录
|
|
83
|
+
const entries = await this.scanDirectory(this.skillsDir);
|
|
84
|
+
// 提取每个skill的元数据
|
|
85
|
+
for (const entry of entries) {
|
|
86
|
+
const metadata = await this.parseSkillMetadata(entry);
|
|
87
|
+
if (metadata) {
|
|
88
|
+
// 如果设置了白名单,只加载白名单中的 skills
|
|
89
|
+
if (this.allowedSkills) {
|
|
90
|
+
if (this.allowedSkills.includes(metadata.name)) {
|
|
91
|
+
this.cache.set(metadata.name, metadata);
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
logger_1.logger.log(`[SkillsManager] Skipping skill not in whitelist: ${metadata.name}`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
// 没有设置白名单,加载所有 skills
|
|
99
|
+
this.cache.set(metadata.name, metadata);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
logger_1.logger.log(`[SkillsManager] Scanned ${this.cache.size} skill(s)`);
|
|
104
|
+
return Array.from(this.cache.values());
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
logger_1.logger.error(`[SkillsManager] Error scanning skills directory:`, error.message);
|
|
108
|
+
return [];
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* 获取所有skills的元数据列表(供LLM选择)
|
|
113
|
+
*/
|
|
114
|
+
async getSkillsMetadata() {
|
|
115
|
+
// 每次调用时重新扫描,支持热更新
|
|
116
|
+
return await this.scan();
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* 加载指定skill的完整内容
|
|
120
|
+
*/
|
|
121
|
+
async loadSkillContent(skillName) {
|
|
122
|
+
// 先扫描确保元数据最新
|
|
123
|
+
await this.scan();
|
|
124
|
+
const metadata = this.cache.get(skillName);
|
|
125
|
+
if (!metadata) {
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
try {
|
|
129
|
+
// 读取SKILL.md内容
|
|
130
|
+
const content = await fs.readFile(metadata.path, 'utf-8');
|
|
131
|
+
// 扫描子目录
|
|
132
|
+
const references = await this.listSubdirectory(metadata.baseDir, 'references');
|
|
133
|
+
const scripts = await this.listSubdirectory(metadata.baseDir, 'scripts');
|
|
134
|
+
const assets = await this.listSubdirectory(metadata.baseDir, 'assets');
|
|
135
|
+
return {
|
|
136
|
+
metadata,
|
|
137
|
+
content,
|
|
138
|
+
references,
|
|
139
|
+
scripts,
|
|
140
|
+
assets,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
logger_1.logger.error(`[SkillsManager] Error loading skill content:`, error.message);
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* 递归扫描目录,查找所有SKILL.md
|
|
150
|
+
*/
|
|
151
|
+
async scanDirectory(dir) {
|
|
152
|
+
const skillFiles = [];
|
|
153
|
+
try {
|
|
154
|
+
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
155
|
+
for (const entry of entries) {
|
|
156
|
+
const fullPath = path.join(dir, entry.name);
|
|
157
|
+
if (entry.isDirectory()) {
|
|
158
|
+
// 检查是否有SKILL.md
|
|
159
|
+
const skillMdPath = path.join(fullPath, 'SKILL.md');
|
|
160
|
+
if (await this.fileExists(skillMdPath)) {
|
|
161
|
+
skillFiles.push(skillMdPath);
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
// 递归扫描子目录
|
|
165
|
+
const subSkills = await this.scanDirectory(fullPath);
|
|
166
|
+
skillFiles.push(...subSkills);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
catch (error) {
|
|
172
|
+
logger_1.logger.warn(`[SkillsManager] Error reading directory ${dir}:`, error.message);
|
|
173
|
+
}
|
|
174
|
+
return skillFiles;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* 解析SKILL.md,提取元数据
|
|
178
|
+
*/
|
|
179
|
+
async parseSkillMetadata(skillMdPath) {
|
|
180
|
+
try {
|
|
181
|
+
const content = await fs.readFile(skillMdPath, 'utf-8');
|
|
182
|
+
// 提取YAML frontmatter
|
|
183
|
+
const match = content.match(/^---\n([\s\S]+?)\n---/);
|
|
184
|
+
if (!match) {
|
|
185
|
+
logger_1.logger.warn(`[SkillsManager] Invalid SKILL.md (missing YAML frontmatter): ${skillMdPath}`);
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
const yaml = match[1];
|
|
189
|
+
const nameMatch = yaml.match(/^name:\s*(.+)$/m);
|
|
190
|
+
const descMatch = yaml.match(/^description:\s*(.+)$/m);
|
|
191
|
+
if (!nameMatch) {
|
|
192
|
+
logger_1.logger.warn(`[SkillsManager] Invalid SKILL.md (missing name): ${skillMdPath}`);
|
|
193
|
+
return null;
|
|
194
|
+
}
|
|
195
|
+
return {
|
|
196
|
+
name: nameMatch[1].trim(),
|
|
197
|
+
description: descMatch ? descMatch[1].trim() : '',
|
|
198
|
+
path: skillMdPath,
|
|
199
|
+
baseDir: path.dirname(skillMdPath),
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
catch (error) {
|
|
203
|
+
logger_1.logger.warn(`[SkillsManager] Error parsing ${skillMdPath}:`, error.message);
|
|
204
|
+
return null;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* 列出子目录下的文件
|
|
209
|
+
*/
|
|
210
|
+
async listSubdirectory(baseDir, subdir) {
|
|
211
|
+
const fullPath = path.join(baseDir, subdir);
|
|
212
|
+
if (!(await this.fileExists(fullPath))) {
|
|
213
|
+
return [];
|
|
214
|
+
}
|
|
215
|
+
const files = [];
|
|
216
|
+
try {
|
|
217
|
+
const entries = await fs.readdir(fullPath, { withFileTypes: true });
|
|
218
|
+
for (const entry of entries) {
|
|
219
|
+
if (entry.isFile()) {
|
|
220
|
+
files.push(path.join(fullPath, entry.name));
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
catch (error) {
|
|
225
|
+
// 目录不存在或无权限访问,返回空数组
|
|
226
|
+
logger_1.logger.debug(`[SkillsManager] Subdirectory not accessible: ${fullPath}`);
|
|
227
|
+
}
|
|
228
|
+
return files;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* 检查文件是否存在
|
|
232
|
+
*/
|
|
233
|
+
async fileExists(filePath) {
|
|
234
|
+
try {
|
|
235
|
+
await fs.access(filePath);
|
|
236
|
+
return true;
|
|
237
|
+
}
|
|
238
|
+
catch {
|
|
239
|
+
return false;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
exports.SkillsManager = SkillsManager;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 操作队列模块
|
|
3
|
+
*
|
|
4
|
+
* 设计原则 (UNIX哲学):
|
|
5
|
+
* - 简洁: 只负责队列管理,单一职责
|
|
6
|
+
* - 模块化: 独立的队列逻辑,易于测试和维护
|
|
7
|
+
* - 隔离: 与技能管理逻辑分离,专注于并发控制
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* 操作类型枚举
|
|
11
|
+
*/
|
|
12
|
+
export declare enum OperationType {
|
|
13
|
+
CREATE = "create",
|
|
14
|
+
RENAME = "rename",
|
|
15
|
+
EDIT = "edit",
|
|
16
|
+
DELETE = "delete",
|
|
17
|
+
RESTORE = "restore"
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* 操作状态枚举
|
|
21
|
+
*/
|
|
22
|
+
export declare enum OperationStatus {
|
|
23
|
+
PENDING = "pending",
|
|
24
|
+
PROCESSING = "processing",
|
|
25
|
+
COMPLETED = "completed",
|
|
26
|
+
FAILED = "failed"
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* 操作任务接口
|
|
30
|
+
*/
|
|
31
|
+
export interface OperationTask {
|
|
32
|
+
/** 操作ID */
|
|
33
|
+
id: string;
|
|
34
|
+
/** 操作类型 */
|
|
35
|
+
type: OperationType;
|
|
36
|
+
/** 目标技能 */
|
|
37
|
+
targetSkill: string;
|
|
38
|
+
/** 操作状态 */
|
|
39
|
+
status: OperationStatus;
|
|
40
|
+
/** 执行操作 */
|
|
41
|
+
execute(): Promise<void>;
|
|
42
|
+
/** 创建时间 */
|
|
43
|
+
createdAt: Date;
|
|
44
|
+
/** 开始时间 */
|
|
45
|
+
startedAt?: Date;
|
|
46
|
+
/** 完成时间 */
|
|
47
|
+
completedAt?: Date;
|
|
48
|
+
/** 错误信息 */
|
|
49
|
+
error?: Error;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* 操作队列类
|
|
53
|
+
*
|
|
54
|
+
* 职责:
|
|
55
|
+
* - 管理技能管理操作的并发执行
|
|
56
|
+
* - 按FIFO顺序处理操作
|
|
57
|
+
* - 防止操作冲突
|
|
58
|
+
*/
|
|
59
|
+
export declare class OperationQueue {
|
|
60
|
+
private queue;
|
|
61
|
+
private processing;
|
|
62
|
+
private readonly maxConcurrent;
|
|
63
|
+
/**
|
|
64
|
+
* 入队操作
|
|
65
|
+
*/
|
|
66
|
+
enqueue(task: OperationTask): Promise<void>;
|
|
67
|
+
/**
|
|
68
|
+
* 出队操作
|
|
69
|
+
*/
|
|
70
|
+
private dequeue;
|
|
71
|
+
/**
|
|
72
|
+
* 处理队列
|
|
73
|
+
*/
|
|
74
|
+
private processQueue;
|
|
75
|
+
/**
|
|
76
|
+
* 获取队列状态
|
|
77
|
+
*/
|
|
78
|
+
getQueueStatus(): {
|
|
79
|
+
length: number;
|
|
80
|
+
processing: boolean;
|
|
81
|
+
tasks: OperationTask[];
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* 清空队列
|
|
85
|
+
*/
|
|
86
|
+
clear(): void;
|
|
87
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* 操作队列模块
|
|
4
|
+
*
|
|
5
|
+
* 设计原则 (UNIX哲学):
|
|
6
|
+
* - 简洁: 只负责队列管理,单一职责
|
|
7
|
+
* - 模块化: 独立的队列逻辑,易于测试和维护
|
|
8
|
+
* - 隔离: 与技能管理逻辑分离,专注于并发控制
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.OperationQueue = exports.OperationStatus = exports.OperationType = void 0;
|
|
12
|
+
const logger_1 = require("../../utils/logger");
|
|
13
|
+
/**
|
|
14
|
+
* 操作类型枚举
|
|
15
|
+
*/
|
|
16
|
+
var OperationType;
|
|
17
|
+
(function (OperationType) {
|
|
18
|
+
OperationType["CREATE"] = "create";
|
|
19
|
+
OperationType["RENAME"] = "rename";
|
|
20
|
+
OperationType["EDIT"] = "edit";
|
|
21
|
+
OperationType["DELETE"] = "delete";
|
|
22
|
+
OperationType["RESTORE"] = "restore";
|
|
23
|
+
})(OperationType || (exports.OperationType = OperationType = {}));
|
|
24
|
+
/**
|
|
25
|
+
* 操作状态枚举
|
|
26
|
+
*/
|
|
27
|
+
var OperationStatus;
|
|
28
|
+
(function (OperationStatus) {
|
|
29
|
+
OperationStatus["PENDING"] = "pending";
|
|
30
|
+
OperationStatus["PROCESSING"] = "processing";
|
|
31
|
+
OperationStatus["COMPLETED"] = "completed";
|
|
32
|
+
OperationStatus["FAILED"] = "failed";
|
|
33
|
+
})(OperationStatus || (exports.OperationStatus = OperationStatus = {}));
|
|
34
|
+
/**
|
|
35
|
+
* 操作队列类
|
|
36
|
+
*
|
|
37
|
+
* 职责:
|
|
38
|
+
* - 管理技能管理操作的并发执行
|
|
39
|
+
* - 按FIFO顺序处理操作
|
|
40
|
+
* - 防止操作冲突
|
|
41
|
+
*/
|
|
42
|
+
class OperationQueue {
|
|
43
|
+
constructor() {
|
|
44
|
+
this.queue = [];
|
|
45
|
+
this.processing = false;
|
|
46
|
+
this.maxConcurrent = 1; // 串行执行,避免冲突
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* 入队操作
|
|
50
|
+
*/
|
|
51
|
+
async enqueue(task) {
|
|
52
|
+
this.queue.push(task);
|
|
53
|
+
logger_1.logger.log(`[OperationQueue] 操作已入队: ${task.type} - ${task.targetSkill}`);
|
|
54
|
+
// 如果没有正在处理,启动处理(不等待,异步执行)
|
|
55
|
+
if (!this.processing) {
|
|
56
|
+
// 不使用await,让队列异步处理
|
|
57
|
+
this.processQueue().catch(error => {
|
|
58
|
+
logger_1.logger.error('[OperationQueue] Queue processing error:', error);
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* 出队操作
|
|
64
|
+
*/
|
|
65
|
+
dequeue() {
|
|
66
|
+
return this.queue.shift() || null;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* 处理队列
|
|
70
|
+
*/
|
|
71
|
+
async processQueue() {
|
|
72
|
+
this.processing = true;
|
|
73
|
+
while (this.queue.length > 0) {
|
|
74
|
+
const task = this.dequeue();
|
|
75
|
+
if (!task)
|
|
76
|
+
break;
|
|
77
|
+
task.status = OperationStatus.PROCESSING;
|
|
78
|
+
task.startedAt = new Date();
|
|
79
|
+
try {
|
|
80
|
+
logger_1.logger.log(`[OperationQueue] 开始处理: ${task.type} - ${task.targetSkill}`);
|
|
81
|
+
await task.execute();
|
|
82
|
+
task.status = OperationStatus.COMPLETED;
|
|
83
|
+
task.completedAt = new Date();
|
|
84
|
+
logger_1.logger.log(`[OperationQueue] 操作完成: ${task.type} - ${task.targetSkill}`);
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
task.status = OperationStatus.FAILED;
|
|
88
|
+
task.completedAt = new Date();
|
|
89
|
+
task.error = error;
|
|
90
|
+
logger_1.logger.error(`[OperationQueue] 操作失败: ${task.type} - ${task.targetSkill}`, error);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
this.processing = false;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* 获取队列状态
|
|
97
|
+
*/
|
|
98
|
+
getQueueStatus() {
|
|
99
|
+
return {
|
|
100
|
+
length: this.queue.length,
|
|
101
|
+
processing: this.processing,
|
|
102
|
+
tasks: [...this.queue],
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* 清空队列
|
|
107
|
+
*/
|
|
108
|
+
clear() {
|
|
109
|
+
this.queue = [];
|
|
110
|
+
logger_1.logger.log('[OperationQueue] 队列已清空');
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
exports.OperationQueue = OperationQueue;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sandbox文件管理器模块
|
|
3
|
+
*
|
|
4
|
+
* 设计原则 (UNIX哲学):
|
|
5
|
+
* - 简洁: 只负责sandbox中的文件操作
|
|
6
|
+
* - 模块化: 独立的文件操作逻辑
|
|
7
|
+
* - 安全: 强制边界控制,确保只能访问技能目录内文件
|
|
8
|
+
*/
|
|
9
|
+
import { SandboxFactory } from '../../infra/sandbox-factory';
|
|
10
|
+
/**
|
|
11
|
+
* 文件树节点接口
|
|
12
|
+
*/
|
|
13
|
+
export interface SkillFileTree {
|
|
14
|
+
/** 文件/目录名 */
|
|
15
|
+
name: string;
|
|
16
|
+
/** 类型 */
|
|
17
|
+
type: 'file' | 'dir';
|
|
18
|
+
/** 相对于技能根目录的路径 */
|
|
19
|
+
path: string;
|
|
20
|
+
/** 文件大小(字节) */
|
|
21
|
+
size?: number;
|
|
22
|
+
/** 修改时间 */
|
|
23
|
+
modifiedTime?: string;
|
|
24
|
+
/** 子节点(目录) */
|
|
25
|
+
children?: SkillFileTree[];
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Sandbox文件管理器类
|
|
29
|
+
*
|
|
30
|
+
* 职责:
|
|
31
|
+
* - 在sandbox隔离环境中执行文件操作
|
|
32
|
+
* - 确保文件访问边界在技能目录内
|
|
33
|
+
* - 提供read、write、delete、list等基础文件操作
|
|
34
|
+
*/
|
|
35
|
+
export declare class SandboxFileManager {
|
|
36
|
+
private sandboxFactory;
|
|
37
|
+
constructor(sandboxFactory: SandboxFactory);
|
|
38
|
+
/**
|
|
39
|
+
* 在sandbox中读取文件
|
|
40
|
+
* @param skillBaseDir 技能根目录
|
|
41
|
+
* @param relativePath 相对路径
|
|
42
|
+
*/
|
|
43
|
+
readFile(skillBaseDir: string, relativePath: string): Promise<string>;
|
|
44
|
+
/**
|
|
45
|
+
* 在sandbox中写入文件
|
|
46
|
+
* @param skillBaseDir 技能根目录
|
|
47
|
+
* @param relativePath 相对路径
|
|
48
|
+
* @param content 文件内容
|
|
49
|
+
*/
|
|
50
|
+
writeFile(skillBaseDir: string, relativePath: string, content: string): Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* 在sandbox中删除文件
|
|
53
|
+
* @param skillBaseDir 技能根目录
|
|
54
|
+
* @param relativePath 相对路径
|
|
55
|
+
*/
|
|
56
|
+
deleteFile(skillBaseDir: string, relativePath: string): Promise<void>;
|
|
57
|
+
/**
|
|
58
|
+
* 在sandbox中列出目录
|
|
59
|
+
* @param skillBaseDir 技能根目录
|
|
60
|
+
* @param relativePath 相对路径
|
|
61
|
+
*/
|
|
62
|
+
listFiles(skillBaseDir: string, relativePath?: string): Promise<SkillFileTree>;
|
|
63
|
+
/**
|
|
64
|
+
* 在sandbox中创建目录
|
|
65
|
+
* @param skillBaseDir 技能根目录
|
|
66
|
+
* @param relativePath 相对路径
|
|
67
|
+
*/
|
|
68
|
+
createDir(skillBaseDir: string, relativePath: string): Promise<void>;
|
|
69
|
+
/**
|
|
70
|
+
* 创建技能的sandbox实例
|
|
71
|
+
* 关键:设置enforceBoundary=true,确保只能在技能目录内操作
|
|
72
|
+
*/
|
|
73
|
+
private createSkillSandbox;
|
|
74
|
+
/**
|
|
75
|
+
* 获取删除命令(跨平台)
|
|
76
|
+
*/
|
|
77
|
+
private getDeleteCommand;
|
|
78
|
+
/**
|
|
79
|
+
* 构建文件树
|
|
80
|
+
*/
|
|
81
|
+
private buildFileTree;
|
|
82
|
+
}
|