sloth-d2c-mcp 1.0.4-beta81 → 1.0.4-beta83
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/build/core/prompt-builder.js +3 -4
- package/dist/build/core/sampling.js +4 -10
- package/dist/build/index.js +40 -11
- package/dist/build/interceptor/vscode.js +4 -4
- package/dist/build/server.js +75 -17
- package/dist/build/utils/client-capabilities.js +143 -0
- package/dist/build/utils/file-manager.js +7 -10
- package/dist/build/utils/update.js +50 -4
- package/dist/interceptor-web/dist/build-report.json +7 -7
- package/dist/interceptor-web/dist/detail.html +1 -1
- package/dist/interceptor-web/dist/index.html +1 -1
- package/package.json +12 -12
|
@@ -23,7 +23,7 @@ export class FileManager {
|
|
|
23
23
|
Logger.log(`已设置工作目录根路径: ${rootPath}`);
|
|
24
24
|
}
|
|
25
25
|
getWorkspaceRoot() {
|
|
26
|
-
return this.workspaceRoot;
|
|
26
|
+
return this.workspaceRoot || './';
|
|
27
27
|
}
|
|
28
28
|
/**
|
|
29
29
|
* 生成文件路径
|
|
@@ -35,7 +35,7 @@ export class FileManager {
|
|
|
35
35
|
getFilePath(fileKey, nodeId, filename) {
|
|
36
36
|
// 清理文件名中的特殊字符
|
|
37
37
|
const cleanFileKey = fileKey.replace(/[^a-zA-Z0-9\u4e00-\u9fff\u3400-\u4dbf-_]/g, '_');
|
|
38
|
-
const cleanNodeId = nodeId ? nodeId.replace(/[^a-zA-Z0-9\u4e00-\u9fff\u3400-\u4dbf-_
|
|
38
|
+
const cleanNodeId = nodeId ? nodeId.replace(/[^a-zA-Z0-9\u4e00-\u9fff\u3400-\u4dbf-_]/g, '_') : 'root';
|
|
39
39
|
const cleanFilename = filename.replace(/[^a-zA-Z0-9\u4e00-\u9fff\u3400-\u4dbf-_.]/g, '_');
|
|
40
40
|
return path.join(this.baseDir, cleanFileKey, cleanNodeId, cleanFilename);
|
|
41
41
|
}
|
|
@@ -54,7 +54,7 @@ export class FileManager {
|
|
|
54
54
|
}
|
|
55
55
|
// 清理文件名中的特殊字符
|
|
56
56
|
const cleanFileKey = fileKey.replace(/[^a-zA-Z0-9\u4e00-\u9fff\u3400-\u4dbf-_]/g, '_');
|
|
57
|
-
const cleanNodeId = nodeId ? nodeId.replace(/[^a-zA-Z0-9\u4e00-\u9fff\u3400-\u4dbf-_
|
|
57
|
+
const cleanNodeId = nodeId ? nodeId.replace(/[^a-zA-Z0-9\u4e00-\u9fff\u3400-\u4dbf-_]/g, '_') : 'root';
|
|
58
58
|
const cleanFilename = filename.replace(/[^a-zA-Z0-9\u4e00-\u9fff\u3400-\u4dbf-_.]/g, '_');
|
|
59
59
|
if (skipParsePath) {
|
|
60
60
|
return path.join(this.workspaceRoot, '.sloth', fileKey, nodeId || 'root', cleanFilename);
|
|
@@ -179,7 +179,7 @@ export class FileManager {
|
|
|
179
179
|
async cleanupNode(fileKey, nodeId) {
|
|
180
180
|
try {
|
|
181
181
|
const cleanFileKey = fileKey.replace(/[^a-zA-Z0-9-_]/g, '_');
|
|
182
|
-
const cleanNodeId = nodeId ? nodeId.replace(/[^a-zA-Z0-9-_
|
|
182
|
+
const cleanNodeId = nodeId ? nodeId.replace(/[^a-zA-Z0-9-_]/g, '_') : 'root';
|
|
183
183
|
const nodeDir = path.join(this.baseDir, cleanFileKey, cleanNodeId);
|
|
184
184
|
await fs.rm(nodeDir, { recursive: true, force: true });
|
|
185
185
|
Logger.log(`节点目录已清理: ${nodeDir}`);
|
|
@@ -234,7 +234,7 @@ export class FileManager {
|
|
|
234
234
|
*/
|
|
235
235
|
getNodeDir(fileKey, nodeId) {
|
|
236
236
|
const cleanFileKey = fileKey.replace(/[^a-zA-Z0-9-_]/g, '_');
|
|
237
|
-
const cleanNodeId = nodeId ? nodeId.replace(/[^a-zA-Z0-9-_
|
|
237
|
+
const cleanNodeId = nodeId ? nodeId.replace(/[^a-zA-Z0-9-_]/g, '_') : 'root';
|
|
238
238
|
return path.join(this.baseDir, cleanFileKey, cleanNodeId);
|
|
239
239
|
}
|
|
240
240
|
/**
|
|
@@ -588,9 +588,6 @@ export class FileManager {
|
|
|
588
588
|
*/
|
|
589
589
|
async saveComponentsDatabase(components) {
|
|
590
590
|
const workspaceRoot = this.getWorkspaceRoot();
|
|
591
|
-
if (!workspaceRoot) {
|
|
592
|
-
throw new Error('工作目录根路径未设置,无法保存组件数据库');
|
|
593
|
-
}
|
|
594
591
|
const slothDir = path.join(workspaceRoot, '.sloth');
|
|
595
592
|
const componentsPath = path.join(slothDir, 'components.json');
|
|
596
593
|
// 确保目录存在
|
|
@@ -706,7 +703,7 @@ export class FileManager {
|
|
|
706
703
|
now.getMinutes().toString().padStart(2, '0') +
|
|
707
704
|
now.getSeconds().toString().padStart(2, '0');
|
|
708
705
|
const cleanFileKey = fileKey.replace(/[^a-zA-Z0-9-_]/g, '_');
|
|
709
|
-
const cleanNodeId = nodeId ? nodeId.replace(/[^a-zA-Z0-9-_
|
|
706
|
+
const cleanNodeId = nodeId ? nodeId.replace(/[^a-zA-Z0-9-_]/g, '_') : 'root';
|
|
710
707
|
// 归档路径:.sloth/{fileKey}/{nodeId}/history/{timestamp}/absolute.html
|
|
711
708
|
const archiveDir = path.join(this.workspaceRoot, '.sloth', cleanFileKey, cleanNodeId, 'history', timestamp);
|
|
712
709
|
try {
|
|
@@ -751,7 +748,7 @@ export class FileManager {
|
|
|
751
748
|
return [];
|
|
752
749
|
}
|
|
753
750
|
const cleanFileKey = fileKey.replace(/[^a-zA-Z0-9-_]/g, '_');
|
|
754
|
-
const cleanNodeId = nodeId ? nodeId.replace(/[^a-zA-Z0-9-_
|
|
751
|
+
const cleanNodeId = nodeId ? nodeId.replace(/[^a-zA-Z0-9-_]/g, '_') : 'root';
|
|
755
752
|
const historyDir = path.join(this.workspaceRoot, '.sloth', cleanFileKey, cleanNodeId, 'history');
|
|
756
753
|
try {
|
|
757
754
|
const entries = await fs.readdir(historyDir, { withFileTypes: true });
|
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
import { Logger } from './logger.js';
|
|
2
2
|
import { getResourceMapAdvanced } from 'sloth-d2c-node/convert';
|
|
3
|
+
import { replacePathVariables } from './webpack-substitutions.js';
|
|
4
|
+
import { getSystemSupportFileName } from './utils.js';
|
|
5
|
+
import { sha1 } from 'js-sha1';
|
|
6
|
+
/**
|
|
7
|
+
* 移除 base64 字符串的前缀(如 data:image/png;base64,),只保留纯 base64 数据
|
|
8
|
+
* @param base64String 带前缀的 base64 字符串
|
|
9
|
+
* @returns 纯 base64 数据
|
|
10
|
+
*/
|
|
11
|
+
export function removeBase64Prefix(base64String) {
|
|
12
|
+
if (!base64String)
|
|
13
|
+
return '';
|
|
14
|
+
const commaIndex = base64String.indexOf(',');
|
|
15
|
+
if (commaIndex !== -1) {
|
|
16
|
+
return base64String.slice(commaIndex + 1);
|
|
17
|
+
}
|
|
18
|
+
return base64String;
|
|
19
|
+
}
|
|
3
20
|
/**
|
|
4
21
|
* 检查imageSetting配置是否有变化,如果有变化则重新生成imageMap
|
|
5
22
|
* @param currentImageMap 当前的imageMap
|
|
@@ -8,7 +25,36 @@ import { getResourceMapAdvanced } from 'sloth-d2c-node/convert';
|
|
|
8
25
|
* @param newConfig 新的配置
|
|
9
26
|
* @returns Promise<{ imageMap: any, updated: boolean }> - 返回新的imageMap和是否更新的标志
|
|
10
27
|
*/
|
|
11
|
-
export async function updateImageMapIfNeeded(currentImageMap, imageNodeList, oldConfig, newConfig) {
|
|
28
|
+
export async function updateImageMapIfNeeded(currentImageMap, imageNodeList, oldConfig, newConfig, local) {
|
|
29
|
+
if (local) {
|
|
30
|
+
Logger.log('本地模式,直接更新imageMap');
|
|
31
|
+
for (let node of imageNodeList) {
|
|
32
|
+
const type = node.srcType === 'PNG' ? 'png' : 'svg';
|
|
33
|
+
const base64 = removeBase64Prefix(currentImageMap[node.id]?.base64);
|
|
34
|
+
const { imageStorageType, imageStorageNamingRule, imageStoragePath } = newConfig?.imageSetting;
|
|
35
|
+
if (imageStorageType === 'local') {
|
|
36
|
+
let webpackPathRule = imageStorageNamingRule;
|
|
37
|
+
if (!webpackPathRule.endsWith('.[ext]')) {
|
|
38
|
+
webpackPathRule += '.[ext]';
|
|
39
|
+
}
|
|
40
|
+
const name = replacePathVariables(webpackPathRule, {
|
|
41
|
+
filename: [getSystemSupportFileName(node.name), type].join('.'),
|
|
42
|
+
chunk: {
|
|
43
|
+
id: node.id,
|
|
44
|
+
name: getSystemSupportFileName(node.name),
|
|
45
|
+
contentHash: {
|
|
46
|
+
[type]: sha1(base64).substring(0, 8),
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
contentHashType: type,
|
|
50
|
+
}, undefined);
|
|
51
|
+
const path = [imageStoragePath, name].join('/');
|
|
52
|
+
node.src = path;
|
|
53
|
+
currentImageMap[node.id].path = path;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return { imageMap: currentImageMap, updated: true };
|
|
57
|
+
}
|
|
12
58
|
// 提取相关的imageSetting配置项
|
|
13
59
|
const oldImageSetting = oldConfig?.imageSetting || {};
|
|
14
60
|
const newImageSetting = newConfig?.imageSetting || {};
|
|
@@ -29,10 +75,10 @@ export async function updateImageMapIfNeeded(currentImageMap, imageNodeList, old
|
|
|
29
75
|
'imageStorageApiFileField',
|
|
30
76
|
'imageStorageApiUrlField',
|
|
31
77
|
'imageStorageApiCustomHeader',
|
|
32
|
-
'imageStorageApiCustomBody'
|
|
78
|
+
'imageStorageApiCustomBody',
|
|
33
79
|
];
|
|
34
80
|
// 检查是否有相关配置发生变化
|
|
35
|
-
const hasImageSettingChanged = relevantKeys.some(key => {
|
|
81
|
+
const hasImageSettingChanged = relevantKeys.some((key) => {
|
|
36
82
|
return oldImageSetting[key] !== newImageSetting[key];
|
|
37
83
|
});
|
|
38
84
|
if (!hasImageSettingChanged) {
|
|
@@ -40,7 +86,7 @@ export async function updateImageMapIfNeeded(currentImageMap, imageNodeList, old
|
|
|
40
86
|
return { imageMap: currentImageMap, updated: false };
|
|
41
87
|
}
|
|
42
88
|
Logger.log('检测到imageSetting配置变化,重新生成imageMap');
|
|
43
|
-
Logger.log('变化的配置项:', relevantKeys.filter(key => oldImageSetting[key] !== newImageSetting[key]));
|
|
89
|
+
Logger.log('变化的配置项:', relevantKeys.filter((key) => oldImageSetting[key] !== newImageSetting[key]));
|
|
44
90
|
try {
|
|
45
91
|
// 重新生成imageMap
|
|
46
92
|
const newImageMap = await getResourceMapAdvanced(imageNodeList, newConfig);
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
{
|
|
2
|
-
"buildTime": "2025-12-
|
|
2
|
+
"buildTime": "2025-12-24T13:36:17.450Z",
|
|
3
3
|
"mode": "build",
|
|
4
4
|
"pages": {
|
|
5
5
|
"main": {
|
|
6
6
|
"file": "index.html",
|
|
7
|
-
"size":
|
|
8
|
-
"sizeFormatted": "1.
|
|
7
|
+
"size": 1642308,
|
|
8
|
+
"sizeFormatted": "1.57 MB"
|
|
9
9
|
},
|
|
10
10
|
"detail": {
|
|
11
11
|
"file": "detail.html",
|
|
12
|
-
"size":
|
|
13
|
-
"sizeFormatted": "275.
|
|
12
|
+
"size": 281799,
|
|
13
|
+
"sizeFormatted": "275.19 KB"
|
|
14
14
|
}
|
|
15
15
|
},
|
|
16
|
-
"totalSize":
|
|
17
|
-
"totalSizeFormatted": "1.
|
|
16
|
+
"totalSize": 1924107,
|
|
17
|
+
"totalSizeFormatted": "1.83 MB"
|
|
18
18
|
}
|