sloth-d2c-mcp 1.0.4-beta89 → 1.0.4-beta91
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/cli/run.js +15 -0
- package/dist/build/core/prompt-builder.js +14 -1
- package/dist/build/core/sampling.js +16 -4
- package/dist/build/index.js +106 -1
- package/dist/build/plugin/index.js +4 -0
- package/dist/build/plugin/loader.js +320 -0
- package/dist/build/plugin/manager.js +127 -0
- package/dist/build/plugin/types.js +1 -0
- package/dist/build/server.js +5 -0
- package/dist/interceptor-web/dist/build-report.json +4 -4
- package/dist/interceptor-web/dist/detail.html +1 -1
- package/dist/interceptor-web/dist/index.html +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { loadAllPlugins, loadWorkspacePlugins } from './loader.js';
|
|
2
|
+
/**
|
|
3
|
+
* 插件管理器 - 负责管理生命周期 hooks 并按顺序调用插件
|
|
4
|
+
*/
|
|
5
|
+
class PluginManager {
|
|
6
|
+
plugins = [];
|
|
7
|
+
initialized = false;
|
|
8
|
+
workspaceRoot = '';
|
|
9
|
+
/**
|
|
10
|
+
* 设置工作区根目录
|
|
11
|
+
* @param root 工作区根目录
|
|
12
|
+
*/
|
|
13
|
+
setWorkspaceRoot(root) {
|
|
14
|
+
this.workspaceRoot = root;
|
|
15
|
+
// 重置初始化状态,以便重新加载工作区插件
|
|
16
|
+
if (this.initialized) {
|
|
17
|
+
this.reset();
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* 获取工作区根目录
|
|
22
|
+
*/
|
|
23
|
+
getWorkspaceRoot() {
|
|
24
|
+
return this.workspaceRoot;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* 初始化插件管理器
|
|
28
|
+
* 如果设置了工作区根目录,则加载工作区插件
|
|
29
|
+
* 否则加载全局插件(兼容旧逻辑)
|
|
30
|
+
*/
|
|
31
|
+
async initialize() {
|
|
32
|
+
if (this.initialized) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
if (this.workspaceRoot) {
|
|
37
|
+
// 加载工作区声明的插件
|
|
38
|
+
console.log(`[sloth] 从工作区加载插件: ${this.workspaceRoot}`);
|
|
39
|
+
this.plugins = await loadWorkspacePlugins(this.workspaceRoot);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
// 兼容旧逻辑:加载全局插件
|
|
43
|
+
console.log(`[sloth] 未设置工作区,加载全局插件`);
|
|
44
|
+
this.plugins = await loadAllPlugins();
|
|
45
|
+
}
|
|
46
|
+
this.initialized = true;
|
|
47
|
+
console.log(`[sloth] 插件管理器初始化完成,已加载 ${this.plugins.length} 个插件`);
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
console.error('[sloth] 插件管理器初始化失败:', error);
|
|
51
|
+
// 如果是工作区模式,抛出错误让调用方知道
|
|
52
|
+
if (this.workspaceRoot) {
|
|
53
|
+
throw error;
|
|
54
|
+
}
|
|
55
|
+
this.plugins = [];
|
|
56
|
+
this.initialized = true;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* 获取已加载的插件列表
|
|
61
|
+
*/
|
|
62
|
+
getPlugins() {
|
|
63
|
+
return [...this.plugins];
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* 注册一个插件
|
|
67
|
+
*/
|
|
68
|
+
registerPlugin(plugin) {
|
|
69
|
+
this.plugins.push(plugin);
|
|
70
|
+
console.log(`[sloth] 插件 ${plugin.name} 已注册`);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* 执行指定的 hook
|
|
74
|
+
* @param hookName hook 名称
|
|
75
|
+
* @param params hook 参数
|
|
76
|
+
* 按顺序调用所有插件,每个插件都会执行,返回最后一个成功的结果
|
|
77
|
+
* 每个插件执行时会收到上一个插件的信息 { lastPlugin, returnVal }
|
|
78
|
+
*/
|
|
79
|
+
async executeHook(hookName, params) {
|
|
80
|
+
if (!this.initialized) {
|
|
81
|
+
await this.initialize();
|
|
82
|
+
}
|
|
83
|
+
const pluginsWithHook = this.plugins.filter((p) => typeof p[hookName] === 'function');
|
|
84
|
+
if (pluginsWithHook.length === 0) {
|
|
85
|
+
console.log(`[sloth] 没有插件注册 ${hookName} hook`);
|
|
86
|
+
return params;
|
|
87
|
+
}
|
|
88
|
+
let lastPlugin = '';
|
|
89
|
+
let lastReturnVal = null;
|
|
90
|
+
for (const plugin of pluginsWithHook) {
|
|
91
|
+
try {
|
|
92
|
+
console.log(`[sloth] 执行插件 ${plugin.name} 的 ${hookName} hook`);
|
|
93
|
+
const hookFn = plugin[hookName];
|
|
94
|
+
const context = {
|
|
95
|
+
lastPlugin,
|
|
96
|
+
returnVal: lastReturnVal,
|
|
97
|
+
config: plugin._config,
|
|
98
|
+
};
|
|
99
|
+
const result = await hookFn({
|
|
100
|
+
...params,
|
|
101
|
+
...(lastReturnVal || {}),
|
|
102
|
+
_config: context.config,
|
|
103
|
+
}, context);
|
|
104
|
+
// 更新上一个插件信息
|
|
105
|
+
lastPlugin = plugin.name;
|
|
106
|
+
lastReturnVal = {
|
|
107
|
+
...params,
|
|
108
|
+
...(lastReturnVal || {}),
|
|
109
|
+
...(result || {}),
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
console.error(`[sloth] 插件 ${plugin.name} 执行 ${hookName} 出错:`, error);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return lastReturnVal || params;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* 重置插件管理器
|
|
120
|
+
*/
|
|
121
|
+
reset() {
|
|
122
|
+
this.plugins = [];
|
|
123
|
+
this.initialized = false;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
// 导出单例实例
|
|
127
|
+
export const pluginManager = new PluginManager();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/build/server.js
CHANGED
|
@@ -33,6 +33,7 @@ const upload = multer({
|
|
|
33
33
|
// 导入默认提示词
|
|
34
34
|
import { chunkOptimizeCodePrompt, aggregationOptimizeCodePrompt, finalOptimizeCodePrompt, chunkOptimizeCodePromptVue, aggregationOptimizeCodePromptVue, finalOptimizeCodePromptVue, noSamplingAggregationPrompt, noSamplingAggregationPromptVue, } from 'sloth-d2c-node/convert';
|
|
35
35
|
import { getParam } from './utils/utils.js';
|
|
36
|
+
import { listWorkspacePlugins } from './plugin/loader.js';
|
|
36
37
|
// 保存 HTTP 服务器实例
|
|
37
38
|
export let httpServer = null;
|
|
38
39
|
// 保存 Socket 服务器实例
|
|
@@ -202,6 +203,7 @@ export async function startHttpServer(port = PORT, mcpServer, configManagerInsta
|
|
|
202
203
|
const uuid = getParam(req.headers.referer || '', 'token') || '';
|
|
203
204
|
req.uuid = uuid;
|
|
204
205
|
req.fileManager = fileManager.withUUID(uuid);
|
|
206
|
+
req.workspaceRoot = req.fileManager.getWorkspaceRoot();
|
|
205
207
|
next();
|
|
206
208
|
});
|
|
207
209
|
// 处理流式 HTTP 的 POST 请求,支持会话复用和初始化
|
|
@@ -337,6 +339,7 @@ export async function startHttpServer(port = PORT, mcpServer, configManagerInsta
|
|
|
337
339
|
const fileKey = req.query.fileKey;
|
|
338
340
|
const nodeId = req.query.nodeId;
|
|
339
341
|
const framework = req.query.framework;
|
|
342
|
+
const plugins = await listWorkspacePlugins(req.workspaceRoot);
|
|
340
343
|
if (fileKey) {
|
|
341
344
|
// 如果提供了 fileKey,返回该 fileKey 的特定配置
|
|
342
345
|
const globalConfig = await configManager.load();
|
|
@@ -401,6 +404,7 @@ export async function startHttpServer(port = PORT, mcpServer, configManagerInsta
|
|
|
401
404
|
defaultFramework: globalConfig.defaultFramework || 'react',
|
|
402
405
|
fileKey: fileKey,
|
|
403
406
|
groupsData: groupsData,
|
|
407
|
+
plugins,
|
|
404
408
|
},
|
|
405
409
|
});
|
|
406
410
|
}
|
|
@@ -441,6 +445,7 @@ export async function startHttpServer(port = PORT, mcpServer, configManagerInsta
|
|
|
441
445
|
imageSetting: configStorage.imageSetting || {},
|
|
442
446
|
promptSetting: promptSetting,
|
|
443
447
|
frameworks: frameworks,
|
|
448
|
+
plugins,
|
|
444
449
|
},
|
|
445
450
|
});
|
|
446
451
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
|
-
"buildTime": "
|
|
2
|
+
"buildTime": "2026-01-07T05:29:02.885Z",
|
|
3
3
|
"mode": "build",
|
|
4
4
|
"pages": {
|
|
5
5
|
"main": {
|
|
6
6
|
"file": "index.html",
|
|
7
|
-
"size":
|
|
7
|
+
"size": 1643352,
|
|
8
8
|
"sizeFormatted": "1.57 MB"
|
|
9
9
|
},
|
|
10
10
|
"detail": {
|
|
@@ -13,6 +13,6 @@
|
|
|
13
13
|
"sizeFormatted": "275.19 KB"
|
|
14
14
|
}
|
|
15
15
|
},
|
|
16
|
-
"totalSize":
|
|
17
|
-
"totalSizeFormatted": "1.
|
|
16
|
+
"totalSize": 1925151,
|
|
17
|
+
"totalSizeFormatted": "1.84 MB"
|
|
18
18
|
}
|