ssh-mcp-devops 2.0.0 → 2.0.2

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/ssh-manager-v2.js +64 -11
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ssh-mcp-devops",
3
- "version": "2.0.0",
3
+ "version": "2.0.2",
4
4
  "description": "SSH MCP Server for AI-powered DevOps with Docker and System Monitoring",
5
5
  "type": "module",
6
6
  "main": "index-v2.js",
package/ssh-manager-v2.js CHANGED
@@ -139,20 +139,44 @@ export class SSHManager {
139
139
  throw new Error(`本地文件不存在: ${localPath}`);
140
140
  }
141
141
 
142
+ // 获取文件大小
143
+ const stats = await fs.stat(localPath);
144
+ const fileSizeMB = (stats.size / 1024 / 1024).toFixed(2);
145
+ console.error(`开始上传文件: ${localPath} (${fileSizeMB} MB)`);
146
+
142
147
  return new Promise((resolve, reject) => {
148
+ // 根据文件大小设置超时(每 MB 10 秒,最少 60 秒)
149
+ const timeout = Math.max(60000, stats.size / 1024 / 1024 * 10000);
150
+ let uploadTimer;
151
+
143
152
  this.client.sftp((err, sftp) => {
144
153
  if (err) return reject(err);
145
154
 
155
+ // 设置超时
156
+ uploadTimer = setTimeout(() => {
157
+ sftp.end();
158
+ reject(new Error(`上传超时 (${(timeout / 1000).toFixed(0)}秒): 文件可能太大`));
159
+ }, timeout);
160
+
146
161
  const transferOptions = {
147
162
  concurrency: 64,
148
163
  chunkSize: 32768,
149
- step: options.onProgress || undefined,
164
+ step: (total, nb, fsize) => {
165
+ // 进度回调
166
+ const percent = ((nb / fsize) * 100).toFixed(1);
167
+ console.error(`上传进度: ${percent}% (${(nb / 1024 / 1024).toFixed(2)} MB / ${fileSizeMB} MB)`);
168
+ if (options.onProgress) {
169
+ options.onProgress(total, nb, fsize);
170
+ }
171
+ },
150
172
  };
151
173
 
152
174
  sftp.fastPut(localPath, remotePath, transferOptions, (err) => {
175
+ clearTimeout(uploadTimer);
153
176
  sftp.end();
154
177
  if (err) return reject(new Error(`上传失败: ${err.message}`));
155
- resolve(`✅ 文件上传成功: ${localPath} -> ${remotePath}`);
178
+ console.error(`✅ 上传完成: ${fileSizeMB} MB`);
179
+ resolve(`✅ 文件上传成功: ${localPath} -> ${remotePath} (${fileSizeMB} MB)`);
156
180
  });
157
181
  });
158
182
  });
@@ -166,19 +190,48 @@ export class SSHManager {
166
190
  await fs.mkdir(localDir, { recursive: true });
167
191
 
168
192
  return new Promise((resolve, reject) => {
193
+ let downloadTimer;
194
+
169
195
  this.client.sftp((err, sftp) => {
170
196
  if (err) return reject(err);
171
197
 
172
- const transferOptions = {
173
- concurrency: 64,
174
- chunkSize: 32768,
175
- step: options.onProgress || undefined,
176
- };
198
+ // 先获取文件大小
199
+ sftp.stat(remotePath, (err, stats) => {
200
+ if (err) {
201
+ sftp.end();
202
+ return reject(new Error(`无法获取远程文件信息: ${err.message}`));
203
+ }
177
204
 
178
- sftp.fastGet(remotePath, localPath, transferOptions, (err) => {
179
- sftp.end();
180
- if (err) return reject(new Error(`下载失败: ${err.message}`));
181
- resolve(`✅ 文件下载成功: ${remotePath} -> ${localPath}`);
205
+ const fileSizeMB = (stats.size / 1024 / 1024).toFixed(2);
206
+ console.error(`开始下载文件: ${remotePath} (${fileSizeMB} MB)`);
207
+
208
+ // 根据文件大小设置超时(每 MB 10 秒,最少 60 秒)
209
+ const timeout = Math.max(60000, stats.size / 1024 / 1024 * 10000);
210
+
211
+ downloadTimer = setTimeout(() => {
212
+ sftp.end();
213
+ reject(new Error(`下载超时 (${(timeout / 1000).toFixed(0)}秒): 文件可能太大`));
214
+ }, timeout);
215
+
216
+ const transferOptions = {
217
+ concurrency: 64,
218
+ chunkSize: 32768,
219
+ step: (total, nb, fsize) => {
220
+ const percent = ((nb / fsize) * 100).toFixed(1);
221
+ console.error(`下载进度: ${percent}% (${(nb / 1024 / 1024).toFixed(2)} MB / ${fileSizeMB} MB)`);
222
+ if (options.onProgress) {
223
+ options.onProgress(total, nb, fsize);
224
+ }
225
+ },
226
+ };
227
+
228
+ sftp.fastGet(remotePath, localPath, transferOptions, (err) => {
229
+ clearTimeout(downloadTimer);
230
+ sftp.end();
231
+ if (err) return reject(new Error(`下载失败: ${err.message}`));
232
+ console.error(`✅ 下载完成: ${fileSizeMB} MB`);
233
+ resolve(`✅ 文件下载成功: ${remotePath} -> ${localPath} (${fileSizeMB} MB)`);
234
+ });
182
235
  });
183
236
  });
184
237
  });