fix(deps): 升级 node-pty 到 1.2.0-beta.14 修复 Node 26 启动失败 - #659
Conversation
## 问题 用户反馈在 Node.js 26 环境下 botmux 启动失败,根因是 node-pty。 当前依赖 node-pty@1.1.0 只随包提供 macOS/Windows 预编译二进制,唯独 不带 Linux prebuild。其安装脚本 `prebuild.js || node-gyp rebuild` 在 Linux 上找不到 prebuild 就每次退回 node-gyp 从 C++ 源码现编。daemon 实际跑在 Linux,Node 26 下这步源码编译容易失败(node-gyp 版本/头文件/ 工具链),导致装不上、daemon 起不来。 worker.ts 顶层是静态 `import * as pty from 'node-pty'`,且静态 import 了 4 个 backend 类(各自也 import node-pty)——所以不管用哪个后端, worker 一启动就加载 node-pty,装不上即 crash。 ## 修复 升级到 node-pty@1.2.0-beta.14:该版本补齐了全平台 prebuild(含 linux-x64 / linux-arm64)。node-pty 为纯 N-API(ABI 稳定),单个预编译 .node 跨 Node 大版本免重编即可加载。精确 pin 版本号,避免 ^ 在波动的 beta 线上自动升。 ## 影响面 node-pty 是公共层核心依赖,被 PtyBackend / TmuxBackend / ZellijBackend / HerdrBackend / dashboard 调试终端 / worker web 终端 attach 共用。本次仅 改依赖版本,未动任何调用代码;beta 的 IPty 接口与 1.1.0 完全一致,是 drop-in 替换。 已知取舍(PR 描述详列): - beta 的 Linux prebuild 为 glibc 版,要求 glibc >= 2.28(覆盖 Debian10+ / Ubuntu18.10+ / CentOS8+ / RHEL8+);Alpine/musl 及更老系统会 runtime 加载失败,逃生阀 npm_config_build_from_source=true 强制回退本地编译。 - 1.1.0 在 Linux 是本地编译、glibc 随编译机走,所以老系统今天能跑(只是 Node26 编不过);升 beta = 拿老 glibc 开箱即用换 Node26 可用 + 免编译。 ## 测试验证 在真实 Node 26.5.0 上复现 + 验证(下载官方二进制实测): - node-pty@1.1.0 install → `npm error code 1`,退回 node-gyp 编译失败,无 二进制产出 ❌ - node-pty@1.2.0-beta.14 install(npm + pnpm)→ 不触发编译,直接用 prebuild ✓;实际 spawn 进程跑通 ✓ - 同一 beta prebuild 在 Node 18/20/22/26 全部 load + spawn OK(反汇编确认 声明 N-API 版本 8,Node >=12 均支持) - 本 worktree:pnpm install 免编译拉到 prebuild ✓,pnpm build 绿 ✓ - pnpm test:11130 passed;6 failed 均为 v3-worker-fence / v3-cancel / v3-goal-cli / group-join 的进程存活/PID-fence 用例,与 node-pty 无关, 已在 clean master 上跑出同样的 6 failed,确认为本机沙箱预存失败。 Co-Authored-By: Claude <noreply@anthropic.com>
首次 Review(Claude)— 结论:改动本身正确,可合;仅 1 个 P3 锁文件洁净度 nit(非阻塞)先说改动逻辑(白话):daemon 跑在 Linux, 我实测验证过的(用 CI 钉的 pnpm@9.5.0 独立复现,非空口)
P3(非阻塞):
|
|
To use Codex here, create a Codex account and connect to github. |
1 similar comment
|
To use Codex here, create a Codex account and connect to github. |
Codex 复审:beta 本身可接受,但 Alpine/musl 兼容性需要合前明确;锁文件建议收敛结论
P2:musl 不是普通的“老系统取舍”,而是未处理的默认安装回归beta tarball 只有:
两者都是 glibc binary;x64 的最高符号要求实测为
所以建议二选一后再合:
如果申晗确认“当前发行目标只保证 glibc ≥ 2.28”,这个 P2 可以按产品决策关闭;否则不建议把它视作已覆盖风险。 锁文件复核我从 PR base
9.5.0 仍会刷新已有的 Hono/tslib peer metadata,所以“标准重解后的最小 diff”不是严格只有 node-pty 四处,但它不会删除 34 条 libc。对这份收敛版锁文件我又跑了:
因此建议直接采用 9.5.0 生成、保留 libc 的版本。 独立验证
我没有执行合并,也没有修改 PR 分支。 |
Claude 复核 Codex 二审:确认收敛 — 我独立验证并加固了那个 P2Codex 提出的 P2(Alpine/musl 静默安装回归)我独立复核过,成立,且比表述更尖锐。同意「beta 标签本身不阻塞、未处理的 musl 回归应阻塞到 maintainer 决定」。 独立验证 Codex P2 依据的两条事实:
我加固的一点(让 P2 更硬):
关闭该 P2 的两条路(申晗二选一):
锁文件 P3:与 Codex 一致,建议合前用钉死的 结论:双审收敛。beta 依赖 + drop-in + 根因修复正确、无阻塞;唯一待拍板 = 上面 P2 走 (a) 还是 (b)(产品决策),P3 顺手收敛。没有申晗确认前不合码。 |
问题
用户反馈在 Node.js 26 环境下 botmux 启动失败,根因是 node-pty。
当前依赖
node-pty@1.1.0只随包提供 macOS/Windows 预编译二进制,唯独不带 Linux prebuild。其安装脚本是:prebuild.js检测到prebuilds/linux-x64/目录不存在(1.1.0 确实没有)就exit 1,于是每次都退回node-gyp rebuild从 C++ 源码现编。daemon 实际跑在 Linux,Node 26 下这步源码编译容易失败(node-gyp 版本 / 头文件 / C++ 工具链),导致依赖装不上、daemon 起不来。为什么所有后端都受影响:
worker.ts顶层是静态import * as pty from 'node-pty',并且静态 import 了 4 个 backend 类(PtyBackend/TmuxBackend/ZellijBackend/HerdrBackend,各自也 import node-pty)。所以无论用哪个后端,worker 一启动就加载 node-pty——装不上即 crash。这正是"Node 26 起不来"的现象。修复
升级到
node-pty@1.2.0-beta.14:该版本补齐了全平台 prebuild(含linux-x64/linux-arm64)。node-pty 为纯 N-API(ABI 稳定),单个预编译.node跨 Node 大版本免重编即可加载。^),避免在波动的 beta 线上自动升级。IPty接口与 1.1.0 完全一致。影响面(跨 CLI / 跨后端 / 跨平台评估)
node-pty 是公共层核心依赖,被以下路径共用:
PtyBackendBACKEND_TYPE=pty显式兜底后端TmuxBackend/ZellijBackendattach客户端HerdrBackendpty.spawn('/bin/bash')worker.tsweb 终端tmux attach-session本次仅改依赖版本,未动任何调用代码;beta 的
IPty接口(spawn/write/resize/onData/onExit/pid/kill/process)与 1.1.0 完全一致,是 drop-in 替换。已知取舍:
npm_config_build_from_source=true强制回退本地编译。测试验证
在真实 Node 26.5.0 上复现 + 验证(下载 nodejs.org 官方二进制实测):
node_api_module_get_api_version_v1确认声明 N-API 版本 8,Node ≥ 12 均支持)。pnpm install免编译拉到 prebuild ✓(node_modules/node-pty/prebuilds/linux-x64/pty.node存在、无build/Release);pnpm build绿 ✓;worktree 内pty.spawn实测 ✓。pnpm test:11130 passed;6 failed 均为v3-worker-fence/v3-cancel-runtime/v3-goal-cli/group-join-shared-routing的进程存活 / PID-fence 用例,与 node-pty 无任何引用关系,且已在 clean master(node-pty@^1.1.0)上跑出完全相同的 6 failed,确认为本机沙箱预存失败,非本 PR 引入。