@sciagent/cli 1.0.85 → 1.0.87
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/bin/sciagent.js +25 -14
- package/package.json +2 -9
- package/scripts/postinstall.js +151 -141
package/bin/sciagent.js
CHANGED
|
@@ -23,7 +23,7 @@ const fs = require('fs');
|
|
|
23
23
|
const os = require('os');
|
|
24
24
|
|
|
25
25
|
// 当前版本号 - 与 postinstall.js 和 package.json 保持同步
|
|
26
|
-
const CURRENT_VERSION = '1.0.
|
|
26
|
+
const CURRENT_VERSION = '1.0.87';
|
|
27
27
|
|
|
28
28
|
// 极狐GitLab下载配置
|
|
29
29
|
const JIHULAB_URL = 'https://jihulab.com';
|
|
@@ -104,11 +104,11 @@ function getBinaryPath() {
|
|
|
104
104
|
|
|
105
105
|
if (cmp === 0) {
|
|
106
106
|
// 版本精确匹配 → 直接使用
|
|
107
|
-
console.log(`[INFO] SciAgent v${installedVersion} (
|
|
107
|
+
console.log(`[INFO] SciAgent v${installedVersion} (${(stats.size / (1024 * 1024)).toFixed(1)} MB, ${stats.mtime.toISOString().slice(0,10)})`);
|
|
108
108
|
return binPath;
|
|
109
109
|
} else if (cmp < 0) {
|
|
110
110
|
// 版本过低 → 自动下载新版本
|
|
111
|
-
console.log(`[INFO] SciAgent version outdated: v${installedVersion} → v${CURRENT_VERSION}`);
|
|
111
|
+
console.log(`[INFO] SciAgent version outdated: v${installedVersion} (${(stats.size / (1024 * 1024)).toFixed(1)} MB) → v${CURRENT_VERSION}`);
|
|
112
112
|
console.log(`[INFO] Downloading new version from JiHuLab...`);
|
|
113
113
|
try { fs.unlinkSync(binPath); fs.unlinkSync(versionFile); } catch (e) {}
|
|
114
114
|
const downloaded = downloadBinary(platform, arch, CURRENT_VERSION);
|
|
@@ -117,7 +117,7 @@ function getBinaryPath() {
|
|
|
117
117
|
process.exit(1);
|
|
118
118
|
} else {
|
|
119
119
|
// 版本更高 → 允许运行(用户可能手动安装了新版)
|
|
120
|
-
console.log(`[INFO] SciAgent v${installedVersion} (newer than package v${CURRENT_VERSION})`);
|
|
120
|
+
console.log(`[INFO] SciAgent v${installedVersion} (newer than package v${CURRENT_VERSION}, ${(stats.size / (1024 * 1024)).toFixed(1)} MB)`);
|
|
121
121
|
return binPath;
|
|
122
122
|
}
|
|
123
123
|
} else {
|
|
@@ -181,21 +181,32 @@ function downloadBinary(platform, arch, version) {
|
|
|
181
181
|
console.log(` Target: ${targetPath}`);
|
|
182
182
|
|
|
183
183
|
try {
|
|
184
|
-
// 同步下载(使用curl或PowerShell)
|
|
185
184
|
if (platform === 'win32') {
|
|
186
185
|
// Windows: 使用 PowerShell 下载
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
186
|
+
// 将URL和目标路径写入临时PS1脚本文件,避免命令行引号/特殊字符问题
|
|
187
|
+
const tmpScript = path.join(os.tmpdir(), 'sciagent-download.ps1');
|
|
188
|
+
const scriptContent = [
|
|
189
|
+
'$ProgressPreference = "SilentlyContinue"',
|
|
190
|
+
`$uri = "${downloadUrl}"`,
|
|
191
|
+
`$out = "${targetPath}"`,
|
|
192
|
+
'Write-Host " Downloading from $uri..."',
|
|
193
|
+
'Invoke-WebRequest -Uri $uri -OutFile $out -UseBasicParsing',
|
|
194
|
+
'if (Test-Path $out) { $s = (Get-Item $out).Length; Write-Host " Downloaded: $s bytes" } else { Write-Error "File not created"; exit 1 }'
|
|
195
|
+
].join('\r\n');
|
|
196
|
+
fs.writeFileSync(tmpScript, scriptContent, 'utf8');
|
|
197
|
+
|
|
198
|
+
try {
|
|
199
|
+
execSync(`powershell -NoProfile -ExecutionPolicy Bypass -File "${tmpScript}"`, {
|
|
200
|
+
stdio: 'inherit',
|
|
201
|
+
timeout: 600000
|
|
202
|
+
});
|
|
203
|
+
} finally {
|
|
204
|
+
try { fs.unlinkSync(tmpScript); } catch (e) {}
|
|
205
|
+
}
|
|
195
206
|
} else {
|
|
196
207
|
// Linux/macOS: 使用 curl
|
|
197
208
|
execSync(`curl -fsSL -o '${targetPath}' '${downloadUrl}'`, {
|
|
198
|
-
stdio: '
|
|
209
|
+
stdio: 'inherit',
|
|
199
210
|
timeout: 600000
|
|
200
211
|
});
|
|
201
212
|
fs.chmodSync(targetPath, 0o755);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sciagent/cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.87",
|
|
4
4
|
"description": "SciAgent CLI - AI Research Assistant",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"files": [
|
|
@@ -14,14 +14,7 @@
|
|
|
14
14
|
"scripts": {
|
|
15
15
|
"postinstall": "node scripts/postinstall.js"
|
|
16
16
|
},
|
|
17
|
-
"optionalDependencies": {
|
|
18
|
-
"@sciagent/cli-linux-x64": "1.0.85",
|
|
19
|
-
"@sciagent/cli-linux-arm64": "1.0.85",
|
|
20
|
-
"@sciagent/cli-darwin-x64": "1.0.85",
|
|
21
|
-
"@sciagent/cli-darwin-arm64": "1.0.85",
|
|
22
|
-
"@sciagent/cli-win32-x64": "1.0.85",
|
|
23
|
-
"@sciagent/cli-win32-arm64": "1.0.85"
|
|
24
|
-
},
|
|
17
|
+
"optionalDependencies": {},
|
|
25
18
|
"keywords": [
|
|
26
19
|
"ai",
|
|
27
20
|
"research",
|
package/scripts/postinstall.js
CHANGED
|
@@ -27,7 +27,7 @@ const ARCH_MAP = {
|
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
// 当前版本号 - 每次发布时同步更新
|
|
30
|
-
const CURRENT_VERSION = '1.0.
|
|
30
|
+
const CURRENT_VERSION = '1.0.87';
|
|
31
31
|
|
|
32
32
|
// GitHub Releases 回退版本列表(当当前版本的 release 不存在时尝试)
|
|
33
33
|
const GITHUB_FALLBACK_VERSIONS = ['1.0.50', '1.0.48', '1.0.46', '1.0.40', '1.0.38', '1.0.36'];
|
|
@@ -127,21 +127,11 @@ function checkBinaryInstalled(platform, arch) {
|
|
|
127
127
|
}
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
-
//
|
|
131
|
-
//
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
const stats = fs.statSync(packagePath);
|
|
136
|
-
if (stats.size > 10 * 1024 * 1024) {
|
|
137
|
-
return { installed: true, path: packagePath };
|
|
138
|
-
} else {
|
|
139
|
-
console.log(` ℹ️ npm 包中的二进制文件太小 (${stats.size} bytes),是空壳包`);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
} catch (e) {
|
|
143
|
-
// 包未安装
|
|
144
|
-
}
|
|
130
|
+
// 不再从 npm optionalDependencies 查找二进制,原因:
|
|
131
|
+
// 1. npm 缓存中的旧包可能包含旧版二进制(如 1.0.40 的 194MB 旧 exe)
|
|
132
|
+
// 2. npm 可能修改 package.json 版本号来匹配请求,但二进制文件仍是旧的
|
|
133
|
+
// 3. 超过 250MB 的包无法发布到 npm,只有空壳包
|
|
134
|
+
// 所有二进制统一从极狐GitLab下载,确保版本正确
|
|
145
135
|
|
|
146
136
|
return { installed: false };
|
|
147
137
|
}
|
|
@@ -182,81 +172,118 @@ function checkCodebuddyBinaryInstalled() {
|
|
|
182
172
|
function downloadFile(url, destPath, timeout = 120000) {
|
|
183
173
|
return new Promise((resolve, reject) => {
|
|
184
174
|
const protocol = url.startsWith('https') ? https : http;
|
|
175
|
+
|
|
176
|
+
// 确保目标目录存在
|
|
177
|
+
const destDir = path.dirname(destPath);
|
|
178
|
+
if (!fs.existsSync(destDir)) {
|
|
179
|
+
fs.mkdirSync(destDir, { recursive: true });
|
|
180
|
+
}
|
|
181
|
+
|
|
185
182
|
const file = fs.createWriteStream(destPath);
|
|
186
183
|
let completed = false;
|
|
184
|
+
let downloadedSize = 0;
|
|
187
185
|
|
|
188
186
|
const timer = setTimeout(() => {
|
|
189
187
|
if (!completed) {
|
|
188
|
+
completed = true;
|
|
190
189
|
file.close();
|
|
191
190
|
try { fs.unlinkSync(destPath); } catch (e) {}
|
|
192
|
-
reject(new Error(
|
|
191
|
+
reject(new Error(`Download timeout after ${timeout / 1000}s (${(downloadedSize / (1024 * 1024)).toFixed(1)} MB downloaded)`));
|
|
193
192
|
}
|
|
194
193
|
}, timeout);
|
|
195
194
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
downloadFile(response.headers.location, destPath, timeout).then(resolve).catch(reject);
|
|
206
|
-
return;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
if (response.statusCode !== 200) {
|
|
210
|
-
file.close();
|
|
211
|
-
try { fs.unlinkSync(destPath); } catch (e) {}
|
|
212
|
-
clearTimeout(timer);
|
|
213
|
-
reject(new Error(`HTTP ${response.statusCode}`));
|
|
195
|
+
function doRequest(requestUrl, redirectCount = 0) {
|
|
196
|
+
if (redirectCount > 5) {
|
|
197
|
+
if (!completed) {
|
|
198
|
+
completed = true;
|
|
199
|
+
clearTimeout(timer);
|
|
200
|
+
file.close();
|
|
201
|
+
try { fs.unlinkSync(destPath); } catch (e) {}
|
|
202
|
+
reject(new Error('Too many redirects'));
|
|
203
|
+
}
|
|
214
204
|
return;
|
|
215
205
|
}
|
|
216
206
|
|
|
217
|
-
const
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
if (
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
207
|
+
const request = protocol.get(requestUrl, {
|
|
208
|
+
headers: { 'User-Agent': 'sciagent-cli/1.0' },
|
|
209
|
+
timeout: 60000
|
|
210
|
+
}, (response) => {
|
|
211
|
+
// Handle redirects
|
|
212
|
+
if (response.statusCode >= 300 && response.statusCode < 400 && response.headers.location) {
|
|
213
|
+
response.resume(); // drain the response
|
|
214
|
+
let location = response.headers.location;
|
|
215
|
+
// Handle relative redirects
|
|
216
|
+
if (location.startsWith('/')) {
|
|
217
|
+
const parsed = new URL(requestUrl);
|
|
218
|
+
location = `${parsed.protocol}//${parsed.host}${location}`;
|
|
219
|
+
}
|
|
220
|
+
doRequest(location, redirectCount + 1);
|
|
221
|
+
return;
|
|
227
222
|
}
|
|
223
|
+
|
|
224
|
+
if (response.statusCode !== 200) {
|
|
225
|
+
response.resume(); // drain the response
|
|
226
|
+
if (!completed) {
|
|
227
|
+
completed = true;
|
|
228
|
+
clearTimeout(timer);
|
|
229
|
+
file.close();
|
|
230
|
+
try { fs.unlinkSync(destPath); } catch (e) {}
|
|
231
|
+
reject(new Error(`HTTP ${response.statusCode} for ${requestUrl}`));
|
|
232
|
+
}
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const totalSize = parseInt(response.headers['content-length'], 10);
|
|
237
|
+
|
|
238
|
+
response.on('data', (chunk) => {
|
|
239
|
+
downloadedSize += chunk.length;
|
|
240
|
+
if (totalSize) {
|
|
241
|
+
const percent = Math.floor((downloadedSize / totalSize) * 100);
|
|
242
|
+
const mb = (downloadedSize / (1024 * 1024)).toFixed(1);
|
|
243
|
+
const totalMb = (totalSize / (1024 * 1024)).toFixed(1);
|
|
244
|
+
process.stdout.write(`\r 下载进度: ${percent}% (${mb}/${totalMb} MB)`);
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
response.pipe(file);
|
|
249
|
+
|
|
250
|
+
file.on('finish', () => {
|
|
251
|
+
if (!completed) {
|
|
252
|
+
completed = true;
|
|
253
|
+
clearTimeout(timer);
|
|
254
|
+
file.close();
|
|
255
|
+
console.log(); // New line after progress
|
|
256
|
+
resolve();
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
file.on('error', (err) => {
|
|
261
|
+
if (!completed) {
|
|
262
|
+
completed = true;
|
|
263
|
+
clearTimeout(timer);
|
|
264
|
+
file.close();
|
|
265
|
+
try { fs.unlinkSync(destPath); } catch (e) {}
|
|
266
|
+
reject(err);
|
|
267
|
+
}
|
|
268
|
+
});
|
|
228
269
|
});
|
|
229
270
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
271
|
+
request.on('error', (err) => {
|
|
272
|
+
if (!completed) {
|
|
273
|
+
completed = true;
|
|
274
|
+
clearTimeout(timer);
|
|
275
|
+
file.close();
|
|
276
|
+
try { fs.unlinkSync(destPath); } catch (e) {}
|
|
277
|
+
reject(new Error(`Network error: ${err.message} (${(downloadedSize / (1024 * 1024)).toFixed(1)} MB downloaded)`));
|
|
278
|
+
}
|
|
238
279
|
});
|
|
239
280
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
clearTimeout(timer);
|
|
243
|
-
file.close();
|
|
244
|
-
try { fs.unlinkSync(destPath); } catch (e) {}
|
|
245
|
-
reject(err);
|
|
281
|
+
request.on('timeout', () => {
|
|
282
|
+
request.destroy();
|
|
246
283
|
});
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
request.on('error', (err) => {
|
|
250
|
-
completed = true;
|
|
251
|
-
clearTimeout(timer);
|
|
252
|
-
file.close();
|
|
253
|
-
try { fs.unlinkSync(destPath); } catch (e) {}
|
|
254
|
-
reject(err);
|
|
255
|
-
});
|
|
284
|
+
}
|
|
256
285
|
|
|
257
|
-
|
|
258
|
-
request.destroy();
|
|
259
|
-
});
|
|
286
|
+
doRequest(url);
|
|
260
287
|
});
|
|
261
288
|
}
|
|
262
289
|
|
|
@@ -519,6 +546,46 @@ async function downloadFromJiHuLab(platform, arch, version) {
|
|
|
519
546
|
fs.mkdirSync(installDir, { recursive: true });
|
|
520
547
|
const targetPath = path.join(installDir, binName);
|
|
521
548
|
|
|
549
|
+
// Windows: 优先使用 PowerShell(更可靠的大文件下载)
|
|
550
|
+
if (platform === 'win32') {
|
|
551
|
+
try {
|
|
552
|
+
const tmpScript = path.join(os.tmpdir(), 'sciagent-download.ps1');
|
|
553
|
+
const scriptContent = [
|
|
554
|
+
'$ProgressPreference = "SilentlyContinue"',
|
|
555
|
+
`$uri = "${downloadUrl}"`,
|
|
556
|
+
`$out = "${targetPath}"`,
|
|
557
|
+
'Write-Host " [JiHuLab] Downloading from JiHuLab..."',
|
|
558
|
+
'Invoke-WebRequest -Uri $uri -OutFile $out -UseBasicParsing',
|
|
559
|
+
'if (Test-Path $out) { $s = (Get-Item $out).Length; Write-Host " [JiHuLab] Downloaded: $s bytes" } else { Write-Error "File not created"; exit 1 }'
|
|
560
|
+
].join('\r\n');
|
|
561
|
+
fs.writeFileSync(tmpScript, scriptContent, 'utf8');
|
|
562
|
+
|
|
563
|
+
try {
|
|
564
|
+
execSync(`powershell -NoProfile -ExecutionPolicy Bypass -File "${tmpScript}"`, {
|
|
565
|
+
stdio: 'inherit',
|
|
566
|
+
timeout: 600000
|
|
567
|
+
});
|
|
568
|
+
} finally {
|
|
569
|
+
try { fs.unlinkSync(tmpScript); } catch (e) {}
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
// 验证下载
|
|
573
|
+
if (fs.existsSync(targetPath)) {
|
|
574
|
+
const stats = fs.statSync(targetPath);
|
|
575
|
+
if (stats.size > 10 * 1024 * 1024) {
|
|
576
|
+
console.log(` [OK] JiHuLab download success: ${targetPath} (${(stats.size / (1024 * 1024)).toFixed(1)} MB)`);
|
|
577
|
+
fs.writeFileSync(path.join(installDir, '.version'), version);
|
|
578
|
+
return true;
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
console.log(` [WARN] PowerShell download validation failed, trying Node.js...`);
|
|
583
|
+
} catch (e) {
|
|
584
|
+
console.log(` [WARN] PowerShell download failed: ${e.message}, trying Node.js...`);
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
// 通用方式: Node.js https 下载
|
|
522
589
|
try {
|
|
523
590
|
await downloadFile(downloadUrl, targetPath, 600000); // 10 分钟超时
|
|
524
591
|
|
|
@@ -585,60 +652,9 @@ async function downloadFromServer(platform, arch, version) {
|
|
|
585
652
|
}
|
|
586
653
|
}
|
|
587
654
|
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
// 1.0.40/1.0.38/1.0.36 包含完整的二进制文件
|
|
592
|
-
const FALLBACK_VERSIONS = [CURRENT_VERSION, '1.0.63', '1.0.61', '1.0.48', '1.0.46', '1.0.40', '1.0.38', '1.0.36'];
|
|
593
|
-
|
|
594
|
-
let npmCmd = 'npm';
|
|
595
|
-
const isGlobal = process.env.npm_config_global === 'true' ||
|
|
596
|
-
process.env.npm_lifecycle_event === 'postinstall';
|
|
597
|
-
|
|
598
|
-
for (const version of FALLBACK_VERSIONS) {
|
|
599
|
-
const packageName = `@sciagent/cli-${platform}-${arch}@${version}`;
|
|
600
|
-
console.log(`\n Installing platform binary: ${packageName}`);
|
|
601
|
-
console.log(' This may take a moment...\n');
|
|
602
|
-
|
|
603
|
-
try {
|
|
604
|
-
let installArgs = ['install', '-g', packageName];
|
|
605
|
-
|
|
606
|
-
if (!isGlobal) {
|
|
607
|
-
installArgs = ['install', packageName];
|
|
608
|
-
}
|
|
609
|
-
|
|
610
|
-
execSync(`${npmCmd} ${installArgs.join(' ')}`, {
|
|
611
|
-
stdio: 'inherit',
|
|
612
|
-
timeout: 300000
|
|
613
|
-
});
|
|
614
|
-
|
|
615
|
-
// 关键修复:npm install 成功不等于二进制文件存在
|
|
616
|
-
// 空壳包(423 bytes)也会返回成功,但没有实际二进制
|
|
617
|
-
const binName = platform === 'win32' ? 'sciagent.exe' : 'sciagent';
|
|
618
|
-
try {
|
|
619
|
-
const resolvedPath = require.resolve(`@sciagent/cli-${platform}-${arch}/bin/${binName}`);
|
|
620
|
-
if (fs.existsSync(resolvedPath)) {
|
|
621
|
-
const stats = fs.statSync(resolvedPath);
|
|
622
|
-
// 二进制文件应该至少 10MB
|
|
623
|
-
if (stats.size > 10 * 1024 * 1024) {
|
|
624
|
-
console.log(` ✅ Verified binary: ${resolvedPath} (${(stats.size / (1024 * 1024)).toFixed(1)} MB)`);
|
|
625
|
-
return true;
|
|
626
|
-
} else {
|
|
627
|
-
console.log(` ⚠️ Binary too small (${stats.size} bytes), likely a stub package`);
|
|
628
|
-
}
|
|
629
|
-
}
|
|
630
|
-
} catch (e) {
|
|
631
|
-
// require.resolve 失败说明 bin 目录不存在
|
|
632
|
-
}
|
|
633
|
-
console.log(` ⚠️ ${packageName} installed but has no binary, trying next version...`);
|
|
634
|
-
} catch (e) {
|
|
635
|
-
console.log(` ⚠️ ${packageName} not available, trying next version...`);
|
|
636
|
-
}
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
console.error(`\n ❌ Failed to install platform binary for ${platform}-${arch}`);
|
|
640
|
-
return false;
|
|
641
|
-
}
|
|
655
|
+
// installBinaryPackage 已移除
|
|
656
|
+
// 原因:npm optionalDependencies 缓存旧包导致版本错乱
|
|
657
|
+
// 所有二进制统一从极狐GitLab下载
|
|
642
658
|
|
|
643
659
|
async function main() {
|
|
644
660
|
console.log('[postinstall] Starting postinstall script...');
|
|
@@ -697,22 +713,16 @@ async function main() {
|
|
|
697
713
|
const serverSuccess = await downloadFromServer(platform, arch, CURRENT_VERSION);
|
|
698
714
|
|
|
699
715
|
if (!serverSuccess) {
|
|
700
|
-
|
|
701
|
-
console.
|
|
702
|
-
console.
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
console.error('');
|
|
711
|
-
console.error(' Please run this command manually:');
|
|
712
|
-
console.error(` npm install -g ${packageName}@${CURRENT_VERSION}`);
|
|
713
|
-
console.error('');
|
|
714
|
-
process.exit(1);
|
|
715
|
-
}
|
|
716
|
+
console.error('');
|
|
717
|
+
console.error('╔══════════════════════════════════════════════════════════╗');
|
|
718
|
+
console.error('║ Manual Installation Required ║');
|
|
719
|
+
console.error('╚══════════════════════════════════════════════════════════╝');
|
|
720
|
+
console.error('');
|
|
721
|
+
console.error(' All download sources failed. Please try again later or:');
|
|
722
|
+
console.error(` 1. Check your network connection`);
|
|
723
|
+
console.error(` 2. Visit: https://jihulab.com/13996615495-group/research-agent/-/packages`);
|
|
724
|
+
console.error('');
|
|
725
|
+
process.exit(1);
|
|
716
726
|
}
|
|
717
727
|
}
|
|
718
728
|
|