@zzp123/mcp-zentao 1.4.0 → 1.4.1
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 +76 -14
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -999,18 +999,26 @@ server.tool("uploadImageFromClipboard", {
|
|
|
999
999
|
filename: z.string().optional(),
|
|
1000
1000
|
uid: z.string().optional()
|
|
1001
1001
|
}, async ({ filename, uid }) => {
|
|
1002
|
-
if (!zentaoApi)
|
|
1003
|
-
|
|
1002
|
+
if (!zentaoApi) {
|
|
1003
|
+
return {
|
|
1004
|
+
content: [{
|
|
1005
|
+
type: "text",
|
|
1006
|
+
text: JSON.stringify({ error: "请先初始化禅道API配置" }, null, 2)
|
|
1007
|
+
}],
|
|
1008
|
+
isError: true
|
|
1009
|
+
};
|
|
1010
|
+
}
|
|
1004
1011
|
const fs = await import('fs');
|
|
1005
1012
|
const path = await import('path');
|
|
1006
1013
|
const { execSync } = await import('child_process');
|
|
1007
1014
|
try {
|
|
1015
|
+
console.log('[uploadImageFromClipboard] 开始执行...');
|
|
1008
1016
|
// 读取系统剪贴板图片
|
|
1009
|
-
let base64Data;
|
|
1010
1017
|
let fileBuffer;
|
|
1011
1018
|
let finalFilename;
|
|
1012
1019
|
// Windows: 使用 PowerShell 读取剪贴板
|
|
1013
1020
|
if (process.platform === 'win32') {
|
|
1021
|
+
console.log('[uploadImageFromClipboard] Windows平台,使用PowerShell读取剪贴板...');
|
|
1014
1022
|
const psScript = `
|
|
1015
1023
|
Add-Type -AssemblyName System.Windows.Forms
|
|
1016
1024
|
$img = [System.Windows.Forms.Clipboard]::GetImage()
|
|
@@ -1028,64 +1036,118 @@ server.tool("uploadImageFromClipboard", {
|
|
|
1028
1036
|
stdio: ['pipe', 'pipe', 'pipe']
|
|
1029
1037
|
}).trim();
|
|
1030
1038
|
if (!result || result.includes('NoImage') || result.includes('Error')) {
|
|
1031
|
-
|
|
1039
|
+
console.error('[uploadImageFromClipboard] 剪贴板中没有图片');
|
|
1040
|
+
return {
|
|
1041
|
+
content: [{
|
|
1042
|
+
type: "text",
|
|
1043
|
+
text: JSON.stringify({
|
|
1044
|
+
error: "剪贴板中没有图片",
|
|
1045
|
+
tip: "请先复制图片,不要粘贴到输入框,直接告诉我'上传'"
|
|
1046
|
+
}, null, 2)
|
|
1047
|
+
}],
|
|
1048
|
+
isError: true
|
|
1049
|
+
};
|
|
1032
1050
|
}
|
|
1033
|
-
|
|
1034
|
-
fileBuffer = Buffer.from(base64Data, 'base64');
|
|
1051
|
+
fileBuffer = Buffer.from(result, 'base64');
|
|
1035
1052
|
finalFilename = filename || `clipboard_${Date.now()}.png`;
|
|
1053
|
+
console.log(`[uploadImageFromClipboard] 已读取剪贴板图片,大小: ${fileBuffer.length} bytes`);
|
|
1036
1054
|
}
|
|
1037
1055
|
// macOS: 使用 pngpaste
|
|
1038
1056
|
else if (process.platform === 'darwin') {
|
|
1057
|
+
console.log('[uploadImageFromClipboard] macOS平台,使用pngpaste读取剪贴板...');
|
|
1039
1058
|
const tempFile = path.join(process.cwd(), '.temp_clipboard.png');
|
|
1040
1059
|
try {
|
|
1041
1060
|
execSync(`pngpaste "${tempFile}"`);
|
|
1042
1061
|
fileBuffer = fs.readFileSync(tempFile);
|
|
1043
1062
|
fs.unlinkSync(tempFile);
|
|
1044
1063
|
finalFilename = filename || `clipboard_${Date.now()}.png`;
|
|
1064
|
+
console.log(`[uploadImageFromClipboard] 已读取剪贴板图片,大小: ${fileBuffer.length} bytes`);
|
|
1045
1065
|
}
|
|
1046
|
-
catch {
|
|
1047
|
-
|
|
1066
|
+
catch (err) {
|
|
1067
|
+
console.error('[uploadImageFromClipboard] macOS读取剪贴板失败:', err);
|
|
1068
|
+
return {
|
|
1069
|
+
content: [{
|
|
1070
|
+
type: "text",
|
|
1071
|
+
text: JSON.stringify({
|
|
1072
|
+
error: "剪贴板中没有图片或pngpaste未安装",
|
|
1073
|
+
tip: "请先安装 pngpaste: brew install pngpaste"
|
|
1074
|
+
}, null, 2)
|
|
1075
|
+
}],
|
|
1076
|
+
isError: true
|
|
1077
|
+
};
|
|
1048
1078
|
}
|
|
1049
1079
|
}
|
|
1050
1080
|
// Linux: 使用 xclip
|
|
1051
1081
|
else {
|
|
1082
|
+
console.log('[uploadImageFromClipboard] Linux平台,使用xclip读取剪贴板...');
|
|
1052
1083
|
try {
|
|
1053
1084
|
const buffer = execSync('xclip -selection clipboard -t image/png -o', {
|
|
1054
1085
|
maxBuffer: 10 * 1024 * 1024
|
|
1055
1086
|
});
|
|
1056
1087
|
fileBuffer = buffer;
|
|
1057
1088
|
finalFilename = filename || `clipboard_${Date.now()}.png`;
|
|
1089
|
+
console.log(`[uploadImageFromClipboard] 已读取剪贴板图片,大小: ${fileBuffer.length} bytes`);
|
|
1058
1090
|
}
|
|
1059
|
-
catch {
|
|
1060
|
-
|
|
1091
|
+
catch (err) {
|
|
1092
|
+
console.error('[uploadImageFromClipboard] Linux读取剪贴板失败:', err);
|
|
1093
|
+
return {
|
|
1094
|
+
content: [{
|
|
1095
|
+
type: "text",
|
|
1096
|
+
text: JSON.stringify({
|
|
1097
|
+
error: "剪贴板中没有图片或xclip未安装",
|
|
1098
|
+
tip: "请先安装 xclip: sudo apt-get install xclip"
|
|
1099
|
+
}, null, 2)
|
|
1100
|
+
}],
|
|
1101
|
+
isError: true
|
|
1102
|
+
};
|
|
1061
1103
|
}
|
|
1062
1104
|
}
|
|
1063
1105
|
// 创建 img 文件夹
|
|
1064
1106
|
const imgDir = path.join(process.cwd(), 'img');
|
|
1065
1107
|
if (!fs.existsSync(imgDir)) {
|
|
1108
|
+
console.log(`[uploadImageFromClipboard] 创建目录: ${imgDir}`);
|
|
1066
1109
|
fs.mkdirSync(imgDir, { recursive: true });
|
|
1067
1110
|
}
|
|
1068
1111
|
// 保存到 img 文件夹
|
|
1069
1112
|
const savedPath = path.join(imgDir, finalFilename);
|
|
1070
1113
|
fs.writeFileSync(savedPath, fileBuffer);
|
|
1114
|
+
console.log(`[uploadImageFromClipboard] 图片已保存到: ${savedPath}`);
|
|
1071
1115
|
// 上传到禅道
|
|
1072
|
-
|
|
1116
|
+
console.log('[uploadImageFromClipboard] 开始上传到禅道...');
|
|
1117
|
+
const uploadResult = await zentaoApi.uploadFile({
|
|
1073
1118
|
file: fileBuffer,
|
|
1074
1119
|
filename: finalFilename,
|
|
1075
1120
|
uid
|
|
1076
1121
|
});
|
|
1122
|
+
console.log('[uploadImageFromClipboard] 上传成功,结果:', uploadResult);
|
|
1077
1123
|
const response = {
|
|
1078
|
-
|
|
1124
|
+
success: true,
|
|
1125
|
+
upload: uploadResult,
|
|
1079
1126
|
savedPath: savedPath,
|
|
1127
|
+
filename: finalFilename,
|
|
1128
|
+
fileSize: fileBuffer.length,
|
|
1080
1129
|
message: `图片已保存到本地并上传到禅道`
|
|
1081
1130
|
};
|
|
1082
|
-
|
|
1131
|
+
console.log('[uploadImageFromClipboard] 返回结果:', response);
|
|
1132
|
+
return {
|
|
1133
|
+
content: [{
|
|
1134
|
+
type: "text",
|
|
1135
|
+
text: JSON.stringify(response, null, 2)
|
|
1136
|
+
}]
|
|
1137
|
+
};
|
|
1083
1138
|
}
|
|
1084
1139
|
catch (error) {
|
|
1140
|
+
console.error('[uploadImageFromClipboard] 发生错误:', error);
|
|
1141
|
+
const errorResponse = {
|
|
1142
|
+
success: false,
|
|
1143
|
+
error: error.message || String(error),
|
|
1144
|
+
stack: error.stack,
|
|
1145
|
+
tip: "请检查:\n1. 确保已复制图片到剪贴板\n2. 不要粘贴到输入框,直接说'上传剪贴板图片'\n3. 或使用命令行: upload.bat"
|
|
1146
|
+
};
|
|
1085
1147
|
return {
|
|
1086
1148
|
content: [{
|
|
1087
1149
|
type: "text",
|
|
1088
|
-
text:
|
|
1150
|
+
text: JSON.stringify(errorResponse, null, 2)
|
|
1089
1151
|
}],
|
|
1090
1152
|
isError: true
|
|
1091
1153
|
};
|