@sciagent/cli 1.1.49 → 1.1.50
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 +131 -16
- package/package.json +1 -1
- package/scripts/postinstall.js +19 -3
package/bin/sciagent.js
CHANGED
|
@@ -25,7 +25,7 @@ const https = require('https');
|
|
|
25
25
|
const http = require('http');
|
|
26
26
|
|
|
27
27
|
// 当前版本号 - 与 postinstall.js 和 package.json 保持同步
|
|
28
|
-
const CURRENT_VERSION = '1.1.
|
|
28
|
+
const CURRENT_VERSION = '1.1.50';
|
|
29
29
|
|
|
30
30
|
// Releases 服务器下载配置
|
|
31
31
|
const RELEASE_SERVER_URL = process.env.RELEASE_SERVER_URL || 'https://sciagent.tech';
|
|
@@ -396,19 +396,23 @@ function getBinaryPath() {
|
|
|
396
396
|
checkAutoUpdate(platform, arch);
|
|
397
397
|
return binPath;
|
|
398
398
|
} else if (cmp < 0) {
|
|
399
|
-
// 版本过低 →
|
|
399
|
+
// 版本过低 → 同步下载新版本并替换,然后再启动
|
|
400
400
|
console.log(`[INFO] SciAgent version outdated: v${installedVersion} (${(stats.size / (1024 * 1024)).toFixed(1)} MB) → v${CURRENT_VERSION}`);
|
|
401
401
|
console.log(`[INFO] Downloading new version from server...`);
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
402
|
+
const downloaded = downloadBinary(platform, arch, CURRENT_VERSION);
|
|
403
|
+
if (downloaded && fs.existsSync(downloaded)) {
|
|
404
|
+
console.log(`[INFO] ✅ Updated to v${CURRENT_VERSION}. Starting...`);
|
|
405
|
+
checkAutoUpdate(platform, arch);
|
|
406
|
+
return downloaded;
|
|
407
|
+
}
|
|
408
|
+
// 下载失败,尝试临时目录下载
|
|
409
|
+
const tempDownloaded = downloadBinaryToTemp(platform, arch, CURRENT_VERSION);
|
|
410
|
+
if (tempDownloaded) {
|
|
411
|
+
console.log(`[INFO] ✅ New version downloaded to temp. Will apply on next restart.`);
|
|
412
|
+
console.log(`[INFO] ⚠️ Continuing with current version v${installedVersion} this time.`);
|
|
413
|
+
} else {
|
|
414
|
+
console.log(`[INFO] ⚠️ Download failed. Continuing with current version v${installedVersion}.`);
|
|
409
415
|
}
|
|
410
|
-
// 下载失败,继续使用当前版本
|
|
411
|
-
console.log(`[INFO] ⚠️ Download failed. Continuing with current version.`);
|
|
412
416
|
return binPath;
|
|
413
417
|
} else {
|
|
414
418
|
// 版本更高 → 允许运行(用户可能手动安装了新版)
|
|
@@ -417,11 +421,21 @@ function getBinaryPath() {
|
|
|
417
421
|
return binPath;
|
|
418
422
|
}
|
|
419
423
|
} else {
|
|
420
|
-
// 没有.version文件 →
|
|
424
|
+
// 没有.version文件 → 版本未知,同步下载正确版本
|
|
421
425
|
console.log(`[INFO] SciAgent binary found but version unknown, downloading v${CURRENT_VERSION}...`);
|
|
422
|
-
const downloaded =
|
|
423
|
-
if (downloaded) {
|
|
424
|
-
console.log(`[INFO] ✅
|
|
426
|
+
const downloaded = downloadBinary(platform, arch, CURRENT_VERSION);
|
|
427
|
+
if (downloaded && fs.existsSync(downloaded)) {
|
|
428
|
+
console.log(`[INFO] ✅ Installed v${CURRENT_VERSION}. Starting...`);
|
|
429
|
+
checkAutoUpdate(platform, arch);
|
|
430
|
+
return downloaded;
|
|
431
|
+
}
|
|
432
|
+
// 下载失败,尝试临时目录
|
|
433
|
+
const tempDownloaded = downloadBinaryToTemp(platform, arch, CURRENT_VERSION);
|
|
434
|
+
if (tempDownloaded) {
|
|
435
|
+
console.log(`[INFO] ✅ New version downloaded to temp. Will apply on next restart.`);
|
|
436
|
+
console.log(`[INFO] ⚠️ Continuing with unknown version this time.`);
|
|
437
|
+
} else {
|
|
438
|
+
console.log(`[INFO] ⚠️ Download failed. Continuing with unknown version.`);
|
|
425
439
|
}
|
|
426
440
|
return binPath;
|
|
427
441
|
}
|
|
@@ -538,7 +552,8 @@ function downloadBinaryToTemp(platform, arch, version) {
|
|
|
538
552
|
}
|
|
539
553
|
|
|
540
554
|
/**
|
|
541
|
-
* 从 Release Server
|
|
555
|
+
* 从 Release Server 下载二进制文件(直接到目标路径,用于首次安装或版本更新)
|
|
556
|
+
* 如果目标文件已存在,先下载到临时目录再替换
|
|
542
557
|
*/
|
|
543
558
|
function downloadBinary(platform, arch, version) {
|
|
544
559
|
const binName = platform === 'win32' ? 'sciagent.exe' : 'sciagent';
|
|
@@ -552,7 +567,107 @@ function downloadBinary(platform, arch, version) {
|
|
|
552
567
|
const installDir = getInstallDir(platform);
|
|
553
568
|
fs.mkdirSync(installDir, { recursive: true });
|
|
554
569
|
const targetPath = path.join(installDir, binName);
|
|
570
|
+
const targetExists = fs.existsSync(targetPath);
|
|
571
|
+
|
|
572
|
+
// 如果目标文件已存在,先下载到临时目录再替换
|
|
573
|
+
if (targetExists) {
|
|
574
|
+
const tempDir = path.join(os.tmpdir(), 'sciagent-update');
|
|
575
|
+
fs.mkdirSync(tempDir, { recursive: true });
|
|
576
|
+
const tempPath = path.join(tempDir, binName);
|
|
577
|
+
// 清理旧的临时文件
|
|
578
|
+
try { if (fs.existsSync(tempPath)) fs.unlinkSync(tempPath); } catch (e) {}
|
|
579
|
+
|
|
580
|
+
console.log(` Downloading ${filename} v${version} to temp...`);
|
|
581
|
+
|
|
582
|
+
try {
|
|
583
|
+
if (platform === 'win32') {
|
|
584
|
+
const tmpScript = path.join(os.tmpdir(), 'sciagent-download.ps1');
|
|
585
|
+
const scriptContent = [
|
|
586
|
+
'$ProgressPreference = "SilentlyContinue"',
|
|
587
|
+
`$uri = "${downloadUrl}"`,
|
|
588
|
+
`$out = "${tempPath}"`,
|
|
589
|
+
'Write-Host " Downloading from server..."',
|
|
590
|
+
'Invoke-WebRequest -Uri $uri -OutFile $out -UseBasicParsing',
|
|
591
|
+
'if (Test-Path $out) { $s = (Get-Item $out).Length; Write-Host " Downloaded: $s bytes" } else { Write-Error "File not created"; exit 1 }'
|
|
592
|
+
].join('\r\n');
|
|
593
|
+
fs.writeFileSync(tmpScript, scriptContent, 'utf8');
|
|
594
|
+
|
|
595
|
+
try {
|
|
596
|
+
execSync(`powershell -NoProfile -ExecutionPolicy Bypass -File "${tmpScript}"`, {
|
|
597
|
+
stdio: 'inherit',
|
|
598
|
+
timeout: 600000
|
|
599
|
+
});
|
|
600
|
+
} finally {
|
|
601
|
+
try { fs.unlinkSync(tmpScript); } catch (e) {}
|
|
602
|
+
}
|
|
603
|
+
} else {
|
|
604
|
+
execSync(`curl -fsSL -o '${tempPath}' '${downloadUrl}'`, {
|
|
605
|
+
stdio: 'pipe',
|
|
606
|
+
timeout: 600000
|
|
607
|
+
});
|
|
608
|
+
fs.chmodSync(tempPath, 0o755);
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
// 验证临时文件
|
|
612
|
+
if (fs.existsSync(tempPath)) {
|
|
613
|
+
const tempStats = fs.statSync(tempPath);
|
|
614
|
+
if (tempStats.size > 10 * 1024 * 1024) {
|
|
615
|
+
console.log(` ✅ Downloaded: ${(tempStats.size / (1024 * 1024)).toFixed(1)} MB`);
|
|
616
|
+
|
|
617
|
+
// 尝试替换目标文件
|
|
618
|
+
try {
|
|
619
|
+
if (platform === 'win32') {
|
|
620
|
+
const tmpScript = path.join(os.tmpdir(), 'sciagent-replace.ps1');
|
|
621
|
+
const scriptContent = [
|
|
622
|
+
`Copy-Item -Path "${tempPath}" -Destination "${targetPath}" -Force`,
|
|
623
|
+
'if (Test-Path $out) { Write-Host "OK" } else { Write-Error "Copy failed"; exit 1 }'
|
|
624
|
+
].join('\r\n');
|
|
625
|
+
fs.writeFileSync(tmpScript, scriptContent, 'utf8');
|
|
626
|
+
try {
|
|
627
|
+
execSync(`powershell -NoProfile -ExecutionPolicy Bypass -File "${tmpScript}"`, {
|
|
628
|
+
stdio: 'pipe', timeout: 30000
|
|
629
|
+
});
|
|
630
|
+
} finally {
|
|
631
|
+
try { fs.unlinkSync(tmpScript); } catch (e) {}
|
|
632
|
+
}
|
|
633
|
+
} else {
|
|
634
|
+
fs.copyFileSync(tempPath, targetPath);
|
|
635
|
+
fs.chmodSync(targetPath, 0o755);
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
// 验证替换成功
|
|
639
|
+
if (fs.existsSync(targetPath)) {
|
|
640
|
+
const targetStats = fs.statSync(targetPath);
|
|
641
|
+
if (targetStats.size > 10 * 1024 * 1024) {
|
|
642
|
+
fs.writeFileSync(path.join(installDir, '.version'), version);
|
|
643
|
+
try { fs.unlinkSync(tempPath); } catch (e) {}
|
|
644
|
+
return targetPath;
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
} catch (replaceErr) {
|
|
648
|
+
// 替换失败(可能被锁定),写入 pending update
|
|
649
|
+
console.log(` ⚠️ Cannot replace running binary. Writing pending update...`);
|
|
650
|
+
const pendingData = {
|
|
651
|
+
version: version,
|
|
652
|
+
tempPath: tempPath,
|
|
653
|
+
timestamp: new Date().toISOString(),
|
|
654
|
+
platform: process.platform
|
|
655
|
+
};
|
|
656
|
+
fs.writeFileSync(path.join(installDir, '.pending-update'), JSON.stringify(pendingData, null, 2), 'utf8');
|
|
657
|
+
console.log(` 📋 Update will be applied on next restart.`);
|
|
658
|
+
return null;
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
} catch (e) {
|
|
663
|
+
console.error(` ❌ Download failed: ${e.message}`);
|
|
664
|
+
try { if (fs.existsSync(tempPath)) fs.unlinkSync(tempPath); } catch (e2) {}
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
return null;
|
|
668
|
+
}
|
|
555
669
|
|
|
670
|
+
// 目标文件不存在(首次安装),直接下载到目标路径
|
|
556
671
|
console.log(` Downloading ${filename} v${version}...`);
|
|
557
672
|
console.log(` Target: ${targetPath}`);
|
|
558
673
|
|
package/package.json
CHANGED
package/scripts/postinstall.js
CHANGED
|
@@ -27,7 +27,7 @@ const ARCH_MAP = {
|
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
// 当前版本号 - 每次发布时同步更新
|
|
30
|
-
const CURRENT_VERSION = '1.1.
|
|
30
|
+
const CURRENT_VERSION = '1.1.50';
|
|
31
31
|
|
|
32
32
|
// GitHub Releases 回退版本列表(当当前版本的 release 不存在时尝试)
|
|
33
33
|
const GITHUB_FALLBACK_VERSIONS = ['1.1.3', '1.0.50', '1.0.48', '1.0.46', '1.0.40', '1.0.38', '1.0.36'];
|
|
@@ -110,13 +110,21 @@ function checkBinaryInstalled(platform, arch) {
|
|
|
110
110
|
} else {
|
|
111
111
|
console.log(` ℹ️ 已安装版本 ${installedVersion} != 目标版本 ${CURRENT_VERSION},需要更新`);
|
|
112
112
|
// 版本不匹配,删除旧文件强制重新下载
|
|
113
|
-
_removeBinaryFiles(homeBinDir, homeBinPath);
|
|
113
|
+
const allRemoved = _removeBinaryFiles(homeBinDir, homeBinPath);
|
|
114
|
+
if (!allRemoved) {
|
|
115
|
+
// 删除失败(可能被锁定),标记需要更新但不阻塞
|
|
116
|
+
// downloadFromServer 会下载到临时目录并处理锁定情况
|
|
117
|
+
console.log(` ℹ️ 旧文件删除失败(可能被占用),将下载新版本到临时目录`);
|
|
118
|
+
}
|
|
114
119
|
return { installed: false };
|
|
115
120
|
}
|
|
116
121
|
} else {
|
|
117
122
|
console.log(` ℹ️ 二进制版本未知(无.version文件),需要重新下载`);
|
|
118
123
|
// 版本未知,删除文件强制重新下载
|
|
119
|
-
_removeBinaryFiles(homeBinDir, homeBinPath);
|
|
124
|
+
const allRemoved = _removeBinaryFiles(homeBinDir, homeBinPath);
|
|
125
|
+
if (!allRemoved) {
|
|
126
|
+
console.log(` ℹ️ 旧文件删除失败(可能被占用),将下载新版本到临时目录`);
|
|
127
|
+
}
|
|
120
128
|
return { installed: false };
|
|
121
129
|
}
|
|
122
130
|
} else {
|
|
@@ -144,14 +152,22 @@ function _removeBinaryFiles(binDir, binPath) {
|
|
|
144
152
|
if (fs.existsSync(versionFile)) {
|
|
145
153
|
filesToRemove.push(versionFile);
|
|
146
154
|
}
|
|
155
|
+
// 也删除 .pending-update 文件
|
|
156
|
+
const pendingFile = path.join(binDir, '.pending-update');
|
|
157
|
+
if (fs.existsSync(pendingFile)) {
|
|
158
|
+
filesToRemove.push(pendingFile);
|
|
159
|
+
}
|
|
160
|
+
let allRemoved = true;
|
|
147
161
|
for (const f of filesToRemove) {
|
|
148
162
|
try {
|
|
149
163
|
fs.unlinkSync(f);
|
|
150
164
|
console.log(` ℹ️ 已删除: ${f}`);
|
|
151
165
|
} catch (e) {
|
|
152
166
|
console.log(` ⚠️ 无法删除 ${f}: ${e.message}`);
|
|
167
|
+
allRemoved = false;
|
|
153
168
|
}
|
|
154
169
|
}
|
|
170
|
+
return allRemoved;
|
|
155
171
|
}
|
|
156
172
|
|
|
157
173
|
function checkCodebuddyBinaryInstalled() {
|