chore(release): release.mjs 支持双架构(同时出 x64 + arm64 包)+ CHANGELOG v2.0.1

## release.mjs
- 打包阶段改为循环 `pack.mjs --arch x64|arm64`(原先只出 x64)
- 资产新增 `nodeagent-win-arm64.zip`;`latest.json` 新增 `zip_arm64` 字段
  (**只增不减**,符合 VERSIONING 的兼容铁律;旧控制端忽略即可)
- RELEASE_NOTES 提示按架构选包(x64 包在 ARM Windows 上 TLS 握手不通)
- 顺手修一处改名遗漏:`zipPath` → `zipX64` 后,产物存在性检查仍在用旧名(会 ReferenceError)

## CHANGELOG
补 v2.0.1 段:3 个修复(control.ps1 解析期错误 / 连接保活缺 pong / v26 清理阈值过粗)
+ 2 项新增(`pack --arch`、`verify-b2.mjs`)+ 新增文档 `VM-VERIFICATION.md` + 真机验证状态表
This commit is contained in:
jkooe committed 2026-10-11 08:00:52 +08:00
1 parent 7d13a48caa
commit f4ae20969a
2 files changed
+55 -4

No files matched your search

+38
View File
@@ -5,6 +5,44 @@
---
## [v2.0.1] —— 2026-10-11
> 一轮**真机验证**(Parallels 27 + Win11 ARM)带来的修复批次:在补齐 6 项待验证项的过程中,
> **抓到并修掉 5 个真问题** —— 全部只有真机能发现(macOS 上 100% 测不出)。
### 修复
- **`control.ps1` 的 `$scheme:` 被当 drive 引用** —— PowerShell **解析期错误 → 整个脚本不可用**
(stop / start / status 全废,且只报一行语法错、极易误判为别的问题)。改用 `${scheme}`;
并新增守卫扫全仓 `.ps1` 的 `$ident:` 形式(含注入故障验证)。
- **连接保活缺 pong 检测** —— 心跳只 `ping()` 而不检查 pong,且 ws 库默认不会因「ping 无 pong」断开;
客户端进程已死(TCP 未发 FIN)时,连接会**永久占用 `max_connections` 名额**,
叠加「有任务/订阅时清扫保守跳过」的策略 → **会把正常控制端挡在外面**(真机实测把自己锁住了)。
现对静默超过 `idle_timeout_ms * 2` 的连接 `terminate()`,并让 pong 也算「活跃」。
- **v26 自重启任务清理阈值过粗** —— 原用「早于 1 小时」,频繁 restart(间隔 < 1h)时旧任务照样累积;
改为「**早于本 agent 启动时刻**」——语义精确:凡在**我启动之前**运行的任务,必然不是我的宿主。
### 新增
- **`scripts/pack.mjs --arch <x64|arm64>`** —— Windows 包分架构。**x64 包在 ARM Windows 上协议层不可用**
(能启动、能 listen 8765,但 **TLS 握手不完成** —— Prism 模拟下异常,现象极具误导性);
ARM 机器须用 arm64 包。`release.mjs` 随之**同时产出两个架构**,`latest.json` 新增 `zip_arm64` 字段
(**只增不减**,旧控制端忽略即可)。
- **`scripts/verify-b2.mjs`** —— v23 连接层三防护的真机验证脚本(`idle` / `maxconn` / `ban` 三模式),
全部走真实连接而非 mock。
- **`docs/VM-VERIFICATION.md`** —— 无 Windows 真机时用 Parallels Win11 ARM 补验证的完整清单
(含实测结果、能补/不能补矩阵、8 条排查项)。
### 真机验证状态(本版实测)
| 项 | 结果 |
|---|---|
| A 组(`verify.mjs` 17 项) | 15 通过 / 0 失败 / 1 跳过 |
| v1.5 四项(字符串热键/预设别名/长按/后台投递) | 全过(`route=post` 实测命中 138 窗口) |
| v23 三防护 | 三场景全过(封禁 / 上限 / 空闲断开) |
| v26 自重启清理 | 验证并改进(阈值改为 agent 启动时刻) |
| 锚点端到端 | 全过(含云盘链外留存) |
## [v2.0.0] —— 2026-10-10
> 自 `v1.6.0` 起累计 37 个提交。**能力数 43 → 51**,单测 195 → 273,端到端 30。
+17 -4
View File
@@ -137,7 +137,11 @@ console.log(`✓ 版本号已写入 ${pkgFiles.length} 个 package.json + ${taur
console.log('=== 构建 ===');
sh('pnpm', ['-r', 'build'], { stdio: 'inherit' });
console.log('=== 打包 ===');
sh('pnpm', ['pack:win'], { stdio: 'inherit' });
// 2026-10-11:Windows 包分架构 —— x64 包在 **ARM Windows** 上协议层不可用(真机实证:
// 能启动/listen 但 TLS 握手不完成),故两个架构都产出。
for (const arch of ['x64', 'arm64']) {
sh('node', ['scripts/pack.mjs', '--arch', arch], { stdio: 'inherit' });
}
try {
sh('pnpm', ['pack:mac'], { stdio: 'inherit' });
} catch {
@@ -145,9 +149,13 @@ try {
}
const agentPath = join(root, 'release', 'nodeagent-win-x64', 'agent.mjs');
const zipPath = join(root, 'release', 'nodeagent-win-x64.zip');
// agent.mjs 与架构无关(纯 JS bundle),两包内容相同;zip 各含对应架构的 node.exe
const zipX64 = join(root, 'release', 'nodeagent-win-x64.zip');
const zipArm64 = join(root, 'release', 'nodeagent-win-arm64.zip');
if (!existsSync(agentPath)) fail(`找不到 agent 产物: ${agentPath}`);
if (!existsSync(zipPath)) fail(`找不到 zip 产物: ${zipPath}`);
for (const z of [zipX64, zipArm64]) {
if (!existsSync(z)) fail(`找不到 zip 产物: ${z}`);
}
// ---------- ④ 生成资产(校验和 + latest.json)----------
const sha256 = (p) => createHash('sha256').update(readFileSync(p)).digest('hex');
@@ -156,7 +164,8 @@ mkdirSync(distDir, { recursive: true });
const assets = [
{ name: 'agent.mjs', path: agentPath, purpose: '自更新载荷(被控端 system.agent.update 直接使用)' },
{ name: 'nodeagent-win-x64.zip', path: zipPath, purpose: '人工安装包(自包含 node.exe,免装 Node.js)' },
{ name: 'nodeagent-win-x64.zip', path: zipX64, purpose: '人工安装包 · x64 Windows(自包含 node.exe)' },
{ name: 'nodeagent-win-arm64.zip', path: zipArm64, purpose: '人工安装包 · ARM Windows(Parallels Win11 ARM 等)' },
];
for (const a of assets) {
copyFileSync(a.path, join(distDir, a.name));
@@ -188,6 +197,8 @@ const latest = {
note: '自更新用:nodeagent update --url <url> --sha256 <sha256>',
},
zip: { url: `${base}/nodeagent-win-x64.zip`, sha256: assets[1].sha256, bytes: assets[1].bytes },
// 2026-10-11 新增(只增字段,旧控制端忽略即可):ARM Windows 用包
zip_arm64: { url: `${base}/nodeagent-win-arm64.zip`, sha256: assets[2].sha256, bytes: assets[2].bytes },
};
writeFileSync(join(distDir, 'latest.json'), JSON.stringify(latest, null, 2) + '\n');
@@ -275,6 +286,7 @@ writeFileSync(
`## 人工安装(首次)`,
`\`\`\`powershell`,
`Expand-Archive nodeagent-win-x64.zip C:\\nodeagent -Force`,
`# ARM Windows(如 Parallels 的 Win11 ARM)请改用 nodeagent-win-arm64.zip —— x64 包在其上 TLS 握手不通`,
`# 先把 C:\\nodeagent 加入杀软信任区(主流杀软)`,
`powershell -ExecutionPolicy Bypass -File C:\\nodeagent\\install.ps1 -NodeId win -AllowInput`,
'```',
@@ -291,6 +303,7 @@ sh('gh', [
notes,
join(distDir, 'agent.mjs'),
join(distDir, 'nodeagent-win-x64.zip'),
join(distDir, 'nodeagent-win-arm64.zip'),
join(distDir, 'latest.json'),
join(distDir, 'SHA256SUMS'),
]);