@sciagent/cli 1.3.15 → 1.3.17
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 +1 -1
- package/package.json +1 -1
- package/scripts/postinstall.js +79 -1
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.3.
|
|
28
|
+
const CURRENT_VERSION = '1.3.17';
|
|
29
29
|
|
|
30
30
|
// Releases 下载源配置(优先级从高到低)
|
|
31
31
|
// JihuLab 通用包仓库(国内 CDN,速度快)作为主源
|
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.3.
|
|
30
|
+
const CURRENT_VERSION = '1.3.17';
|
|
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'];
|
|
@@ -185,6 +185,57 @@ function _removeBinaryFiles(binDir, binPath) {
|
|
|
185
185
|
return allRemoved;
|
|
186
186
|
}
|
|
187
187
|
|
|
188
|
+
/**
|
|
189
|
+
* 校验 Windows PE 可执行文件架构(AMD64 = 0x8664)
|
|
190
|
+
* 解析 MZ 头 → 0x3C 处 PE 偏移 → "PE\0\0" 签名 → Machine 字段。
|
|
191
|
+
* 非 Windows 或非 .exe 返回 true(跳过校验)。
|
|
192
|
+
* 返回 { ok: boolean, desc: string }。校验失败时会给出可操作提示。
|
|
193
|
+
*/
|
|
194
|
+
function checkPeArchitecture(binaryPath) {
|
|
195
|
+
if (process.platform !== 'win32') return { ok: true, desc: 'non-win32 skip' };
|
|
196
|
+
let fd = null;
|
|
197
|
+
try {
|
|
198
|
+
fd = fs.openSync(binaryPath, 'r');
|
|
199
|
+
const mz = Buffer.alloc(2);
|
|
200
|
+
fs.readSync(fd, mz, 0, 2, 0);
|
|
201
|
+
if (mz.toString('latin1') !== 'MZ') {
|
|
202
|
+
return { ok: false, desc: '文件损坏:缺少 MZ 头(不是有效的 EXE,可能下载/解压不完整)' };
|
|
203
|
+
}
|
|
204
|
+
const peOffBuf = Buffer.alloc(4);
|
|
205
|
+
fs.readSync(fd, peOffBuf, 0, 4, 0x3C);
|
|
206
|
+
const peOffset = peOffBuf.readUInt32LE(0);
|
|
207
|
+
const peSig = Buffer.alloc(4);
|
|
208
|
+
fs.readSync(fd, peSig, 0, 4, peOffset);
|
|
209
|
+
if (peSig.toString('latin1') !== 'PE\u0000\u0000') {
|
|
210
|
+
return { ok: false, desc: '文件损坏:缺少 PE 签名(可能下载/解压不完整)' };
|
|
211
|
+
}
|
|
212
|
+
const machineBuf = Buffer.alloc(2);
|
|
213
|
+
fs.readSync(fd, machineBuf, 0, 2, peOffset + 4);
|
|
214
|
+
const machine = machineBuf.readUInt16LE(0);
|
|
215
|
+
if (machine === 0x8664) return { ok: true, desc: 'AMD64 (x64)' };
|
|
216
|
+
if (machine === 0x14C) return { ok: false, desc: '架构不匹配:EXE 是 32 位 (i386),当前系统是 64 位(WinError 216)' };
|
|
217
|
+
if (machine === 0xAA64) return { ok: false, desc: `架构不匹配:EXE 是 ARM64,当前系统是 AMD64(WinError 216)` };
|
|
218
|
+
return { ok: false, desc: `架构不匹配:未知 Machine=0x${machine.toString(16).toUpperCase().padStart(4, '0')}(WinError 216)` };
|
|
219
|
+
} catch (e) {
|
|
220
|
+
return { ok: false, desc: `无法读取 EXE 头: ${e.message}` };
|
|
221
|
+
} finally {
|
|
222
|
+
if (fd !== null) { try { fs.closeSync(fd); } catch (e) {} }
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* 校验 SDK 二进制文件是否有效(大小 + PE 架构 + 完整性)
|
|
228
|
+
* 校验失败时返回 false(调用方应删除重下)
|
|
229
|
+
*/
|
|
230
|
+
function validateCodebuddyBinary(binaryPath) {
|
|
231
|
+
if (!fs.existsSync(binaryPath)) return { ok: false, desc: '文件不存在' };
|
|
232
|
+
const stats = fs.statSync(binaryPath);
|
|
233
|
+
if (stats.size <= 10 * 1024 * 1024) {
|
|
234
|
+
return { ok: false, desc: `文件太小 (${(stats.size / 1024).toFixed(0)} KB < 10 MB),可能是损坏文件` };
|
|
235
|
+
}
|
|
236
|
+
return checkPeArchitecture(binaryPath);
|
|
237
|
+
}
|
|
238
|
+
|
|
188
239
|
function checkCodebuddyBinaryInstalled() {
|
|
189
240
|
const binDir = getCodebuddyBinDir();
|
|
190
241
|
const binaryName = BINARY_NAMES[process.platform] || 'codebuddy-headless';
|
|
@@ -194,6 +245,16 @@ function checkCodebuddyBinaryInstalled() {
|
|
|
194
245
|
const stats = fs.statSync(binaryPath);
|
|
195
246
|
// 检查文件大小是否合理(至少10MB,防止损坏的文件)
|
|
196
247
|
if (stats.size > 10 * 1024 * 1024) {
|
|
248
|
+
// 额外校验 PE 架构与完整性(防 WinError 216/1392)
|
|
249
|
+
const check = checkPeArchitecture(binaryPath);
|
|
250
|
+
if (!check.ok) {
|
|
251
|
+
console.log(` ⚠️ 已存在的 SDK 校验失败: ${check.desc}`);
|
|
252
|
+
console.log(` 删除 ${binaryPath} 并重新下载...`);
|
|
253
|
+
try { fs.unlinkSync(binaryPath); } catch (e) {
|
|
254
|
+
console.log(` 删除失败: ${e.message}`);
|
|
255
|
+
}
|
|
256
|
+
return { installed: false };
|
|
257
|
+
}
|
|
197
258
|
return { installed: true, path: binaryPath, size: stats.size };
|
|
198
259
|
}
|
|
199
260
|
}
|
|
@@ -468,9 +529,18 @@ sys.exit(1)
|
|
|
468
529
|
|
|
469
530
|
if (fs.existsSync(targetPath)) {
|
|
470
531
|
const stats = fs.statSync(targetPath);
|
|
532
|
+
// 提取后立即校验 PE 架构与完整性(防 WinError 216/1392)
|
|
533
|
+
const check = validateCodebuddyBinary(targetPath);
|
|
534
|
+
if (!check.ok) {
|
|
535
|
+
console.log(` ⚠️ 提取的 SDK 二进制校验失败: ${check.desc}`);
|
|
536
|
+
try { fs.unlinkSync(targetPath); } catch (e) {}
|
|
537
|
+
try { fs.unlinkSync(wheelPath); fs.unlinkSync(scriptPath); fs.rmdirSync(tmpDir); } catch (e) {}
|
|
538
|
+
throw new Error(`SDK 二进制校验失败: ${check.desc}`);
|
|
539
|
+
}
|
|
471
540
|
console.log(`✅ CodeBuddy SDK 安装成功!(PyPI wheel)`);
|
|
472
541
|
console.log(` 路径: ${targetPath}`);
|
|
473
542
|
console.log(` 大小: ${(stats.size / (1024 * 1024)).toFixed(1)} MB`);
|
|
543
|
+
console.log(` 架构: ${check.desc}`);
|
|
474
544
|
|
|
475
545
|
try { fs.unlinkSync(wheelPath); fs.unlinkSync(scriptPath); fs.rmdirSync(tmpDir); } catch (e) {}
|
|
476
546
|
return true;
|
|
@@ -538,8 +608,16 @@ sys.exit(1)
|
|
|
538
608
|
if (platform !== 'win32') {
|
|
539
609
|
fs.chmodSync(targetPath, 0o755);
|
|
540
610
|
}
|
|
611
|
+
// 校验 PE 架构与完整性(防 WinError 216/1392)
|
|
612
|
+
const check = checkPeArchitecture(targetPath);
|
|
613
|
+
if (!check.ok) {
|
|
614
|
+
console.log(` ⚠️ 下载的 SDK 二进制校验失败: ${check.desc}`);
|
|
615
|
+
try { fs.unlinkSync(targetPath); } catch (e) {}
|
|
616
|
+
throw new Error(`SDK 二进制校验失败: ${check.desc}`);
|
|
617
|
+
}
|
|
541
618
|
console.log(`✅ CodeBuddy SDK 安装成功!(Releases 服务器)`);
|
|
542
619
|
console.log(` 路径: ${targetPath}`);
|
|
620
|
+
console.log(` 架构: ${check.desc}`);
|
|
543
621
|
return true;
|
|
544
622
|
}
|
|
545
623
|
}
|